text:
# Deep Learning¶

Martin Holub, 05/07/2018

# Landscape of AI¶

• Artificial Intelligence: The study of intelligent agents, systems that perceive their environment and take actions that maximize their chance of successfully achieving their goals

• Machine Learning: A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P if its performance at tasks in T, as measured by P, improves with experience E.

• Representation Learning (Feature Learning): Set of techniques that allows a system to automatically discover the representations needed for learning.

• Deep Learning (Hierarchical Learning): Class of machine learning algorithms that learn multiple levels of representations that correspond to different levels of abstraction; the levels form a hierarchy of concepts.

## Mo' Data, Mo' GPUs¶

It is true that some skill is required to get good performance from a deep learning algorithm. Fortunately, the amount of skill required reduces as the amount of training data increases. The learning algorithms reaching human performance on complex tasks today are nearly identical to the learning algorithms that struggled to solve toy problems in the 1980s [...] The most important new development is that today we can provide these algorithms with the resources they need to succeed.

Another key reason that neural networks are wildly successful today after enjoying comparatively little success since the 1980s is that we have the computational resources to run much larger models today.

Bigger Models More Data
• As of 2016, the rule of thumb is that supervised deep learning algorithm will generally achieve acceptable performance with around 5000 examples per category and will match or exceed human performance when trained on dataset with at leas 10 million labeled examples.

# Machine Learning¶

A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P if its performance at tasks in T, as measured by P, improves with experience E.

$T$:

• Task is how ML system should process a collection of features, i.e. example $\boldsymbol{x} \in \mathbb{R}^n$
• classification (w/ or w/o missing values), regression, transcription, translation, anomaly detection, imputation, denoising, density estimation, ...

$P$:

• usually tied to the $T$
• accuracy (classification, ...), error (regression, ...), log-likelihood (density estimation, ...)

$E$:

• dataset (w/ or w/o labels)

## Example: Linear Regression¶

$$\hat{y} = \boldsymbol{w}^T\boldsymbol{x}$$

$T$: predict $y$ from $\boldsymbol{x}$

$P$: $MSE_{test} = \frac{1}{m}\sum_i^{}(\hat{y}_i^{(test)}-y_i^{(test)})^2$

$E$: $(\boldsymbol{X}^{(train)}, \boldsymbol{y}^{(train)})$

Need: ML algorithm that improves weights $\boldsymbol{w}$ in a way that reduces $MSE_{test}$ given the training examples.

Solution: minimize $MSE_{train}$: $$\nabla_{\boldsymbol{w}} MSE_{train} = 0$$ $$...$$ $$\boldsymbol{w} = ({\boldsymbol{X}^{(train)}}^T\boldsymbol{X}^{(train)})^{-1}{\boldsymbol{X}^{(train)}}^T\boldsymbol{y}^{(train)}$$

## Capacity and Over-/Under- fitting¶

ML != Optimization ... generalization (test) error

model capacity controls whether the model is more likely to under- or over-fit

Caveat: Deep Learning models have theoretically unlimited capacity.

Occam's Razor: Among competing hypotheses that explain known observations equally well, select the "simplest" one.

## Regularization¶

Any modification to a learning algorithm that is intended to reduce generalization error but not the training error.

E.g. penalize weights with L2 norm $$J(\boldsymbol{w}) = MSE_{train} + \lambda\boldsymbol{w}^T\boldsymbol{w},$$ where $\lambda$ is a hyperparameter expressing our preference over possible model functions.

How to choose values of hyperparameters? -> train/validation split, e.g. 80/20

# Popular ML Algorithms¶

Supervised:

• Linear regression, Logistic regression, LDA, SVMs, K-Nearest neighbors, Decision trees, ...

Unsupervised:

• PCA, ICA, K-Means clustering, ...

# Deep Learning¶

Aplications in Genomics, System Biology, Biomarker discovery, ...

## Architecture:¶

#### Depth gives more powerful models¶

Apart from depth and width there are other considerations in terms of architecture:

• Connectivity of the layers, backward connections
• CNNs, RNNs
• Skip connections
• ResNets

### Example: Learning XOR¶

This is a toy example of deep feedforward network (also called MLP)

$$J(\boldsymbol{\theta}) = \frac{1}{4}\sum_{\boldsymbol{x}}^{}(f(\boldsymbol{x}) - \hat{f}(\boldsymbol{x}; \boldsymbol{\theta}))^2,\quad \hat{f}(\boldsymbol{x};\boldsymbol{\theta}) = \boldsymbol{x}^T\boldsymbol{w} + b \quad \rightarrow \quad \boldsymbol{\hat{y}} = \frac{1}{2} :($$

Takeaway: Linear model can learn non-linear function via feature transformations. Instead of engineering it, you can learn it. Usually, by specifying some broader family of functions and tuning on the data.

$$\boldsymbol{h}=g(\boldsymbol{W}^T\boldsymbol{x}+\boldsymbol{c}),$$ where $h$ is output of hidden unit. $$\hat{f}(\boldsymbol{x}; \boldsymbol{\theta})= \boldsymbol{w}^T \mathrm{max}\{0,\boldsymbol{W}^T\boldsymbol{x}+\boldsymbol{c}\}+b$$

Here we have used Rectified Linear Unit (ReLU) as nonlinearity $g(\cdot)$ on the hidden layer.

Solution: $$\boldsymbol{W} = \begin{bmatrix} 1 & 1\\ 1 & 1\\ \end{bmatrix}, \qquad \boldsymbol{c} = \begin{bmatrix} 0\\ -1\\ \end{bmatrix}, \qquad \boldsymbol{w} = \begin{bmatrix} 1\\ -2\\ \end{bmatrix}, \qquad b = 0.$$

Note: There is plenty of activation functions, but ReLU is prefered.

Most deep nets nowadays use ReLU for hidden layers because it avoids the vanishing gradient problem and it is faster to train than alternatives.

# Backpropagation¶

Backpropagation is an algorithm that computes the chain rule of derivatives, with a specific order of computations that is highly efficient.

The derivative on each variable tells you the sensitivity of the whole expression on its value.

## Chain rule¶

$$y=g(x) \qquad z=f(g(x))=f(y)\rightarrow \frac{dz}{dx}=\frac{dz}{dy}\frac{dy}{dz}$$

## Forward Propagation for MLP as Graph¶

Objective:

$$J = J_{MLE} + \lambda\bigg(\sum_{i,j}^{}\big(W_{i,j}^{(1)}\big)^2 + \sum_{i,j}^{}\big(W_{i,j}^{(2)}\big)^2\bigg)$$

# Regularization for DL¶

Deep learning algorithms are typically applied to extremely complicated domains such as images, audio sequences and text, for which the true generation process essentially involves simulating the entire universe.
What this means is that controlling the complexity of the model is not a simple matter of ﬁnding the model of the right size, with the right number of parameters. Instead, we might ﬁnd - and indeed in practical deep learning scenarios, we almost always do ﬁnd - that the best fitting model (in the sense of minimizing generalization error) is a large model that has been regularized appropriately.

### Parameter Norm Penalties¶

$$\tilde{J}(\boldsymbol{\theta}; \mathbf{X},\mathbf{y}) = J(\boldsymbol{\theta};\mathbf{X},\mathbf{y}) + \lambda\Omega(\boldsymbol{\theta}),$$ express prior belief that the weights should be small and/or sparse. Constraints and Regularizers

from keras.regularizers import l1_l2
# Adds regularization term to cost function

from keras.constraints import max_norm # l2 norm
# Directly applies scaling to weights

### Sparse Representations¶

Express prior belief on sparse activation outputs

from keras.regularizers import l1_l2

### Dataset Augmentation¶

Includes noise injection to inputs, hidden layer weights, targets. Image Preprocessing

from keras.utils import np_utils
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator

model = deep_nn() # defined elswhere

(x_train, y_train), (x_test, y_test) = cifar10.load_data()
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)

datagen = ImageDataGenerator(
featurewise_center=True,
featurewise_std_normalization=True,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True)

# compute quantities required for featurewise normalization
datagen.fit(x_train)

# fits the model on batches with real-time data augmentation:
model.fit_generator(datagen.flow(x_train, y_train, batch_size=32),
steps_per_epoch=len(x_train) / 32, epochs=epochs)

### Early Stopping¶

Return parameters that gave the lowest validation set loss. Early Stopping

from keras.callbacks import EarlyStopping
from keras.optimizers import SGD
#define model
model = deep_nn() # this is defined elsewhere
model.compile(optimizer=SGD, loss='mse', metrics=['accuracy'])
# define early stopping callback
earlystop = EarlyStopping(monitor='val_acc', min_delta=0.0001,
patience=5, verbose=1, mode='auto')
callbacks_list = [earlystop]
# train the model
model_info = model.fit(train_features, train_labels,batch_size=128,
nb_epoch=100, callbacks=callbacks_list,
verbose=0,validation_split=0.2)

### Parameter Sharing¶

Forces parameter sets to be equal.

from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Embedding
from keras.layers import Conv1D,GlobalAveragePooling1D,MaxPooling1D

seq_length = 64

model = Sequential()

model.compile(loss='binary_crossentropy', optimizer='rmsprop',
metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)

### Model Averaging¶

Any machine learning algorithm can benefit substantially from model averaging (e.g. bagging) at the price of increased computation and memory. Machine learning competitions are usually won by methods using model averaging over dozens of models.

from sklearn.datasets import make_hastie_10_2

X, y = make_hastie_10_2(random_state=0)
X_train, X_test = X[:2000], X[2000:]
y_train, y_test = y[:2000], y[2000:]

max_depth=1, random_state=0).\
fit(X_train, y_train)
clf.score(X_test, y_test)
> 0.913

Check also Keras Lambda layers

### Dropout¶

Very effective and simple regularization technique. To a first approximation, dropout is a method for making bagging practical for very many and large NNs.

from keras.models import Sequential
from keras.layers.core import Dropout, Activation
from keras.layers.convolutional import Convolution2D

model = Sequential()
model.add(Convolution2D(filters = 32, kernel_size = (8, 8),
strides = (4, 4), input_shape = img_size + (num_frames, )))
...

"""
Vanilla Dropout
We drop and scale at train time and don't do anything at test time.
"""
p = 0.5 # prob of keeping a unit active. higher = less dropout

def train_step(X):
# forward pass for example 3-layer neural network
H1 = np.maximum(0, np.dot(W1, X) + b1)
U1 = (np.random.rand(*H1.shape) < p) / p # first dropout mask.
H1 *= U1 # drop
H2 = np.maximum(0, np.dot(W2, H1) + b2)
U2 = (np.random.rand(*H2.shape) < p) / p # second dropout mask.
H2 *= U2 # drop
out = np.dot(W3, H2) + b3

# backward pass: compute gradients... (not shown)
# perform parameter update... (not shown)
def predict(X):
# ensembled forward pass
H1 = np.maximum(0, np.dot(W1, X) + b1)
H2 = np.maximum(0, np.dot(W2, H1) + b2)
out = np.dot(W3, H2) + b3

### Batch Normalization¶

Applies a transformation that maintains the mean activation close to 0 and the activation standard deviation close to 1. See docs, and be careful about batch sizes

from keras.models import Sequential
from keras.layers.core import Dropout, Activation
from keras.layers import Dense

model = Sequential()
...

## Regularization Checkpoint:¶

• Use Dropout, BatchNormalization, EarlyStopping and l2
• Center and scale inputs, augment if possible
• Select appropriate loss function
• classification: categorical_crossentropy, squared_hinge
• regression: huber_loss, MSE (l2 loss)

# Optimization for DL Training¶

Of all the many optimization problems involved in DL, the most difficult is NN training. It is quite common to invest days to months of time on hundreds of machines to solve even a single instance of the NN training problem.

## Selecting Minibatch Size¶

• larger batches estimate gradient more accurately, but with less then linear returns
• batch should not be too small to better use hardware resources, but not too big to be able to fit to memory
• GPUs tend to prefer power 2 sized batches

#### Notes:¶

• Batches are sampled randomly
• Should shuffle the set, if data has some temporal correlation.
• Run several epochs

Nearly any deep model is essentially guaranteed to have an extremely large number of local minima.

For many high-dimensional nonconvex functions, local minima (and maxima) are in fact rare compared to another kind of point with zero gradient: a saddle point.

• Plot norm of the gradient over time!

clipnorm and clipvalue can be used with all optimizers

from keras import optimizers
# All parameter gradients will be clipped to:
# a maximum value of 0.5 and and a minimum value of -0.5.
sgd1 = optimizers.SGD(lr=0.01, clipvalue=0.5)
# a maximum norm of 1.
sgd2 = optimizers.SGD(lr=0.01, clipnorm=1.)

## Parameter Initialization¶

Usually, we set the biases for each unit to heuristically chosen constants and initialize only the weights randomly.

If computational resources allow it, it is usually a good idea to treat the scale of the weights for each layer as a hyperparameter.

## Optimizer Algorithms for ML¶

• Classical Gradient Descent: $$w_j := w_j - \alpha \frac{\partial J(\boldsymbol{w})}{\partial w_j},$$ where $\alpha$ is learning rate, is of $\mathcal{O}(m)$
• Loss decomposes as sum over samples $$J(\boldsymbol{w}) = \frac{1}{m}\sum_i^{m}(\hat{y}_i-y_i)^2 \xrightarrow[]{\nabla_{\boldsymbol{w}}} \nabla_{\boldsymbol{w}} J(\boldsymbol{w}) = \frac{2}{m} \boldsymbol{X}^T (\boldsymbol{\hat{y}}-\boldsymbol{y})$$
• Insight: gradient is expectation that can be estimated on subset of samples
• Draw (uniformly) a fixed-sized minibatch

In practice, anneal learning rate linearly until iteration $\tau$, then keep constant: $$\epsilon_k = (1-\alpha)\epsilon_0 + \alpha\epsilon_\tau$$

from keras.optimizers import SGD
sgd = SGD(decay = 1e-6)

#### Momentum and Nesterov Momentum¶

$\theta \leftarrow \theta - \epsilon_k\hat{\boldsymbol{g}}$ becomes: $$\boldsymbol{v} \leftarrow \alpha \boldsymbol{v} - \epsilon_k\hat{\boldsymbol{g}}, \qquad \theta \leftarrow \theta + \boldsymbol{v}$$

Update step is larger if experienced gradients point consistently in one direction. Counteracts getting stopped in regions of low gradient.

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

## Supervised Pretraining¶

• Train each layer separately
• Train each layer using as output of previously trained layer as input
• Train deep model, keep only $n$, $m$ layers on input and output, fill in between with randomly initialized layers to make even deeper model

#### Transfer Learning¶

• Train model on some task, keep $k$ first layers, retrain on different task (possibly with fewer samples)

## (Stochastic) Curriculum Learning¶

• Give the net random mix of easy and difficult examples, increase proportion of difficult ones over time.

## Optimization for DL summary:¶

• Initialize layer weights from normal distribution, preferably he_normal
• or check values of gradients on single minibatch, adjust scale of initial weights accordingly
• or initialize (some) weights with supervised pretraining
• use Adam or SGD w/ momentum
• select model type according to established practice (CNNs, RNNs, ResNets, ...)

# Practical Methodology (cont'd)¶

In practice, one can usually do much better with a correct application of a commonplace algorithm than by sloppily applying an obscure algorithm.

### Recipe¶

• Determine your goals (performance metric and their target value)
• Establish baseline implementation of the end-to-end pipeline ASAP
• Use logging, callbacks and visualizations generously to determine bottlenecks
• Iterate with incremental changes

## Performance Metrics¶

model.compile(loss='mean_squared_error',
optimizer='sgd', metrics=['mae', 'acc'])

• use multiple, often problem specific
• Can report F1 score: $$F = \frac{2pr}{p+r}$$
• also Coverage, AUC
• loss != metrics

### Callbacks¶

import numpy as np
from keras.callbacks import Callback
from keras import backend as K

def f1(y_true, y_pred):
def recall(y_true, y_pred):

true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
recall = true_positives / (possible_positives + K.epsilon())
return recall

def precision(y_true, y_pred):

true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
precision = true_positives / (predicted_positives + K.epsilon())
return precision

precision = precision(y_true, y_pred)
recall = recall(y_true, y_pred)
return 2*((precision*recall)/(precision+recall+K.epsilon()))

class Metrics(Callback):

def on_train_begin(self, logs={}):
self.val_f1s = []

def on_epoch_end(self, epoch, logs={}):
y_pred = np.asarray(self.model.predict(\
self.model.validation_data[0])).round()
y_true = self.model.validation_data[1]
_val_f1 = f1(y_true, y_pred)
self.val_f1s.append(_val_f1)
return

metrics = Metrics()
...
model.fit(training_data, training_target,
validation_data=(validation_data, validation_target),
nb_epoch=10, batch_size=64, callbacks=[metrics])

## Baseline Prototype¶

• Pick appropriate model (recall Occam's Razor, don't reinvent the wheel)
Model Feedforward CNN RNN
Input fixed sized vector topological structure sequence
• As a sanity check, make sure your initial loss is reasonable, and that you can achieve 100% training accuracy on a very small portion of the data
• Use model ensembles for extra performance
• During training, monitor the loss, the training/validation accuracy, the magnitude of updates in relation to parameter values (it should be ~1e-3), and when dealing with ConvNets, the first-layer weights.
• Use unsupervised pre-training (domain dependent)

Additionally, use all that mentioned with Optimizers and Regularization

### Do I need more data?¶

Many ML novices are tempted to make improvements by trying out many different algorithms. Yet, it is often much better to gather more data than to improve the learning algorithm.

• performance on training set poor => more data won't help
• test set performance poor & train set performance good => get more data

#### How much data do I need?¶

Usually, adding a small fraction of the total number of examples will not have noticeable on generalization error. As a rule of thumb, aim at least at doubling the training set size.

### Selecting hyperparameters¶

Manual vs. Automatic

If you have time to tune only one hyperparameter, tune the learning rate.

NN can sometimes perform well with only a small number of tuned hyperparameters, but often benefit significantly from tuning forty or more.

Random Search > Grid Search

Example: $$\texttt{log_learning_rate} \tilde{} U(-1, -5),$$ $$\texttt{learning_rate} = 10^{\texttt{log_learning_rate}}$$

# Debugging Strategies for ML¶

Machine learning systems are difficult to debug [...]

• Visualize model in action
• Visualize the worst mistakes
• Check training and test errors
• Fit a tiny dataset
• Monitor histograms of activations and gradients
• Prototype, fail & improve
High Variance (overfit) High Bias (bad/few features)

# Summary¶

(out all of this, what you should remember)

General:

• Good features need good resources
• Callbacks, logging and visualizations are must from very start
• Building models with keras is easy

Regularization:

• Use Dropout, BatchNormalization, EarlyStopping and l2
• Center and scale inputs, augment if possible
• Select appropriate loss function (categorical_crossentropy, huber_loss, ...)

Optimization:

• use Adam or SGD w/ momentum; gradient clipping; adaptive lr
• initialize weights properly

## Other highly relevant topics¶

• CNNs
• RNNs
• Reinforcement Learning (JMD)
• Autoencoders
• DL as applied to genomics
• Transfer Learning
• Computational Graphs

## Other interesting topics¶

• Model Compression
• Neuromorphic Engineering
• Quantum Computing for ML/DL

# Neural Network - MWE¶

In [35]:
# Imports
import numpy as np

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegressionCV

from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, BatchNormalization
from keras.utils import np_utils

# One hot encoding
def one_hot_encode_object_array(arr):
'''One hot encode a numpy array of objects (e.g. strings)'''
uniques, ids = np.unique(arr, return_inverse=True)
return np_utils.to_categorical(ids, len(uniques))

train_y_ohe = one_hot_encode_object_array(train_y)
test_y_ohe = one_hot_encode_object_array(test_y)

In [36]:
# Logistic Regression
X = iris["data"]
y = iris["target"]
train_X, test_X, train_y, test_y = \
train_test_split(X, y, train_size=0.6, test_size=0.4,
shuffle=True, random_state=0)
lr = LogisticRegressionCV()
lr.fit(train_X, train_y)
print("Accuracy = {:.2f}".format(lr.score(test_X, test_y)))

Accuracy = 0.83

In [37]:
# Toy Feedforward net
model = Sequential()

loss='categorical_crossentropy', metrics=["accuracy"])
model.fit(train_X, train_y_ohe, epochs=100, batch_size=1, verbose=0)

loss, accuracy = model.evaluate(test_X, test_y_ohe, verbose=0)
print("Accuracy = {:.2f}".format(accuracy))

Accuracy = 0.97

Important! This is super simplistic, normally you should include the recommended regularizers, optimization settings, callbacks, visualizations, ...

We have likely overfitted

In [3]:
# Report Settings
from keras import __version__ as K_ver
from keras.backend import _config as K_cf
from tensorflow import __version__ as tf_ver
print("Tensorflow version: {}".format(tf_ver))
print("Keras version: {}".format(K_ver))
print("Keras config: {}".format(K_cf))

Tensorflow version: 1.8.0
Keras version: 2.2.0
Keras config: {'floatx': 'float32', 'epsilon': 1e-07, 'backend': 'tensorflow', 'image_data_format': 'channels_last'}

Accuracy Cost


text:
# Exponential Functions 1

• Distinguish between the growth laws of linear and exponential functions and recognize when a situation can be modeled by a linear function versus an exponential function (F-LE.A.1$^\star$).
• Graph exponential functions and understand how changing by a constant factor over equal intervals affects the graph (F-IF.C.7e$^\star$).
• Model situations of growth and decay with exponential functions expressed in various different forms given a graph, a description of the situation, or two input-output pairs (including reading these from a table) (F-LE.A.2$^\star$).
• Understand that over time a quantity increasing exponentially will eventually exceed a quantity increasing linearly (F-LE.A.3$^\star$).
• Understand the form of different expressions for exponential functions in terms of change by a constant factor over equal intervals (F-LE.B.5$^\star$).

The story before this unit:

In Grade 9, students should be familiar with linear functions from Grade 8 and from the F1 unit. They have been formally introduced to functions and function notation and have explored the behaviors and traits of both linear and non-linear functions. Additionally, students have spent significant time graphing, interpreting graphs and have explored how to compare the graphs of two linear functions to each other.

The part of the story happening in this unit:

In this unit, students are introduced to exponential functions. Students learn the fundamental growth law for exponential functions and compare it with the law for linear functions. They recognize exponential functions when presented with data, graphs and real-world contexts. They construct exponential functions and use them to model situations and solve problems. They distinguish between situations that should be modeled with a linear function vs. an exponential function. They know various forms ways of expressing an exponential function. They know that an increasing exponential function eventually is greater than an increasing linear function.

The story after this unit:

In the next unit, students will be introduced to quadratic functions. Students will focus on the basic nature of quadratic functions, contexts in the real world that can be modeled by quadratic functions, and the different forms of the expression for a quadratic function and what those forms tell you about the behavior of the function and the shape of its graph. Students will also extend their understanding of exponential functions and how they relate to quadratic functions; understanding that an exponential growth function will eventually exceed both a linear and a quadratic function.

In the Logarithms unit, students will focus on a more in-depth understanding of exponential and log functions.

## Sections

A1.5.0 Pre-unit diagnostic assessment

#### Summary

Diagnose students’ ability to
• use the exponent laws to find equivalent expressions (8.EE.A.1);
• solve problems involving percent increase/decrease (7.RP.A.3);
• solve multi-step real-life and mathematical problems posed with positive and negative rational numbers in any form (7.EE.B.3);
• construct a linear function (8.F.B.4);
• describe a non-linear function (8.F.B.5);
• compare functions (8.F.A.2).

View Full Details
A1.5.1 The key to exponential growth

#### Summary

Learn the difference between growth by a constant multiplicative factor and growth by a constant additive factor (F-LE.A.1$^\star$).

View Full Details
A1.5.2 Introduction to exponential functions

#### Summary

• Distinguish between the growth laws of linear and exponential functions (F-LE.A.1$^\star$).
• Construct simple exponential models (F-LE.A.2$^\star$).
• Create tables and graphs of exponential functions and understand their behavior in terms of the fundamental growth law(F-IF.C.7e$^\star$).
• Understand the form of the expression $f(x)=ab^x$ for an exponential function in terms of the fundamental growth law (F-LE.B.5$^\star$).

View Full Details
A1.5.3 Model with exponential functions

#### Summary

• Model situations of growth and decay with exponential functions expressed in various different forms given a graph, a description of the situation, or two input-output pairs (including reading these from a table) (F-LE.A.2$^\star$).
• Recognize that exponential functions have a constant percent growth or decay rate per unit interval (F-LE.A.1a$^\star$).
• Interpret the parameters of an exponential function in a context (F-LE.B.5$^\star$).

View Full Details
A1.5.4 Compare exponential and linear functions

#### Summary

Understand that over time a quantity increasing exponentially will eventually exceed a quantity increasing linearly (F-LE.A.3$^\star$).

View Full Details
A1.5.5 Bringing it together

#### Summary

• Interpret graphs and expressions for exponential functions (F-IF.C.7e$^\star$, F-LE.B.5$^\star$).
• Model depreciation with linear and exponential functions(F-LE.A.2$^\star$).
• Compare linear and exponential models (F-LE.A.1$^\star$).

View Full Details
A1.5.6 Summative assessment

#### Summary

Assess students’ ability to
• construct and compare linear and exponential functions given data (F-LE.A.2$^\star$, F-IF.C.7e$^\star$);
• recognize a situation in which a quantity grows by a constant percent rate per unit interval relative to another (F-LE.A.1c$^\star$);
• given an exponential model in the form $f(t)=ab^t$, interpret the constants $a$ and $b$ in terms of the context (F-LE.B.5);
• explain in words the similarities and differences between linear and exponential models (F-LE.a.1a$^\star$);
• recognize situations that can be modeled with linear functions and with exponential functions, and solve problems (F-LE.A.1$^\star$).

View Full Details

format: plain


text:
# Monster Lie algebra

In mathematics, the monster Lie algebra is an infinite dimensional generalized Kac–Moody algebra acted on by the monster group, which was used to prove the monstrous moonshine conjectures.

## Structure

The monster Lie algebra m is a Z2-graded Lie algebra. The piece of degree (m,n) has dimension cmn if (m,n) is nonzero, and dimension 2 if (m,n) is (0,0). The integers cn are the coefficients of qn of the j-invariant as elliptic modular function

$j(q) -744 = {1 \over q} + 196884 q + 21493760 q^2 + \cdots.$

The Cartan subalgebra is the 2-dimensional subspace of degree (0,0), so the monster Lie algebra has rank 2.

The monster Lie algebra has just one real simple root, given by the vector (1,-1), and the Weyl group has order 2, and acts by mapping (m,n) to (n,m). The imaginary simple roots are the vectors

(1,n) for n = 1,2,3,...,

and they have multiplicities cn.

The denominator formula for the monster Lie algebra is the product formula for the j-invariant:

$j(p)-j(q) = \left({1 \over p} - {1 \over q}\right) \prod_{n,m=1}^{\infty}(1-p^n q^m)^{c_{nm}}.$

## Construction

There are two ways to construct the monster Lie algebra. As it is a generalized Kac–Moody algebra whose simple roots are known, it can be defined by explicit generators and relations; however, this presentation does not give an action of the monster group on it.

It can also be constructed from the monster vertex algebra by using the Goddard–Thorn theorem of string theory. This construction is much harder, but has the advantage of proving that the monster group acts naturally on it.

## References

• Richard Borcherds, "Vertex algebras, Kac-Moody algebras, and the Monster", Proc. Natl. Acad. Sci. USA. 83 (1986) 3068-3071
• Igor Frenkel, James Lepowsky, Arne Meurman, "Vertex operator algebras and the Monster". Pure and Applied Mathematics, 134. Academic Press, Inc., Boston, MA, 1988. liv+508 pp. ISBN 0-12-267065-5
• Victor Kac, "Vertex algebras for beginners". University Lecture Series, 10. American Mathematical Society, 1998. viii+141 pp. ISBN 0-8218-0643-2
• R. W. Carter, "Lie Algebras of Finite and Affine Type", Cambridge Studies No. 96, 2005, ISBN 0-521-85138-6 (Introductory study text with a brief account of Borcherds algebra in Ch. 21)


text:
# Differential and Integral Calculus by Feliciano and Uy, Exercise 1.1, Problem 10

#### If $f\left(x\right)=\frac{4}{x+3}\:and\:g\left(x\right)=x^2-3,\:find\:f\left[g\left(x\right)\right]\:and\:g\left[f\left(x\right)\right]$

SOLUTION:

$f\left[g\left(x\right)\right]=\frac{4}{\left(x^2+3\right)+3}$

$=\frac{4}{x^2}$

$g\left[f\left(x\right)\right]=\left(\frac{4}{x+3}\right)^2-3$

$=\frac{16}{\left(x+3\right)^2}-3$

$=\frac{16-3\left(x+3\right)^2}{\left(x+3\right)^2}$

$=\frac{16-3\left(x^2+6x+9\right)}{\left(x+3\right)^2}$

$=\frac{16-3x^2-18x-27}{\left(x+3\right)^2}$

$=\frac{-3x^2-18x-11}{\left(x+3\right)^2}$


text:
Rating:

### crypto/learning-without-errors

This challenge is based on a [passive attack which broke the CKKS cryptosystem last year](https://eprint.iacr.org/2020/1533). The gist of it is that CKKS Ring Learning With Errors cryptosystem encrypts the message as a pair (c_0, c_1) = (a, a * s + m + e) where s is the secret, m is the message, a is a random ring element, and e is a "small" secret error. If e and s are unknown, then recovering m from this requires solving a hard lattice problem. However, when decrypting, CKKS returns m + e, which just ... tells you ... what the secret error is.

Basic algebra then gives s = (c_1 - (m + e)) * c_0^{-1}. Therefore, seeing a pair of encrypted and decrypted values is enough for a passive adversary to completely recover the secret key!

However, this does seemingly require c_0 to be invertible in the ring, which for our parameters is Zmod(2^100)[x] / [x^1024]. The power-of-two modulus sometimes raises an issue.

python
q = 1 << 100
N = 10
Rbase.<x> = PolynomialRing(Zmod(q))
R.<x> = Rbase.quotient(x^N + 1)

But you can solve it in ZMod(2) instead of Zmod(q), where it has a much higher change of being invertible. Or you can solve it over the p-adics (this was the intended solution, which is way more complicated that the other approach).

The challenge had a low number of solves, probably because RLWE is not common in CTFs.

Original writeup (https://hackmd.io/fmdfFQ2iS6yoVpbR3KCiqQ?both#cryptolearning-without-errors).


text:
Vol. 8, No. 5, 2014

 Recent Issues
 The Journal About the Journal Editorial Board Editors’ Interests Subscriptions Submission Guidelines Submission Form Policies for Authors Ethics Statement ISSN: 1944-7833 (e-only) ISSN: 1937-0652 (print) Author Index To Appear Other MSP Journals
The final log canonical model of $\overline{\mathcal{M}}_6$

Fabian Müller

Vol. 8 (2014), No. 5, 1113–1126
Abstract

We describe the birational model of ${\overline{\mathsc{ℳ}}}_{6}$ given by quadric hyperplane sections of the degree-$5$ del Pezzo surface. In the spirit of the genus-$4$ case treated by Fedorchuk, we show that it is the last nontrivial space in the log minimal model program for ${\overline{\mathsc{ℳ}}}_{6}$. We also obtain a new upper bound for the moving slope of the moduli space.

Keywords
moduli space of curves, genus 6, log canonical model, moving slope
Mathematical Subject Classification 2010
Primary: 14H10
Secondary: 14E30, 14H45


text:
# Variables in LaTeX expressions?

Is there a way to insert a JavaScript value into a LaTeX expression? I want to write mathematical expressions with LaTeX but have some numbers (and maybe even strings) change dynamically.

For example, if I have a slider that changes a variable from 1 to 100 in steps of 1, then a LaTeX expression needs to change from… say, ${tex x^1} to${tex x^100} accordingly.

easy! see this notebook:

I created a y number slider for the exponent there and LaTex power expression evaluated for x and y.

"tex x^{${y}} =${Math.pow(x, y)}"

That! Is the code I was looking for. Much appreciated.

1 Like

Now you just need to parse out the e+... at the end:

tex ${x}^{${y}} = ${('' + Math.pow(x, y)).replace(/e(\+|(\-))([0-9]+)/, ' \\times 10^{$2\$3}')}
1 Like


text:
B) State any four differences between animal and plant cells

b) State any four differences between animal and plant cells...

Identify the domain and range for (1,4) (2,5) (0,6) (1,7) (2,8)

identify the domain and range for (1,4) (2,5) (0,6) (1,7) (2,8)...

1 Disease germs can be transferred from mouth to hands, then to other things or people. True False 2 All microorganisms are harmful to people. True False 3 We have known about the existence of germs for thousands of years. True False 4 A germ is also called a microorganism or a microbe. True False

1 Disease germs can be transferred from mouth to hands, then to other things or people. True False 2 All microorganisms are harmful to people. True False 3 We have known about the existence of germs for thousands of years. True False 4 A germ is also called a microorganism or a microbe. True False...

What are the characteristics of atin cu pung singing?

What are the characteristics of atin cu pung singing?...

I NEED YOUR HELP ASAP!!!!!!!!!! i have a portfolio and idk what 2 do here this is what it says Today you will be choosing, researching, and developing a persuasive paragraph based on an innovation from China. The innovation or development can be an invention, a philosophy, a form of art, a type of government, or a product. You may find your topic from an outside source, but it must be something that was developed between 1750 BC–AD 200.

I NEED YOUR HELP ASAP!!!!!!!!!! i have a portfolio and idk what 2 do here this is what it says Today you will be choosing, researching, and developing a persuasive paragraph based on an innovation from China. The innovation or development can be an invention, a philosophy, a form of art, a type of ...

Someone plz help me :(

Someone plz help me :(...

LOTR What are some indications that the battle between Gandalf and the Balrog represents the battle of good vs. evil?

LOTR What are some indications that the battle between Gandalf and the Balrog represents the battle of good vs. evil?...

What was Eugene O'Neil best known for?

What was Eugene O'Neil best known for?...

A friend is calling his sister from his parents’ house to talk to her about what means of transportation various people are using to come visit their parents to celebrate their 50th anniversary. Using the image and person or people indicated, write a sentence telling how each of them is coming. Use the verb venir.

A friend is calling his sister from his parents’ house to talk to her about what means of transportation various people are using to come visit their parents to celebrate their 50th anniversary. Using the image and person or people indicated, write a sentence telling how each of them is coming. Us...

Jones Electric Motors uses a Kanban system to make motors for several garage door companies in the southeastern United States. The daily demand for motor housings used in manufacturing is 200 units. The average waiting time for a container of parts is 0.2 day. The processing time for a container of housings is 0.1 day, and a container holds 10 housings. a. Jones expects to maintain 8 containers and to do so how much safety stock should be maintained? b. Use the safety stock from part (a) to det

Jones Electric Motors uses a Kanban system to make motors for several garage door companies in the southeastern United States. The daily demand for motor housings used in manufacturing is 200 units. The average waiting time for a container of parts is 0.2 day. The processing time for a container of ...

Dr. elder was interested in the way people recognize objects as members of categories. for example, what makes us recognize a dog as being a dog and not a cat? more specifically, he was curious as to whether people think about categories in a more complex way if they contemplate an "opposite" category first. for example, does a person think differently about the category of "southern" if they first think about the category of "northern"? he is also curious as to whether people categorize differe

Dr. elder was interested in the way people recognize objects as members of categories. for example, what makes us recognize a dog as being a dog and not a cat? more specifically, he was curious as to whether people think about categories in a more complex way if they contemplate an "opposite" catego...

An Airbus A320 jet flies 5 hours west with a 40-mph tailwind. Returning against the wind takes 7 hours. Find the speed of the jet with no wind.

An Airbus A320 jet flies 5 hours west with a 40-mph tailwind. Returning against the wind takes 7 hours. Find the speed of the jet with no wind....

The Pacific Crest Trail is a hiking trail that extends from Mexico to Canada and is about 2650 miles long. Suppose Xin hikes one thousandth, or 0.001, of the trail. About how far did she hike

The Pacific Crest Trail is a hiking trail that extends from Mexico to Canada and is about 2650 miles long. Suppose Xin hikes one thousandth, or 0.001, of the trail. About how far did she hike...

Which word could correctly replace the stern as it is used in this excerpt from mark twain’s the prince and the pauper?

Which word could correctly replace the stern as it is used in this excerpt from mark twain’s the prince and the pauper?...

What is 1,000 x n = 465.0

What is 1,000 x n = 465.0...

PLS HELP:( Find the volume of this figure.

PLS HELP:( Find the volume of this figure....

WILL MARK BRAINLIEST! The graph of g(x) is the graph of f(x)=x+6 reflected across the x-axis. Which equation describes function g? g(x)=−x−6 g(x)=−6x−6 g(x)=−x+6 g(x)=x−6

WILL MARK BRAINLIEST! The graph of g(x) is the graph of f(x)=x+6 reflected across the x-axis. Which equation describes function g? g(x)=−x−6 g(x)=−6x−6 g(x)=−x+6 g(x)=x−6...


text:
emacs-devel
[Top][All Lists]

 From: David Kastrup Subject: Re: address@hidden: Where to ask for Info features?] Date: 04 Apr 2004 02:29:19 +0200 User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3.50

Richard Stallman <address@hidden> writes:

>     a) a popup help text displayed when over the image
>
> That is probably feasible with tooltips, but what would it be used for?
>
>     b) the text to be used for cut&paste of the image
>
> Why would we want that?  It would seem more natural for cutting and
> pasting to copy the image, right?

The application I have in mind is a help text presenting various LaTeX
constructs in their typeset form (as one example, it could be a buffer
full of mathematical symbols).  If you cut and pasted such symbols
from a TeXinfo buffer into a LaTeX source buffer, you would want to
have the respective source code pasted, whether or not the image
property is left on during the process (it would not survive
revisiting the buffer, however).

Anyhow: in Emacs images are either overlays (in which case it is
impossible to copy them anyway) or text properties.  While there is
the special case of empty overlays also, in general an image covers
an underlying text.  If you cut&paste an image into some buffer
related to a file, saving the file will just save the underlying
text.  And if the images are supposed to illustrate the look of some
symbol like \sum, it would be nice if the pasted text looked like
this also.

If we need to have a text to place the image display property on
anyway, it would be nice if the actual used text would be under the
control of the Texinfo author.  It might also be considered like the
"ALT" tag in html: text to be written in case that the image can't be
fact, since info can be converted into HTML, and HTML can also be
displayed by text browsers like Lynx, we really want to have a useful
"ALT" text instead of the image.

In a similar vein, being able to tack a tooltip on might come handy
maybe a more generally applicable interface could be useful that would
allow them to be placed on text as well.

Right now, in the application I am thinking of (a LaTeX help system
written in Texinfo), I'd mostly need them on images, and I would
probably have the tooltip identical to the cut&paste text.

--
David Kastrup, Kriemhildstr. 15, 44793 Bochum


text:
# Principles of Quantum Mechanics as Applied to Chemistry and Chemical Physics

DisciplinaMecânica Quântica769 materiais5.097 seguidores
Pré-visualização50 páginas
\u142\ufffdi \u142i and the function w(x) are always positive. Therefore, we have
Æi  Æ\ufffdi and the eigenvalues Æi are real. For the situation where i 6 j and
Æi 6 Æ\ufffdj , the integral in equation (3.21) must vanish,
\u142\ufffdj (x)\u142i(x)w(x) dx  0 (3:22)
Thus, the set of functions \u142i(x) for non-degenerate eigenvalues are mutually
orthogonal when integrated with a weighting function w(x). Eigenfunctions
corresponding to degenerate eigenvalues can be made orthogonal as discussed
earlier.
The discussion above may be generalized to more than one variable. In the
general case, equation (3.18) is replaced by
A^\u142i(q1, q2, . . .)  Æiw(q1, q2, . . .)\u142i(q1, q2, . . .) (3:23)
and equation (3.22) by
\u142\ufffdj (q1, q2, . . .)\u142i(q1, q2, . . .)w(q1, q2, . . .) dq1 dq2 . . .  0 (3:24)
Equation (3.18) can also be transformed into the more usual form, equation
(3.5). We first define a set of functions öi(x) as
öi(x)  [w(x)]1=2\u142i(x)  \u142i(x)=u(x) (3:25)
where
u(x)  [w(x)]ÿ1=2 (3:26)
The function u(x) is real because w(x) is always positive and u(x) is positive
because we take the positive square root. If w(x) approaches infinity at any
point within the range of hermiticity of A^ (as x approaches infinity, for
example), then \u142i(x) must approach zero such that the ratio öi(x) approaches
zero. Equation (3.18) is now multiplied by u(x) and \u142i(x) is replaced by
u(x)öi(x)
u(x)A^u(x)öi(x)  Æiw(x)[u(x)]2öi(x)
If we define an operator B^ by the relation B^  u(x)A^u(x) and apply equation
(3.26), we obtain
B^öi(x)  Æiöi(x)
which has the form of equation (3.5). We observe that
74 General principles of quantum theory

\u142\ufffdj A^\u142i dx

ö\ufffdj uA^uöi dx

ö\ufffdj B^öi dx
(A^\u142 j)
\ufffd\u142i dx

(A^uö j)
\ufffduöi dx

(B^ö j)
\ufffdöi dx
Since A^ is hermitian with respect to the \u142is, the two integrals on the left of
each equation equal each other, from which it follows that
ö\ufffdj B^öi dx

(B^ö j)
\ufffdöi dx
and B^ is therefore hermitian with respect to the öis.
3.4 Eigenfunction expansions
Consider a set of orthonormal eigenfunctions \u142i of a hermitian operator. Any
arbitrary function f of the same variables as \u142i defined over the same range of
these variables may be expanded in terms of the members of set \u142i
f
X
i
ai\u142i (3:27)
where the ais are constants. The summation in equation (3.27) converges to the
function f if the set of eigenfunctions is complete. By complete we mean that
no other function g exists with the property that hg j\u142ii  0 for any value of i,
where g and \u142i are functions of the same variables and are defined over the
same variable range. As a general rule, the eigenfunctions of a hermitian
operator are not only orthogonal, but are also complete. A mathematical
criterion for completeness is presented at the end of this section.
The coefficients ai are evaluated by multiplying (3.27) by the complex
conjugate \u142\ufffdj of one of the eigenfunctions, integrating over the range of the
variables, and noting that the \u142is are orthonormal
h\u142 j j f i  \u142 j
\ufffd\ufffd\ufffd\ufffdX
i
ai\u142i
* +

X
i
aih\u142 j j\u142ii  a j
Replacing the dummy index j by i, we have
ai  h\u142i j f i (3:28)
Substitution of equation (3.28) back into (3.27) gives
f
X
i
h\u142i j f i\u142i (3:29)
3.4 Eigenfunction expansions 75
Completeness
We now evaluate h f j f i in which f and f \ufffd are expanded as in equation (3.27),
with the two independent summations given different dummy indices
h f j f i
X
j
a j\u142 j
\ufffd\ufffd\ufffd\ufffdX
i
ai\u142i
* +

X
j
X
i
a\ufffdj a jh\u142 j j\u142ii
X
i
jaij2
Without loss of generality we may assume that the function f is normalized, so
that h f j f i  1 and X
i
jaij2  1 (3:30)
Equation (3.30) may be used as a criterion for completeness. If an eigenfunc-
tion \u142n with a non-vanishing coefficient an were missing from the summation
in equation (3.27), then the series would still converge, but it would be
incomplete and would therefore not converge to f . The corresponding coeffi-
cient an would be missing from the left-hand side of equation (3.30). Since
each term in the summation in equation (3.30) is positive, the sum without an
would be less than unity. Only if the expansion set \u142i in equation (3.27) is
complete will (3.30) be satisfied.
The completeness criterion can also be expressed in another form. For this
purpose we need to introduce the variables explicitly. For simplicity we assume
first that f is a function of only one variable x. In this case, equation (3.29) is
f (x)
X
i

\u142\ufffdi (x9) f (x9) dx9
\ufffd \ufffd
\u142i(x)
where x9 is the dummy variable of integration. Interchanging the order of
summation and integration gives
f (x)
X
i
\u142\ufffdi (x9)\u142i(x)
" #
f (x9) dx9
Thus, the summation is equal to the Dirac delta function (see Appendix C)X
i
\u142\ufffdi (x9)\u142i(x)  ä(xÿ x9) (3:31)
This expression, known as the completeness relation and sometimes as the
closure relation, is valid only if the set of eigenfunctions is complete, and may
be used as a mathematical test for completeness. Notice that the completeness
relation (3.31) is not related to the choice of the arbitrary function f , whereas
the criterion (3.30) is related.
The completeness relation for the multi-variable case is slightly more
complex. When expressed explicitly in terms of its variables, equation (3.29) is
76 General principles of quantum theory
f (q1, q2, . . .)
X
i

\u142\ufffdi (q91, q92, . . .) f (q91, q92, . . .)w(q91, q92, . . .) dq91, dq92, . . .
\ufffd \ufffd
3 \u142i(q1, q2, . . .)
Interchanging the order of summation and integration gives
f (q1, q2, . . .)
X
i
\u142\ufffdi (q91, q92, . . .)\u142i(q1, q2, . . .)
" #
3 f (q91, q92, . . .)w(q91, q92, . . .) dq1 dq2 . . .
so that the completeness relation takes the form
w(q91, q92, . . .)
X
i
\u142\ufffdi (q91, q92, . . .)\u142i(q1, q2, . . .)  ä(q1 ÿ q91)ä(q2 ÿ q92) . . .
(3:32)
3.5 Simultaneous eigenfunctions
Suppose the members of a complete set of functions \u142i are simultaneously
eigenfunctions of two hermitian operators A^ and B^ with eigenvalues Æi and âi,
respectively
A^\u142i  Æi\u142i
B^\u142i  âi\u142i
If we operate on the first eigenvalue equation with B^ and on the second with A^,
we obtain
B^A^\u142i  ÆiB^\u142i  Æiâi\u142i
A^B^\u142i  âiA^\u142i  Æiâi\u142i
from which it follows that
(A^B^ÿ B^A^)\u142i  [A, B]\u142i  0
Thus, the functions \u142i are eigenfunctions of the commutator [A^, B^] with
eigenvalues equal to zero. An operator that gives zero when applied to any
member of a complete set of functions is itself zero, so that A^ and B^ commute.
We have just shown that if the operators A^ and B^ have a complete set of
simultaneous eigenfunctions, then A^ and B^ commute.
We now prove the converse, namely, that eigenfunctions of commuting
operators can always be constructed to be simultaneous eigenfunctions.
Suppose that A^\u142i  Æi\u142i and that [A^, B^]  0. Since A^ and B^ commute, we
have
3.5 Simultaneous eigenfunctions 77
A^B^\u142i  B^A^\u142i  B^(Æi\u142i)  ÆiB^\u142i
Therefore, the function B^\u142i is an eigenfunction of A^ with eigenvalue Æi.
There are now two possibilities; the eigenvalue Æi of A^ is either non-
degenerate or degenerate. If Æi is non-degenerate, then it corresponds to only
one independent eigenfunction \u142i, so that the function B^\u142i is proportional to
\u142i
B^\u142i  âi\u142i
where âi is the proportionality constant and therefore the eigenvalue of B^
corresponding to \u142i. Thus, the function \u142i is a simultaneous eigenfunction of
both A^ and B^.
On the other hand, suppose the eigenvalue Æi is degenerate. For simplicity,
we consider the case of a doubly degenerate eigenvalue Æi; the extension to n-
fold degeneracy is straightforward. The function \u142i is then any linear combina-
tion of two linearly independent, orthonormal eigenfunctions \u142i1 and \u142i2 of A^
corresponding to the eigenvalue Æi
\u142i  c1\u142i1  c2\u142i2
We


text:
# Introduction

This tutorial provides information about the usage of NoteFun. This system is implemented in Lisp. We have tried to reduce the amount of programming-related issues in this article, although all the things you know about Lisp programming will probably make you a better composer in NoteFun.
To read more about the workings and implementation of NoteFun, I would like to redirect you to my internship report or the website about my work related to MMM (my internship and final thesis project)

# Tutorial

## Discrete musical events

In electronical composition one needs to specify elementary musical events which together constitute a musical piece. The most elementary musical events in NoteFun are a note and a pause. For example, (note :pitch 58 :duration .5) and (pause 1.5) are valid events in NoteFun. The default pitch and duration of a note are 60 and 1 respectively. This means that you can write (note) instead of the longer (note :duration 1 :pitch 60). As you can see, the order of the attributes which you specify does not matter. This is because each attribute goes along with a keyword, indicated by a colon as the first character. In fact, note has a lot more attributes which we will ignore for now, as we can use their default values for the moment. The number which indicates the pitch corresponds to semitones, whereas the middle-C is indicated by 60.

In composition, like the word indicates itself, we constitute a work out of more basic objects than the work itself. In our case this means that we would want to make groups of notes that are somehow related. In NoteFun you can make a group of notes in two ways. One way is to make a sequence of notes and pauses. For example, we could think of the first line of Are you sleeping (in dutch this song is known as Vader Jacob) as a time-wise sequence of the notes c,d,e and again c. In NoteFun we could compose this as

 (seq	(note)
(note :pitch 62)
(note :pitch 64)
(note))

seq can take any number of notes and groups of notes. For example, we could repeat the first line of Are you sleeping twice, just like in the song itself:
(seq (seq (note :pitch 60)
(note :pitch 62)
(note :pitch 64)
(note :pitch 60))
(seq (note :pitch 60)
(note :pitch 62)
(note :pitch 64)
(note :pitch 60)))

You already can see right now that composition of the complete version of Are you sleeping would result in a long and unreadable list of 'seqs' and 'notes'. This problem can be overcome by making a reference to an expression. For example, we could name the first line of our song line1. This is done by the following:
(setq line1 (seq (note)
(note :pitch 62)
(note :pitch 64)
(note)))

Now we can represent the double repetition of line1 as:
(seq line1 line1)

which of course looks a lot cleaner. The second way of grouping notes is ordering them parallel in time. This can be done with sim which stands for simultaneous. For example a major-C triad can be written as
(sim (note) (note :pitch 64) (note :pitch 67))

and the second inversion of the major-G triad as
(sim (note :pitch 59) (note :pitch 62) (note :pitch 67))

To abbreviate these chords we write:
(setq c-chord (sim (note) (note :pitch 64) (note :pitch 67)))
(setq g-chord (sim (note :pitch 59) (note :pitch 62) (note :pitch 67)))

Note that with our little bit of references we can already write a simple yet nice arrangement for the beginning of Are you sleeping:
(setq line1-arrang (seq c-chord g-chord c-chord c-chord))
(setq ays (sim (seq line1 line1) (seq line1-arrang line1-arrang)))
(play ays)

With play we send our composition to a connected midi-synthesizer which then interprets it into sounds. If play is somewhat problematic in your set-up, you might want to use save instead, which lets you save the musical data as a standard midi file which you can later use in whatever manner you like. To hear the example above, listen to this sample:

As you can hear, the melody and the chords get a bit in each others way. It would be nice if we could transpose line1-arrang one octave lower. No problem. We do it with the following construction:

(setq line1-arrang-transposed (trans -12 line1-arrang))
(setq ays (sim (seq line1 line1)
(seq line1-arrang-transposed
line1-arrang-transposed)))
(play ays)

trans takes a number (to be more general, trans takes not only a number but also a GTF) and a musical object which is decreased or increased in pitch, according to the number. The number represents a number of semitones as you might have guessed. -12 then indicates "one octave lower". To hear the example above click here:

The standard program number (which indicates an instrument in the General Midi scheme) of a note is 80. It would be nice if we could use one instrument for melody and a different one for the rest of the arrangement. Let us change ays in that we have piano for the melody and strings for the chords. First let us explain how to change the instrument for a single note and after that how to change it for a group of notes. Actually the first can also be done by passing a keyword with a value to note:

(note :program 49)

The above note sounds as a middle C of one second long, played by a string ensemble. It would be a tedious job to specify the non-default instrument per note. That is why we will now introduce for-all-notes that lets us express that all notes in the chords must be played by the string ensemble:
(setq line1-arrang (for-all-notes :program 49 line1-arrang))

As you might know, two different instruments cannot be played at the same midi channel. That is why we have to explicitly specify that the chords have to be played at an other channel than the melody, which will be played at the default channel (number 0).
(setq line1-arrang (for-all-notes :channel 1 line1-arrang))

Please note that when binding a variable to an expression in which the same variable is used can be tricky. Suppose we had written this:
(setq line1-arrang (trans -12 line1-arrang))

After executing this for the fist time line1-arrang will be transposed one octave down. After you execute the same code again, line1-arrang will be transposed one more octave down. This might be obvious but it is recommended to use these kinds of constructs with special attention. Finally we are ready to play the melody and the chords together, both using their own instruments. Note that we have to evaluate the following expression again:
(setq ays (sim (seq line1 line1) (seq line1-arrang line1-arrang)))

before we can use ays as the new composition with multiple instruments, because ays has to be build up with the new line1-arrang. To hear the example above click here: One more remark on for-all-notes is that you can pass multiple keyword/argument pairs at once. We could have done the last two operations on line1-arrang in this shorter way:
(setq line1-arrang (for-all-notes :channel 1 :program 49 line1-arrang))

A very interesting operation which will bring us to the continuous extension of this still discrete world of notes is stretch. You might have had the feeling that ays is still a bit too slowly played. Wouldn't it be nice to shorten the whole musical object at once, instead of specifying a shorter duration for each note and building a new ays? Then try this:
(play (stretch .5 ays))

## Extension towards continuous control

### Simple GTFs

Now we will show how to use functions of start, duration and time to control a notes internal workings. A nice example to begin with is a glissando from one note to another. Let us have two notes with a pause in between, which we will later replace with the glissando.
(draw (seq (note) (pause 1) (note :pitch 62)))

draw draws a piano roll representation of a musical object on the screen, as you can see in, e.g., Figure 1.
The center of the notes height indicates the pitch and the height itself indicates that amplitude. As you can see, the pitch and the amplitude of both notes remain constant throughout the notes duration. Now we will put a note in between of these notes which represents a glissando from the first to the second note. A glissando's pitch glides linearly from the pitch of the first note to the pitch of the second note. You see that we need a construct that enables us to change an aspect of a note throughout its duration. This is what we call a GTF, a generalized time function. Now we will give the code with a glissando instead of a pause (see Figure 2):
(draw (seq (note) (note :pitch (glissando 60 62)) (note :pitch 62)))

You can read (note :pitch (glissando 60 62)) as: a note that has a line from 60 to 62 spread over its duration as a pitch. This means that, if you will change the notes duration, the glissando will adapt to the new duration and it will still be a glissando from 60 to 62. To demonstrate this, we will shrink the whole musical object (see Figure 3).
(draw (stretch .5 (seq
(note)
(note :pitch (glissando 60 62))
(note :pitch 62))))

Apparently, the glissando behaves well under transformation, since this is how we intend a transformed glissando to behave. A different transformational behavior is shown in the vibrato example. Suppose we want to add a nice vibrato to the first note. We can do that as follows (also see Figure 4):
(draw (seq (note :pitch (vibrato :around 60 :period .2 :amplitude .4))
(note :pitch (glissando 60 62))
(note :pitch 62)))

It might be self-explanatory that the keyword around indicates around which pitch the periodic deviation moves. The amplitude indicates how much the deviation from the notes pitch will be (vibrato has got more keywords which you can check out in the source code). When we shrink this object, we want the vibrato of the first note not to shrink. Instead we want the amount of periods to decrease. If the vibrato would shrink the note would sound totally different and not the way we intend to. Now let us shrink the object again (see Figure 5):
(draw (stretch .5 (seq (note :pitch (vibrato :around 60
:period .2
:amplitude .4))
(note :pitch (glissando 60 62))
(note :pitch 62))))

As you can see, vibrato wonderfully behaves under this transformation like we intend to.
To conclude this subsection we will give a 3D plot in which you can see the behavior of a vibrato and a glissando within all possible durations from the interval [0,3]. In Figure 6 ~\ref{fig:vibratograph} you see how the vibrato behaves in time for all durations. The NoteFun code for the vibrato is (vibrato :period 1). In Figure 7 ~\ref{fig:glissandograph} you see that the glissando goes from 60 to 62 in a linear way according to the durations. The NoteFun code for the glissando is (glissando 60 62).
In the next section we will introduce four methods of creating new GTFs.
• Creation of GTFs out of other GTFs
• Creation of GTFs out of mathematical functions (lifting)
• Creation of GTFs out of numeric tables
• Creation of GTFs by writing your own Lisp code

### Complex GTFs: creating GTFs out of other GTFs

Now we will introduce tools with which you can make complex GTFs from simpler ones. One is called concat-gtf and like its name says, you can concatenate GTFs with it. With the ones we already saw we can e.g., make a concatenation of a vibrato and a glissando and apply it to one notes pitch. We will have to specify what portion of a duration will be dedicated to what GTF. This is done by means of absolute, relative and proportional who all indicate a point in time within the duration of a note in their own way. The argument list of concat-gtf is built up from alternating GTFs and indications of time. An example of the use is given here (also see Figure 8):
(draw (note :pitch (concat-gtf (glissando 60 62)
(proportional .5)
(vibrato :around 62 :period .2))))

You might wonder what (proportional .5) stands for. It means that what is before this expression may take half (hence .5) of the duration of the musical object, in this case a note, and what is after this expression may take the other half. This means that (glissando 60 62) in this case may take up half a second, since the default duration of a note is 1 second, and (vibrato :around 62 :period .2) may take the rest which is also half a second.
If we transform the note by means of stretch the durations of the GTFs will transform proportionally with the new duration. Instead of proportionally determined points in time you can also use relative points and absolute points. Relative means in this case: seen from the start of the note. Absolute means: seen from the start of the whole piece. Let us give a complex example to demonstrate how relative and absolute behave under transformation (also see Figure 9):

1 (draw (seq (note :duration 4 :pitch (concat-gtf
2                               (glissando 60 62)
3                               (proportional .25)
4                               (vibrato :around 62 :period .2)
5                               (relative 1.8)
6                               (glissando 62 64)
7                               (absolute 3.5)
8                               (glissando 64 60)))
9            (note :duration 5 :pitch (concat-gtf
10                              (glissando 60 62)
11                              (proportional .25)
12                              (vibrato :around 62 :period .2)
13                              (relative 1.8)
14                              (glissando 62 64)
15                              (absolute 7.5)
16                              (glissando 64 60))))
17      :y-min 58 :y-max 65)

You see this quite a complex beast. In this example there are two notes in a sequence. The first has a duration of 4 seconds and the second has a duration of 5 seconds. You can see that (proportional .25) (on line 3 and 11 of the above code fragment) indicate different points counted from the starts of the notes, as it stands for 4 x .25 (=1) in the first note and 5 x .25 (= 1.25) in the second note. The expression (relative 1.8) indicates the same point in time counted from the starts of the notes, namely 1.8 seconds after the start. This always holds, even when a note has been transformed. The expression (absolute 3.5) indicates the point in time that is 3.5 seconds after the start of the entire musical object, in this case a sequence holding the two notes. (absolute 7.5) of course indicates the point in time 7.5 seconds after the start of the entire musical object.

Now answer these questions for yourself before trying out the encoding of the problems in NoteFun:
• How will the musical object look when you add a (pause .5) in the sequence in front of the notes?
• What will happen when you change the duration of the last note from 5 to 4?

In both cases, first try to calculate the new points in time where one GTF ends and another begins. Let us call those points switch points from now on. Afterwards look at the corresponding pictures and see if your guess was correct.

Now for a malicious use of concat-gtf, have a look at what happens here (also see Figure 10):
(draw (note :pitch 			1
(concat-gtf 		2
(glissando 60 62) 		3
(absolute .5)		4
(glissando 62 60)		5
(absolute .25)		6
(glissando 60 62)		7
(absolute 1.5)		8
(glissando 60 62))))	9

The glissando on line 3 takes half the note, as you can expect. But what must be the behavior of the glissando on line 5, since the point in time indicates by line 6 is before the point in time indicated by line 4... ? concat-gtf prints a warning on the screen saying: "Times being re-arranged!'' concat-gtf checks if the successive switch points of its argument list are monotonously increasing. Also it check whether all the switch points remain between the bounds of the start and end time of the note. If not, it changes the switch points so they will obey these two properties.
In our last example concat-gtf changes the switch point on line 6 into (absolute .5) (first property) and the switch point on line 8 into (absolute 1) (second property). The result is that the glissando of line 5 will not appear since it has a time interval of exactly 0 seconds. The glissando of line 5 will appear on the interval [.5,1]. The glissando of line 9 will not appear since it has a time interval of 0 seconds. In other words, the last example is equivalent to the following code:
(draw (note :pitch
(concat-gtf
(glissando 60 62)
(absolute .5)
(glissando 60 62))))

Try this out and see for your self.
We conclude this subsection with a 3D graph of a complex GTF with duration from the interval [0,3] plotted in time. See Figure 11. The NoteFun code for this GTF is:
(concat-gtf
(glissando 60 62)
(proportional .25)
(vibrato :around 62 :period .2)
(relative 1.8)
(glissando 62 64)
(absolute 3.5)
(glissando 64 60))

## Intermezzo: guide to a wider application of GTFs

Note that until now we have only used GTFs in combination with the pitch of a note. To stimulate your creativity we must remark that GTFs can also be used in combination with a lot of other possible features of the note like amplitude and midi related parameters like brightness and pan. To simulate a fade-out you can use a GTF that goes from 1 to 0, where 1 indicates full volume and 0 indicates total silence (also see Figure 12):
(draw (note :amplitude (ramp 1 0)))

As you might guess ramp is similar to glissando. In fact, it is actually the same function. It only has a more general name and unlike glissando its name will inspire us to use it for all kinds of things, like here for amplitude.

To make use of the midi controller related features of note, you can add the synthesizer specific controller number and the range in which you want to control it yourself. The code for the controllers that we have put in for our own synthesizer (A Yamaha MU90R) looks like this:

(add-midi-controller :pan 10 -1 0 1)
(add-midi-controller :balance 8 0 .5 1)
(add-midi-controller :timbre 71 0 .8 1)
(add-midi-controller :brightness 74 0 .8 1)

You can make up any keyword your want for your specific controller. The syntax for add-midi-controller is
(add-midi-controllers
<keyword>
<midi control number>
<minimal-value>
<default-value>
<maximum-value>)

For a panning from left to right within a note we could write:
(note :pan (ramp -1 1))

You can remove a midi controller by executing (remove-midi-controller ). For example, if we want to remove the controller for brightness, we write: (remove-midi-controller :brightness). To get a list of all currently available midi controllers you write: (show-midi-controllers).

## Complex GTFs continued

Another tool for merging simple GTFs into a complex one is switch-gtf. It works slightly different than concat-gtf but has the same way of calling. Instead of concatenating GTFs it switches between GTFs at certain switch points and the GTFs are all spanned over the notes entire duration. Let us give an example based on two glissando's, one going up and one going down. Within the note we will switch between them using switch-gtf (also see Figure 13):
(draw (note :duration 3
:pitch (switch-gtf (glissando 60 65)
(proportional .25)
(glissando 65 60)
(proportional .5)
(glissando 60 65)
(proportional .75)
(glissando 65 60))))

switch-gtf corrects badly successive switch points in the same way as concat-gtf does.

Another way of building new GTFs from other ones is called time warping. Instead of going through a GTF from left to right in time, we can e.g., do it from right to left; from the beginning to the end. This operation can be done with a time warp that we called time-reverse. Its use is illustrated in the following example.

(setq some-gtf (concat-gtf
(glissando 60 62)
(proportional .25)
(vibrato :around 62 :period .2)
(proportional .5)
(glissando 62 64)
(proportional .75)
(glissando 64 65)))

(draw (note :pitch some-gtf) :y-max 66)
(draw (note :pitch (warp-gtf some-gtf (reverse-time)) :y-max 66)

First we make a reference to a GTF to be able to write more readable code. We use the name some-gtf as the reference name. Then we draw the result of using some-gtf as a notes pitch (see Figure 14). Lastly we draw the result of a transformed version of some-gtf by means of the time warp time-reverse (see Figure 15).
To hear the sound produced in example illustrated by Figure 14, click here:
To hear the sound produced in example illustrated by Figure 15, click here:

Another handy time warp is make-time-cyclic. make-time-cyclic has one argument indicating a point time within the duration of the note by means of absolute, relative and proportional. I will show the use of make-time-cyclic by means of an example (see Figure 16):
(draw (sim (note :duration 3
:pitch (warp-gtf (glissando 62 65)
(make-time-cyclic (proportional .5))))
(note :channel 1 :duration 3
:pitch (warp-gtf (glissando 60 62)
(make-time-cyclic (relative .5)))))
:y-max 66)

Note that we have to set an other channel for either one of the notes, to make the example sound correctly. To hear the sound produced in this last example, click here:

By now it might be clear how make-time-cyclic works. The point in time indicated by the time switch is the period length which indicates after what amount of time the GTF should start over again as if it were from the start.

There are more facilities that let us create GTFs out of other ones. One is called mix-gtf. By means of an example we will show its use (see Figure 17):

(draw (note :duration 3 :pitch
(mix-gtf
(glissando 60 70)
1
(sine-gtf :period 2 :amplitude 1) 1))
:y-max 75)

The syntax in which you can use mix-gtf is: (mix-gtf [<gtf> <factor>]*). The factors in this expression can be real numbers or GTFs (the notation we have used for the argument list must be read as a regular expression in which <gtf> and <factor> can be arbitrary GTFs and numbers. The same holds for successive examples in which this notation is used.). The result of this expression will be a gtf which is the weighted result of the succeeding gtfs and factors in the argument list. Our last example will be a gtf which is the addition of a glissando from 60 to 70 and a sine with an amplitude of 1 and a period of 2 seconds. Check Figure 18 and see if it looks like you expect. Because of the fact that we can either fill in a real number or a GTF as the factor, we are able to express things like: "let the impact of a GTF run from 2 to 0 along with the duration of the note". As follows:
(draw (note :duration 3 :pitch
(mix-gtf (ramp 60 70)
1
(sine-gtf :amplitude 1)
(ramp 2 0)))
:y-max 75)

The first GTF is kept constant (the succesive factor is 1) but the second GTF is multiplied by a ramp from 2 to 0. What we will expect is a ramp with a periodic deviation of which the amplitude will decrease as we go through the note in time. You can see the result in Figure 18.
Another similar combinator of GTFs is interpolate-gtf. As its name suggests, it interpolates between two GTFs. To make this clear let us interpolate between a glissando and a vibrato:
(draw (note :duration 3 :pitch (interpolate-gtf (glissando 60 70) (vibrato)))
:y-max 70)

The interpolation can be defined in terms of mix-gtf:

(interpolate-gtf gtf1 gtf2) = (mix-gtf gtf1 (ramp 1 0) gtf2 (ramp 0 1))

To give more elementary operations on GTFs we will introduce gtf+ and gtf*. After that we will introduce a more general function with which you can make your own operation on GTFs.

A GTF that is the sum of multiple other GTFs can be made with gtf+ with the following syntax: (gtf+ [<gtf | number>]*). For example, we can add a glissando and another glissando so that they will compensate each other, resulting in a constant pitch:
(note :pitch (gtf+ (glissando 30 40) (glissando 30 20)))

The result is just a note with a constant pitch of 60.

The next example demonstrates the use of gtf* within the use of gtf+.

(draw (note :pitch (gtf+ 60 (gtf* (ramp 0 1) (sine-gtf :period .2)))))

The result is a note with a with-time-increasing periodic deviation from pitch 60 (see Figure 20).

If you require more operators on GTFs you can define them yourself using time-fun-compose. For example, if we would like to make the operator for division on GTFs we write: (time-fun-compose #'/ [<gtf>]*)

More close to Lisp, a usable definition could be called gtf/ and would look like this:
(defun gtf/ (gtf1 gtf2 &rest args)
(apply #'time-fun-compose #'/ gtf1 gtf2 args))

We can use gtf/ from now on as demonstrated in the following example (see Figure 21):
(draw (note :duration 2
:pitch (gtf+ 60 (gtf/ (sine-gtf :amplitude 5) (ramp 2 10)))))

## GTFs created from home-made functions

In this section we will describe how one can build a GTF based on a mathematical function, like the sine function. This way of building gives one more degree of freedom of customizing your own GTFs as you will not be only limited to the tools we provided before. Instead you can come up with any unary function, provided that they give a sensible result, you wish. We will denote these functions with simple functions in what follows. You can specify how it should behave under transformation. Like we saw with the glissando, some functions should transform in a proportionally stretching way. Other functions, similar to the vibrato, should not be stretched. We call the creation of a GTF out of a simple function lifting. An equivalent of the glissando might be a linear function, like (lambda(x) x). Suppose we want to have a simple function that corresponds to a glissando from 60 to 70. Note that we do not know the duration of the note, to which the function will be applied, since it can be any positive real number. For now we will just choose a function that goes from 60 to 70 in an interval of 1 second:
(setq linfunc #'(lambda(x) (+ 60 (* 10 x))))
Now look at the following example (see Figure 22):
(draw (note :duration 2 :pitch (lift linfunc (proportional-lift 0 1)))
:y-max 72)

What does (lift linfunc (proportional-lift 0 1)) mean? Informally it means, select the function linfunc on the interval [0,1 and stretch it according to the duration of a note.
More general, the syntax for lift is:

(lift <lift-function>).

proportional-lift is a lift function that selects an interval out of a simple function. Try to modify the duration of the note in the last example and see that its pitch still runs from 60 to 70. This is how we want a glissando to behave under transformation.

Another lift function is relative-lift. It does not help us to stretch a selection out of a function but it lets us express something else. Let us try it out as a variation on our last example.
(draw (note :duration 2 :pitch (lift linfunc (relative-lift 0 1)))
:y-max 72)

The behavior as result of this GTF is not the one we intend for a glissando, as you can see in Figure~\ref{fig:lift-relative-1}. But maybe you see where we \emph{do} want to go with our example, because this is the kind of behavior we want to assign to a sine function to make it behave like a vibrato, for example. The arguments of relative-lift do not indicate an interval, but a starting point and an x-scale. This makes it easy to create a nice vibrato out of a sine. Like this (see Figure~\ref{fig:lift-relative-2}):
(draw (note :duration 2 :pitch (gtf+ 62 (lift #'sin (relative-lift 0 Pi)))
:y-max 72))

Now try to modify the duration of the note from the last example again and see what happens! Is it the behavior you desire from a vibrato?

The last lift function for simple functions we will discuss is absolute-lift. It is different from relative-lift in that it does not see the notes start as the starting point ( time = 0 ) for the GTF, but it uses the start of the whole musical object as the starting point of the GTF. Let us illustrate this with a vibrato that is lifted using absolute-lift and that is used over a group of notes.
(draw (seq (sim
(seq (note :duration 2 :pitch (gtf+ 60 lifted-sine))
(note :duration 1 :pitch (gtf+ 57 lifted-sine)))
(seq (note :pitch (gtf+ 63 lifted-sine))
(note :pitch (gtf+ 64 lifted-sine))))
(note :duration 2 :pitch (gtf+ 65 lifted-sine)))
:y-min 55
:y-max 70)

Because the starting point of the whole group of notes is taken as time = 0 you can see the sine wave continuously running through all notes, as if it does not know where one note ends and another begins.

## Lifting tables

Another method of creating GTFs is by means of tables. You can specify a table with key and value pairs and lift it as if it were a mathematical function. An example is given below.
(setq my-table '(
(0.0 60)
(.1 61.4)
(.2 62.3)
(.3 61.2)
(.7 65)
(1 60)))

With the help of table-fun we can make a simple function out of a table:
(setq tablefunction (table-fun my-table))

Since tablefunction now is a simple function, we can use it in the same way as any other simple function. Hence we can lift it with the same constructions as demonstrated in the previous subsection. The function is made by a lineair interpolation between the values of the table, as demonstrated in the following code (see Figure 25):
(draw (seq (note :duration 2
:pitch (lift tablefunction (proportional-lift 0 .5)))
(note :duration 2
:pitch (lift tablefunction (relative-lift 0 .5))))
:y-max 66)

## Creation of GTFs by writing your own Lisp code

In this last subsection on the creation of GTFs we will address you to write your own Lisp code as a means of creating your own GTFs. In order to do that we have to go into details of how a GTF is built up. We will do this, like you are used to in this tutorial, by means of example. First we will show how an existing GTF is built up. After that we will write a new one from scratch.

Do you remember the glissando GTF from all the previous examples? As we already said it is the same function as the ramp function. Here is its encoding in Lisp:
1(defun ramp (from to)
2 (gtf (start duration)
3    (tf(time)
4      (let ((progress (/ (- time start) duration)))
5        (+ from (* progress (- to from)))))))

In general a GTF is built up using the construction
(gtf (start duration)
(...
(tf (time) (...))...)

ramp returns a function of the type R -> R+ -> (R+ -> R+). The constructions gtf and tf work like normal functional abstraction. They are adapted versions of Lisps lambda, enhanced for our purpose here. gtf creates a function of the type R+ -> R+ -> (R+ -> R+) and tf creates a funtion of type R+ -> R+. A GTF makes use of three important variables time, start and duration. The variable time indicates the time counted from the start of an entire musical object; start indicates the time at which the note in which the GTF will be used will begin; duration represents the time interval on which a note will be played. The dots on the second line of the general code are intended to consist of calculations with start and duration. Calculations that involve also time can only occur inside the tf construction. This two layer way of building a GTF is chosen because of efficiency reasons which we will not have to discuss on this website (look at my internship report for more on this). Because all of the calculations that we need in ramp involve time, they have to occur inside the tf.

Now let us look how ramp works. On line 4 of its code an expression with time, start and duration is bound to progress. If we look closer to the expression we see that it indicates the fraction of the duration that has already passed: "current time minus start time" divided by "total duration of the note". At the very start of the note, progress will have value 0. At the very end of the note "time minus start" will equal duration and therefore progress will have the value of 1. Now, with (ramp ) we want to have a GTF that is a linear function from to on the interval [start,start+duration]. Note that the expression
(+ from (* progress (- to from))))))) returns the right value on each point of time on in the interval. Now that we have seen the implementation of ramp it may inspire us to make a different GTF. Wouldn't it be funny to make a GTF that gives random values from a certain range? In Lisp (random ) returns a random floating point number from the range [0,n[ (n self is excluded) when n is a floating point number. Hence (random 1.0) returns a floating point number between 0 and 1. The Lisp expression (+ min (* (- max min) (random 1.0))) then returns a random value between min and max. This is all we have to return, so the code for random-gtf will be quite simple:
(defun random-gtf (min max)
(gtf (start duration)
(tf (time)
(+ min (* (- max min) (random 1.0))))))

Let us see how random-gtf behaves as a pitch GTF:
(play-and-draw (note :pitch (random-gtf 61 62)))

Look at Figure 26 for the result!
Of course we can also use random-gtf to make small random deviations from other GTFs like in the following example (see Figure 27):
(draw (note :duration 2
:pitch (gtf+ (vibrato :around 61)
(random-gtf 0 .5))))

To conclude this tutorial, we will give you a description of how to build a GTF that behaves like an instrument. This GTF will be build up in analogy of a concept in the synthesizer world, namely ADSR. ADSR stands for attack, decay, sustain and release. The idea is that when a note starts, the volume of the note will go from 0 to a certain attack level. Immediately after reaching the attack level the volume will go down in a certain amount of time, till it reaches the sustain level. This level will be maintained for a certain length of time. Just before the end of the note (think of a key being released) the level will go from sustain level to 0 again. This is illustrated in Figure 28. We will discuss a simplified version of this idea for the sake of didactics and the length of this tutorial. From the above description of ADSR it might be evident that we need four basic GTFs which we can concatenate later by means of concat-gtf. Conceptually this may look something like this:
1(concat-gtf
2 attack function
3 time switch
4 decay function
5 time switch
6 sustain function
7 time switch
8 release function)

We need a GTF for going from 0 to an attack level in a certain amount of time. This amount of time does not in- or decrease with the length of a note for most instruments (loosely speaking); it is a constant portion of time. Therefore, the attack function, let us call it attack-fun, must precede a time switch that is made with relative. The same goes for the decay function, which we will call decay-fun and its succeeding time switch. The sustain, named sustain-fun, does depend on the duration of the note. The portion of time needed for the release, let us call it release-fun, from sustain level to 0 is again a constant portion. With this information we can make the concept a bit more concrete:
1 (concat-gtf
2 attack-fun
3 (relative ...)
4 decay-fun
5 (relative ...)
6 sustain-fun
7 (relative end time minus' ...)
8 release-fun)

Let us specify the different functions a little more. We propose the following as an attack function:
(defun attack-fun (begin end)
(gtf+ begin
(gtf* (- end begin) (lift (sine 4) (proportional-lift 0 1)))))

The function attack-fun expects a begin and end value. In the following example you get an impression of how it works (see Figure 29):
(draw (sim (note :pitch (attack-fun 60 65))
(note :duration 2 :pitch (attack-fun 62 70)))
:y-max 72)

For the decay function we propose the following:
(defun decay-fun (begin end)
(time-fun-compose #'- begin
(gtf* (- begin end) (lift (sine 4) (proportional-lift 0 1)))))

We illustrate this function with the following example (see Figure 30):
(draw (sim (note :pitch (decay-fun 65 62))
(note :duration 2 :pitch (attack-fun 70 64)))
:y-max 72)

The sustain function can be really simple. It just has to remain constant at a certain level:
(defun sustain-fun (volume)
(gtf (start duration)
(tf (time)
volume)))

As a release function we can take the same function as the decay function:
(defun release-fun (begin end)
(decay-fun begin end))

Finally we are ready to try out our ADSR. We build a function around it in which you can specify the different levels and time intervals.
1 (defun adsr (attack-time decay-time release-time attack-level sustain-level)
2  (let ((att-time (relative attack-time))
3         (dec-time (relative (+ attack-time decay-time)))
4         (rel-time (fun-funcall #'- #'end-time release-time)))
5     (concat-gtf (attack-fun 0 attack-level)
6                 att-time
7                 (decay-fun attack-level sustain-level)
8                 dec-time
9                 (sustain-fun sustain-level)
10                rel-time
11                (release-fun sustain-level 0)
12                )))

The expression (fun-funcall #'- #'end-time release-time) evaluates to the end time of the note minus the time interval indicated by release-time. Because end-time and release-tim are not normal numbers (actually they are functions) we have to use fun-funcall in this case.

Now let us try out adsr. We define two different ADSRs named inst1 and inst2 as follows and use both in a group of notes:
(setq inst1 (adsr .1 .4 .2 .9 .7))
(setq inst2 (adsr .2 .2 .4 .4 .2))

(draw
(sim
(for-all-notes :amplitude inst1
(seq  (note :pitch 62 :duration 1)
(pause 1)
(note :pitch 63 :duration 2)))
(for-all-notes :channel 1 :amplitude inst2
(seq (note :pitch 63 :duration 2)
(note :pitch 62 :duration 1.5)))))
`

To hear the example above, listen to this sample:

You see that the only the length of the sustain phases depend on the lengths of the notes. The other phases are of constant length, no matter what the lengths of the notes are.

In the following graphs we show both ADSRs plotted in time against durations of lenghts from the interval [0,3] in seconds.


text:
Particle and Astro-Particle Physics Seminars

# Beyond collisionless dark matter

## by Sean Tulin (University of Michigan)

Friday, 5 April 2013 from to (Europe/Zurich)
at CERN ( 4-3-006 - TH Conference Room )
 Description Although collisionless dark matter (CDM) has been highly successful in explaining the large scale structure of the Universe, its success remains unclear on smaller scales. Observations of dwarf galaxies and Milky Way satellites show notable and long-standing disagreements compared to predictions from numerical CDM simulations. This discrepancy can be solved if dark matter is not collisionless, but possesses a large self-interaction cross section. In this talk, I discuss the particle physics dynamics of self-interacting dark matter. Even within a minimal model, self-interactions can exhibit a rich structure, with different behaviors on small vs large scales. I show how considerations from astrophysical observations of structure, dark matter relic density, and indirect detection can map out the underlying particle physics parameter space of self-interacting dark matter.