I am working on the file "ModelSelection.ipynb".
The first task is:
Remarks: As can be expected, with low velocity thresholds, we see an overrepresentation of the reward locations, and only a relatively small number of states that are dedicated to encoding the position along the track.
Recall that the track was shortened halfway through the recording session. Here, the reward locations for the longer track (first half of the experiment) and shorter track (second half of the experiment) are shown by the ends of the dashed lines.
We notice that at some point, the movement velocity (for fixed state evolution) appears to be constant, and that at e.g. 8 units/sec we see a clear bifurcation in the place fields, so that states encode both positions before and after the track was shortened.
Place fields for varying number of states
Next, we take a look at how the place fields are affected by changing the number of states in the model.
Can you write Python code for it?

from placefieldviz import hmmplacefieldposviz

num_states = 35
ds = 0.0625 # bin spikes into 62.5 ms bins (theta-cycle inspired)
vth = 8 # units/sec velocity threshold for place fields

#state_pos, peakorder = hmmplacefieldposviz(num_states=num_states, ds=ds, posdf=posdf, spikes=spikes, speed=speed, vth=vth)

fig, axes = plt.subplots(4, 3, figsize=(17, 11))
axes = [item for sublist in axes for item in sublist]

for ii, ax in enumerate(axes):
    num_states = 5 + ii*5
    state_pos, peakorder, stateorder = hmmplacefieldposviz(num_states=num_states, ds=ds, posdf=posdf, spikes=spikes, speed=speed, vth=vth, normalize=True)
    ax.matshow(state_pos[peakorder,:], interpolation='none', cmap='OrRd')
    #ax.set_xlabel('position bin')
    ax.set_ylabel('state')
    ax.set_xticklabels([])
    ax.set_yticklabels([])
    ax.set_title('learned place fields; RUN > ' + str(vth) + '; m = ' + str(num_states), y=1.02)
    ax.axis('tight')

saveFigure('posterfigs/numstates.pdf')


I am working on the file "ModelSelection.ipynb".
The first task is:
Remarks: We clearly see the bimodal place fields when we use all of the data, and we see the unimodal place fields emerge as we focus on either the first, or the second half of the experiment.
Notice that the reward locations are more concentrated, but that the velocity (with fixed state progression) is roughly constant.
However, if we increase the number of states:
Can you write Python code for it?

from placefieldviz import hmmplacefieldposviz

num_states = 45
ds = 0.0625 # bin spikes into 62.5 ms bins (theta-cycle inspired)
vth = 8 # units/sec velocity threshold for place fields

state_pos_b, peakorder_b, stateorder_b = hmmplacefieldposviz(num_states=num_states, ds=ds, posdf=posdf, spikes=spikes, speed=speed, vth=vth, normalize=True, experiment='both')
state_pos_1, peakorder_1, stateorder_1 = hmmplacefieldposviz(num_states=num_states, ds=ds, posdf=posdf, spikes=spikes, speed=speed, vth=vth, normalize=True, experiment='first')
state_pos_2, peakorder_2, stateorder_2 = hmmplacefieldposviz(num_states=num_states, ds=ds, posdf=posdf, spikes=spikes, speed=speed, vth=vth, normalize=True, experiment='second')

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(17, 3))

ax1.matshow(state_pos_b[peakorder_b,:], interpolation='none', cmap='OrRd')
ax1.set_ylabel('state')
ax1.set_xticklabels([])
ax1.set_yticklabels([])
ax1.set_title('learned place fields BOTH; RUN > ' + str(vth) + '; m = ' + str(num_states) + '; ds = ' + str(ds), y=1.02)
ax1.plot([13, 35], [0, num_states], color='k', linestyle='dashed', linewidth=2)
ax1.plot([7, 41], [0, num_states], color='k', linestyle='dashed', linewidth=2)
ax1.axis('tight')

ax2.matshow(state_pos_1[peakorder_1,:], interpolation='none', cmap='OrRd')
ax2.set_ylabel('state')
ax2.set_xticklabels([])
ax2.set_yticklabels([])
ax2.set_title('learned place fields FIRST; RUN > ' + str(vth) + '; m = ' + str(num_states) + '; ds = ' + str(ds), y=1.02)
ax2.plot([13, 35], [0, num_states], color='gray', linestyle='dashed', linewidth=1)
ax2.plot([7, 41], [0, num_states], color='k', linestyle='dashed', linewidth=2)
ax2.axis('tight')

ax3.matshow(state_pos_2[peakorder_2,:], interpolation='none', cmap='OrRd')
ax3.set_ylabel('state')
ax3.set_xticklabels([])
ax3.set_yticklabels([])
ax3.set_title('learned place fields SECOND; RUN > ' + str(vth) + '; m = ' + str(num_states) + '; ds = ' + str(ds), y=1.02)
ax3.plot([13, 35], [0, num_states], color='k', linestyle='dashed', linewidth=2)
ax3.plot([7, 41],...


I am working on the file "ModelSelection.ipynb".
The first task is:
Remarks: We notice that we clearly see the bimodal place fields when the timescales are sufficiently small, with a particularly clear example at 62.5 ms, for example. Larger timescales tend to focus on the longer track piece, with a single trajectory being skewed away towards the shorter track piece.
Next we consider timescales in increments of 62.5 ms.
Can you write Python code for it?

from placefieldviz import hmmplacefieldposviz

num_states = 35
ds = 0.0625 # bin spikes into 62.5 ms bins (theta-cycle inspired)
vth = 8 # units/sec velocity threshold for place fields

#state_pos, peakorder = hmmplacefieldposviz(num_states=num_states, ds=ds, posdf=posdf, spikes=spikes, speed=speed, vth=vth)

fig, axes = plt.subplots(4, 3, figsize=(17, 11))
axes = [item for sublist in axes for item in sublist]

for ii, ax in enumerate(axes):
    ds = (ii+1)*0.0625
    state_pos, peakorder, stateorder = hmmplacefieldposviz(num_states=num_states, ds=ds, posdf=posdf, spikes=spikes, speed=speed, vth=vth, normalize=True)
    ax.matshow(state_pos[peakorder,:], interpolation='none', cmap='OrRd')
    #ax.set_xlabel('position bin')
    ax.set_ylabel('state')
    ax.set_xticklabels([])
    ax.set_yticklabels([])
    ax.set_title('learned place fields; RUN > ' + str(vth) + '; m = ' + str(num_states) + '; ds = ' + str(ds), y=1.02)
    ax.plot([13, 35], [0, num_states], color='k', linestyle='dashed', linewidth=1)
    ax.plot([7, 41], [0, num_states], color='k', linestyle='dashed', linewidth=1)
    ax.axis('tight')


I am working on the file "ModelSelection/ComparingGaussianMeans.ipynb".
The first task is:
8.2 Order-restricted one-sample comparison
$$ \delta \sim \text{Cauchy} (0, 1){\mathcal I(-∞,0)}$$
$$ \sigma \sim \text{Cauchy} (0, 1){\mathcal I(0,∞)}$$
$$ \mu = \delta\sigma $$
$$ x_{i} \sim \text{Gaussian}(\mu,1/\sigma^2)$$
Can you write Python code for it?


I am working on the file "ModelSelection/ComparingGaussianMeans.ipynb".
The first task is:
8.3 Two-sample comparison
$$ \delta \sim \text{Cauchy} (0, 1)$$
$$ \mu \sim \text{Cauchy} (0, 1)$$
$$ \sigma \sim \text{Cauchy} (0, 1){\mathcal I(0,∞)}$$
$$ \alpha = \delta\sigma $$
$$ x{i} \sim \text{Gaussian}(\mu+\frac{\alpha}{2},1/\sigma^2)$$
$$ y_{i} \sim \text{Gaussian}(\mu-\frac{\alpha}{2},1/\sigma^2)$$
Can you write Python code for it?

# Read data
x =np.array([70,80,79,83,77,75,84,78,75,75,78,82,74,81,72,70,75,72,76,77])
y =np.array([56,80,63,62,67,71,68,76,79,67,76,74,67,70,62,65,72,72,69,71])

n1 = len(x)
n2 = len(y)

# Rescale
y = y - np.mean(x)
y = y / np.std(x)
x = (x - np.mean(x)) / np.std(x)

with pm.Model() as model3:
    delta = pm.Cauchy('delta', alpha=0, beta=1)
    mu = pm.Cauchy('mu', alpha=0, beta=1)
    sigma = pm.HalfCauchy('sigma', beta=1)
    alpha = delta*sigma
    xi = pm.Normal('xi', mu=mu+alpha/2, sd=sigma, observed=x)
    yi = pm.Normal('yi', mu=mu-alpha/2, sd=sigma, observed=y)
    trace3=pm.sample(3e3, njobs=2)

burnin=0
pm.traceplot(trace3[burnin:], varnames=['delta']);
plt.show()

x = np.linspace(-3, 3, 100)
display_delta(trace3, x)


I am working on the file "ModelSelection/ComparingGaussianMeans.ipynb".
The first task is:
Chapter 8 - Comparing Gaussian means
8.1 One-sample comparison
$$ \delta \sim \text{Cauchy} (0, 1)$$
$$ \sigma \sim \text{Cauchy} (0, 1){\mathcal I(0,∞)}$$
$$ \mu = \delta\sigma $$
$$ x{i} \sim \text{Gaussian}(\mu,1/\sigma^2)$$
Can you write Python code for it?

# Read data Dr. Smith
Winter = np.array([-0.05,0.41,0.17,-0.13,0.00,-0.05,0.00,0.17,0.29,0.04,0.21,0.08,0.37,
            0.17,0.08,-0.04,-0.04,0.04,-0.13,-0.12,0.04,0.21,0.17,0.17,0.17,
            0.33,0.04,0.04,0.04,0.00,0.21,0.13,0.25,-0.05,0.29,0.42,-0.05,0.12,
            0.04,0.25,0.12])

Summer = np.array([0.00,0.38,-0.12,0.12,0.25,0.12,0.13,0.37,0.00,0.50,0.00,0.00,-0.13,
            -0.37,-0.25,-0.12,0.50,0.25,0.13,0.25,0.25,0.38,0.25,0.12,0.00,0.00,
            0.00,0.00,0.25,0.13,-0.25,-0.38,-0.13,-0.25,0.00,0.00,-0.12,0.25,
            0.00,0.50,0.00])
x = Winter - Summer  # allowed because it is a within-subjects design
x = x / np.std(x)

with pm.Model() as model1:
    delta = pm.Cauchy('delta', alpha=0, beta=1)
    sigma = pm.HalfCauchy('sigma', beta=1)
    miu = delta*sigma
    xi = pm.Normal('xi', mu=miu, sd=sigma, observed=x)
    trace1=pm.sample(3e3, njobs=2)

burnin=0
pm.traceplot(trace1[burnin:], varnames=['delta']);
plt.show()

def display_delta(trace, x):
    # BFs based on density estimation (using kernel smoothing instead of spline)
    from scipy.stats.kde import gaussian_kde
    from scipy.stats import cauchy

    pm.summary(trace, varnames=['delta'])
    tmp = pm.df_summary(trace, varnames=['delta'])
    # 95% confidence interval:
    x0 = tmp.values[0, 3]
    x1 = tmp.values[0, 4]

    t_delt = trace['delta'][:]
    my_pdf = gaussian_kde(t_delt)
    plt.plot(x, my_pdf(x), '--', lw=2.5, alpha=0.6, label='Posterior') # distribution function
    plt.plot(x, cauchy.pdf(x), 'r-', lw=2.5, alpha=0.6, label='Prior')
    posterior = my_pdf(0)             # this gives the pdf at point delta = 0
    prior     = cauchy.pdf(0)         # height of order-restricted prior at delta = 0
    BF01      = posterior/prior
    print ('the Bayes Factor is %.5f' %(BF01))
    plt.plot([0, 0], [posterior, prior], 'k-',
             [0, 0], [posterior, prior], 'ko', lw=1.5, alpha=1)
    plt.xlabel('Delta')
    plt.ylabel('Density')
    plt.legend(loc='upper left')
    plt.show()

x = np.linspace(-3,...


I am working on the file "Model_Select.ipynb".
The first task is:
Everything below is exploratory analysis for me.
Can you write Python code for it?

for jm in range(0, 5):

    print(outcomes[jm][0])

    print(outcomes[jm][1])
    print(outcomes[jm][4])

best = AdaBoostRegressor(learning_rate=1, loss='square', n_estimators=60)
bestfit= best.fit(XH_train, yH_train)
bestscore = best.score(XH_test, yH_test)
print(outcomes[0][0])
print(bestscore)

best = RandomForestRegressor(max_depth=10)
bestfit= best.fit(XH_train, yH_train)
bestscore = best.score(XH_test, yH_test)
print(outcomes[1][0])
print(bestscore)

best = SVR(max_depth=10)
bestfit= best.fit(XH_train, yH_train)
bestscore = best.score(XH_test, yH_test)
print(outcomes[2][0])
print(bestscore)

best = GradientBoostingRegressor(max_depth=10)
bestfit= best.fit(XH_train, yH_train)
bestscore = best.score(XH_test, yH_test)
print(outcomes[3][0])
print(bestscore)

Xtrain = dat_xtrain.drop(['y'], axis=1)
y16 = dat_ytrain['y']
X15 = dat15.drop(['y'], axis=1)
y15 = dat15['y']

fitted    = outcomes[-2][3].fit(X15, y15)
predicted = fitted.predict(X16)

pred = pd.DataFrame(predicted, columns=['predicted'])
dat16 = dat16.reset_index()
pred['y'] = dat16['y']

def flagger_ranges(pred):
    pred['flag15'] = 0
    pred['flag15'][pred['predicted'].between(pred['y']*0.85, pred['y']*1.15)
                  ] = 1
    pred['flag05'] = 0
    pred['flag05'][pred['predicted'].between(pred['y']*0.85, pred['y']*1.15)
                  ] = 1
    pred['flag10'] = 0
    pred['flag10'][pred['predicted'].between(pred['y']*0.85, pred['y']*1.15)
                  ] = 1
    pred['flag_others']= 0
    pred['flag_others'][pred['flag05'] == 0] = 1
    return pred
pred = flagger_ranges(pred)
pred


I am working on the file "Model_Select.ipynb".
The first task is:
Grid Search:
Here we implement an iterator that executes GridSearchCV and reports the best explained variance. The best_params attribute is then extracted, and used those on the whole training set, then predict on the holdout data.
Testing indicates that for some models, the fit on our full dataset modestly outperforms the CV regularly.
Can you write Python code for it?

outcomes = []

for name, rgsr in zip(names, regressors):

    for item in param_grids:
        if item[0]==name:
            print(name + ':')
            params= item[1]

    cv = sklearn.model_selection.GridSearchCV(rgsr, param_grid=params,
                                              verbose=True, n_jobs=12,
                                              cv=3, pre_dispatch="2*n_jobs")

    if name not in to_scale:
        #X_train, y_train, X_test, y_test = sklearn.model_selection.train_test_split(X, y)
        fitted = cv.fit(XH_train, yH_train)
        score = cv.score(XH_val, yH_val)
        print(score)

        best = rgsr.set_params(**cv.best_params_)
        bestfit= best.fit(XH_train, yH_train)
        bestscore = best.score(XH_test, yH_test)
    if name in to_scale:
    #TODO: fix
        #X_train, y_train, X_test, y_test = sklearn.model_selection.train_test_split(sX, sy)
        fitted = cv.fit(sXH_train, syH_train)
        score = cv.score(sXH_val, syH_val)
        print(score)

        best = rgsr.set_params(**cv.best_params_)
        bestfit= best.fit(sXH_train, syH_train)
        bestscore = best.score(sXH_test, syH_test)

    print(name + " R2 with best model, score:")
    print(bestscore)

    outcomes.append((name, score, cv.cv_results_, cv.best_estimator_,
                     cv.best_params_, bestscore, [yH_test, ]))

for nm in range(0, len(outcomes)):
    print()
    print(outcomes[nm][0])
    print(outcomes[nm][1])
    print()
    print('Best on real:')
    print(outcomes[nm][-1])

#Adapted from https://pythonspot.com/en/matplotlib-bar-chart/

objects     = [j[0] for j in outcomes]
y_pos       = np.arange(len(objects))

performance = [j[-1] for j in outcomes]
for jm in range(len(performance)):
    if performance[jm] < 0:
        performance[jm] = 0
performance

plt.barh(y_pos, performance, align='center', alpha=0.5)
plt.yticks(y_pos, objects)
plt.xlabel('R2 Score')
ti = "Scoring across models for "+shapef+", lagging by "+str(shiftmonths)+ "...


I am working on the file "Model_Select.ipynb".
The first task is:
Here we start building our grid search inputs, beginning with the splits.
Can you write Python code for it?

#Flexible adaptation of Dr. Braman's interactive gridsearch script
#implementation.
#TODO Clean up and streamline
import sklearn
from sklearn.neural_network import *
from sklearn.neighbors import *
from sklearn.svm import *
from sklearn.gaussian_process import *
from sklearn.gaussian_process.kernels import *
from sklearn.tree import *
from sklearn.ensemble import *
from sklearn.naive_bayes import *
from sklearn.discriminant_analysis import *
from sklearn.linear_model import *
from sklearn.model_selection import *
from sklearn.preprocessing import *
import random

#Frame up some separate DataFrames for scalar and stuff
scl_data = data = df

data     = data.reset_index(drop=True)
X = data.drop(['y'], axis=1)
y = data['y']

XH_train = data[data['month'] <= holdout_date-1]
yH_train = XH_train['y']
XH_train = XH_train.drop(['y'], axis=1)

XH_val = scl_data[scl_data['month'] >= holdout_date-1]
XH_val = XH_val[XH_val['month'] <= holdout_date]

yH_val = XH_val['y']
XH_val = XH_val.drop(['y'], axis=1)

XH_test  = data[data['month'] >= holdout_date]
yH_test  = XH_test['y']
XH_test  = XH_test.drop(['y'], axis=1)

ytr = sklearn.preprocessing.MinMaxScaler([0, 1]
            ).fit(y)
y = ytr.fit_transform(y)
y = pd.DataFrame(y, columns=['y'])

scl_data = scl_data.reset_index(drop=True)

y.y

print(scl_data.month.max())
print(scl_data.shape)
scl_data = scl_data.dropna()
print(scl_data.shape)
sXH_train = scl_data[scl_data['month'] <= holdout_date-1]
syH_train = sXH_train['y']
sXH_train = sXH_train.drop(['y'], axis=1)

sXH_val = scl_data[scl_data['month'] >= holdout_date-1]
sXH_val = sXH_val[sXH_val['month'] <= holdout_date]

syH_val = sXH_val['y']
sXH_val = sXH_val.drop(['y'], axis=1)

sXH_test  = scl_data[scl_data['month'] >= holdout_date]
syH_test  = sXH_test['y']
sXH_test  = sXH_test.drop(['y'], axis=1)

#Build scalers for the scl_data, other --------------------
scale_data_splits = [scl_data, sXH_train,sXH_test, syH_train, syH_test]
for scl_data in scale_data_splits:
    scaler =...


I am working on the file "Model_Select.ipynb".
The first task is:
Let's make sure our data came out of the scalers intact:
Can you write Python code for it?

y;

print(sXH_train.shape)
print(syH_train.shape)
print(sXH_test.shape)
print(syH_test.shape)

scl_data.columns

sX = scl_data.drop(['y'], axis=1)
sy = scl_data['y']

assert np.all(np.isfinite(X))
assert np.all(np.isfinite(y))
assert not np.any(np.isnan(X))
assert not np.any(np.isnan(y))

assert np.all(np.isfinite(sX))
assert np.all(np.isfinite(sy))
assert not np.any(np.isnan(sX))
assert not np.any(np.isnan(sy))

scl_data.columns

scl_data.describe()


I am working on the file "Model_Select.ipynb".
The first task is:
Now we examine the columns and lag the data.
Can you write Python code for it?

df.columns

print(df.shape)
shiftnum= (((len(df.NAME.unique()))*(shiftmonths)))

#Also generate some lagged y data in the opposite direction.
df['y']= df['countBBL'].shift(-shiftnum)
df['countBBL_prev_month'] = df['countBBL'].shift((len(df.NAME.unique())))
df['countBBL_prev_cycle'] = df['countBBL'].shift((shiftnum))
df = df[shiftnum:-(shiftnum+(len(df.NAME.unique())))]
df = df.dropna()
df.shape


I am working on the file "Model_Select.ipynb".
The first task is:
The next cell cleans out vestigial columns and drops/fills/expands to dummies for our NA and categorical values.
Can you write Python code for it?

df = pd.get_dummies(df, columns=['NAME'])
df = df.drop(['Unnamed: 0'], axis= 1)
print(df.shape)
df = df.astype('float')

df = df.dropna()
print(df.shape)


I am working on the file "Model_Select.ipynb".
The first task is:
This cell contains our a crude RNG, a list of regressors which benefit from scaled data, and hardcoded data used to generate our param_grid, et cetera.
Can you write Python code for it?

#Make a short list of random states to insert into randomstate params.
scrambler = []
for scram in range(0, 10):
    scrambler.append(random.randint(0, 10000))
print(scrambler)

to_scale = ['SVR']

names       = ['AdaBoostRegressor',
             'RandomForestRegressor',
             'SVR',
             #'KNeighborsRegressor',
             #'BaggingRegressor',
             'GradientBoostingRegressor',
             #'LinearRegression',
             #'MLPRegressor',
             #'SGDRegressor',
             'LassoLars'

]

regressors = [AdaBoostRegressor(),
              RandomForestRegressor(),
              SVR(),
              #KNeighborsRegressor(),
              #BaggingRegressor(),
              GradientBoostingRegressor(),
              #LinearRegression(),
              #MLPRegressor(),
              #SGDRegressor(),
              LassoLars()

]

param_grids =[
    ['AdaBoostRegressor', dict(
        n_estimators=[80, 60, 30],
        learning_rate=[1, .5, .01],
        loss=['linear', 'square', 'exponential'],
        #random_state=scrambler[3:5]

    )],

    ['RandomForestRegressor', dict(
        max_depth=[5, 10, 15],
        criterion=['mse', 'mae'],
        #random_state=scrambler[:2]
    )],
    ['SVR', dict( #Most params for SVR are turned off right now, too expensive
        C=[1, .9],
        epsilon=[.1, .05],
        #kernel=['poly']
    )],
    ['GradientBoostingRegressor', dict(
        max_depth=[3, 6, 9, 12],
        min_samples_split=[2, 4, 8],
        presort=[False]
    )],
    ['LassoLars', dict(
        alpha=[0.1, 1, .5, .75],
        #random_state=[random.randint(0, 10000)]
    )],
    ]


I am working on the file "Model_Select.ipynb".
The first task is:
To start...
We import the data output of our data pipeline. We reset the index, drop index columns, and lag the data.
We explicitly print shape several times, making sure that we capture the magnitude of data lost from dropping NA values.
Can you write Python code for it?

#Shift and shape vars
shiftmonths = 6
shapef = 'anc'
#Assign the split for holdout data.
holdout_date = 2015.5
#Get data
filestring = './data/'+shapef+'_out.csv'
df = pd.read_csv(filestring)
df = df.sort_values(['month', 'NAME'])# , 'ANC'])
df = df.reset_index(drop=True)
len(df.NAME.unique())


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Again, we find that the p-value does not suggest rejecting the powerlaw model.
Of course, a slightly modified version is implemented in stingray as a subclass of the PSDParEst class:
Can you write Python code for it?

from stingray.modeling import PSDParEst

parest = PSDParEst(ps, fitmethod="BFGS")

pval = parest.calibrate_lrt(lpost, starting_pars, lpost_bplc, bplc_start_pars,
                   sample=sample.samples, nsim=100, max_post=True, seed=200)

print(pval)


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
And do the posterior predictive p-value. Since we've already sampled from the simple model, we can pass that sample to the calibrate_lrt function, in order to cut down on computation time (if the keyword sample is not given, it will automatically run MCMC:
Can you write Python code for it?

pval = calibrate_lrt(ps, lpost, starting_pars,
                     lpost_bplc, bplc_start_pars,
                     sample=sample.samples,
                     max_post=True, nsim=100)

print("The posterior predictive p-value is: p = " + str(pval))


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
As a last step, we need to add noise by picking from a chi-square distribution with 2 degrees of freedom:
Can you write Python code for it?

powers = psd_shape*np.random.chisquare(2, size=psd_shape.shape[0])/2.0


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Bayesian Parameter Estimation
For Bayesian parameter estimation, we require a prior along with the likelihood defined above. Together, they form the posterior, the probability of the parameters given the data, which is what we generally want to compute in science.
Since there are no universally accepted priors for a model (they depend on the problem at hand and your physical knowledge about the system), they cannot be easily hard-coded in stingray. Consequently, setting priors is slightly more complex.
Analogously to the LogLikelihood above, we can also define a Posterior object. Each posterior object has three methods: logprior, loglikelihood and logposterior.
We have pre-defined some Posterior objects in posterior.py for common problems, including power spectral analysis. We start by making a PSDPosterior object:
Can you write Python code for it?

from stingray.modeling import PSDPosterior

lpost = PSDPosterior(ps.freq, ps.power, plc, m=ps.m)


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Bayesian-ish QPO Searches
When searching for quasi-periodic oscillations (QPOs) in light curves that are not constant (for example because they are bursts or have other types of variability), one must take care that the variable background is accurately modelled (most standard tools assume that the light curve is constant).
In Vaughan et al, 2010, a method was introduced to search for QPOs in the presence of red noise (stochastic variability), and in Huppenkothen et al, 2013 it was extended to magnetar bursts, and in Inglis et al, 2015 and Inglis et al, 2016 a similar approach was used to find QPOs in solar flares.
Based on a model for the broadband spectral noise, the algorithm finds the highest outlier in a test statistic based on the data-model residuals (under the assumption that if the broadband model is correct, the test statistic $T_R = \max_j(2 D_j/m_j)$ for $j$ power spectral bins with powers $D_j$ and model powers $m_j$ will be distributed following a $\chi^2$ distribution with two degrees of freedom). The observed test statistic $T_R$ is then compared to a theoretical distribution based on simulated power spectra without an outlier in order to compute a posterior predictive p-value as above for the likelihood ratio.
Since the concept is very similar to that above, we do not show the full code here. Instead, the p-value can be calculated using the method calibrate_highest_outlier, which belongs to the PSDParEst class:
Can you write Python code for it?

# compute highest outlier in the data, and the frequency and index
# where that power occurs
max_power, max_freq, max_ind = parest._compute_highest_outlier(lpost, res)

max_power

pval = parest.calibrate_highest_outlier(lpost, starting_pars, sample=sample,
                                  max_post=True,
                                  nsim=100, niter=200, nwalkers=500,
                                  burnin=200, namestr="test")

pval


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Calibrating Likelihood Ratio Tests
In order to use likelihood ratio tests for model comparison, one must compute the p-value of obtaining a likelihood ratio at least as high as that observed given that the null hypothesis (the simpler model) is true. The distribution of likelihood ratios under that assumption will only follow an analytical distribution if
* the models are nested, i.e. the simpler model is a special case of the more complex model and
* the parameter values that transform the complex model into the simple one do not lie on the boundary of parameter space.
Imagine e.g. a simple model without a QPO, and a complex model with a QPO, where in order to make the simpler model out of the more complex one you would set the QPO amplitude to zero. However, the amplitude cannot go below zero, thus the critical parameter value transforming the complex into the simple model lie on the boundary of parameter space.
If these two conditions are not given, the observed likelihood ratio must be calibrated via simulations of the simpler model. In general, one should not simulate from the best-fit model alone: this ignores the uncertainty in the model parameters, and thus may artificially inflate the significance of the result.
In the purely frequentist (maximum likelihood case), one does not know the shape of the probability distribution for the parameters. A rough approximation can be obtained by assuming the likelihood surface to be a multi-variate Gaussian, with covariances given by the inverse Fisher information. One may sample from that distribution and then simulate fake data sets using the sampled parameters. Each simulated data set will be fit with both models to compute a likelihood ratio, which is then used to build a distribution of likelihood ratios from the simpler model to compare the observed likelihood ratio to.
In the Bayesian case, one may sample from the posterior for the parameters directly and then use these samples as above to create fake data sets in order to derive a posterior probability...
Can you write Python code for it?

import copy

def _generate_model(lpost, pars):
    """
    Helper function that generates a fake PSD similar to the
    one in the data, but with different parameters.

    Parameters
    ----------
    lpost : instance of a Posterior or LogLikelihood subclass
        The object containing the relevant information about the
        data and the model

    pars : iterable
        A list of parameters to be passed to lpost.model in oder
        to generate a model data set.

    Returns:
    --------
    model_data : numpy.ndarray
        An array of model values for each bin in lpost.x

    """
    # get the model
    m = lpost.model

    # reset the parameters
    _fitter_to_model_params(m, pars)

    # make a model spectrum
    model_data = lpost.model(lpost.x)

    return model_data

def _generate_psd(ps, lpost, pars):
    """
    Generate a fake power spectrum from a model.

    Parameters:
    ----------
    lpost : instance of a Posterior or LogLikelihood subclass
        The object containing the relevant information about the
        data and the model

    pars : iterable
        A list of parameters to be passed to lpost.model in oder
        to generate a model data set.

    Returns:
    --------
    sim_ps : stingray.Powerspectrum object
        The simulated Powerspectrum object

    """

    model_spectrum = _generate_model(lpost, pars)

      # use chi-square distribution to get fake data
    model_powers = model_spectrum*np.random.chisquare(2*ps.m,
                                                      size=model_spectrum.shape[0])/(2.*ps.m)

    sim_ps = copy.copy(ps)

    sim_ps.powers = model_powers

    return sim_ps

def _compute_pvalue(obs_val, sim):
    """
    Compute the p-value given an observed value of a test statistic
    and some simulations of that same test statistic.

    Parameters
    ----------
    obs_value : float
        The observed value of the test statistic in question

 ...


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Convenience Functions
For convenience, we have implemented some simple functions to reduce overhead with having to instantiate objects of the various classes.
Note that these convenience function use similar approaches and guesses in all cases; this might work for some simple quicklook analysis, but when preparing publication-ready results, one should approach the analysis with more care and make sure the options chosen are appropriate for the problem at hand.
Fitting a power spectrum with some model
The code above allows for a lot of freedom in building an appropriate model for your application. However, in everyday life, one might occasionally want to do a quick fit for various applications, without having to go too much into details. Below is a convenience function written for exactly that purpose.
Please note that while this aims to use reasonable defaults, this is unlikely to produce publication-ready results!
So let's fit a power law and a constant to some data, which we'll create below:
Can you write Python code for it?

from stingray import Powerspectrum

m = 1
nfreq = 100000
freq = np.linspace(1, 1000, nfreq)

np.random.seed(100)  # set the seed for the random number generator
noise = np.random.exponential(size=nfreq)

model = models.PowerLaw1D() + models.Const1D()
model.x_0_0.fixed = True

alpha_0 = 2.0
amplitude_0 = 100.0
amplitude_1 = 2.0

model.alpha_0 = alpha_0
model.amplitude_0 = amplitude_0
model.amplitude_1 = amplitude_1

p = model(freq)
power = noise * p

ps = Powerspectrum()
ps.freq = freq
ps.power = power
ps.m = m
ps.df = freq[1] - freq[0]
ps.norm = "leahy"


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Cool, that seems to work! For convenience PSDParEst also has a plotting function:
Can you write Python code for it?


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Finally, it also produces the values of the mean function for the parameters at the maximum. Let's plot that and compare with the power spectrum we put in:
Can you write Python code for it?

plt.figure(figsize=(12,8))
plt.loglog(ps.freq, psd_shape, label="true power spectrum",lw=3)
plt.loglog(ps.freq, ps.power, label="simulated data")
plt.loglog(ps.freq, res.mfit, label="best fit", lw=3)
plt.legend()


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
In order to fit this, we'll write a convenience function that can take the power spectrum, a model, some starting parameters and just run with it:
Can you write Python code for it?

from stingray.modeling import PSDLogLikelihood, PSDPosterior, PSDParEst

def fit_powerspectrum(ps, model, starting_pars, max_post=False, priors=None,
                      fitmethod="L-BFGS-B"):

    if priors:
        lpost = PSDPosterior(ps, model, priors=priors)
    else:
        lpost = PSDLogLikelihood(ps.freq, ps.power, model, m=ps.m)

    parest = PSDParEst(ps, fitmethod=fitmethod, max_post=max_post)
    res = parest.fit(lpost, starting_pars, neg=True)

    return parest, res


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Let's look at the output:
Can you write Python code for it?


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Let's make a dataset so we can test it!
Can you write Python code for it?

np.random.seed(400)
nlor = 3

x_0_0 = 0.5
x_0_1 = 2.0
x_0_2 = 7.5

amplitude_0 = 150.0
amplitude_1 = 50.0
amplitude_2 = 15.0

fwhm_0 = 0.1
fwhm_1 = 1.0
fwhm_2 = 0.5

whitenoise = 2.0

model = models.Lorentz1D(amplitude_0, x_0_0, fwhm_0) + \
        models.Lorentz1D(amplitude_1, x_0_1, fwhm_1) + \
        models.Lorentz1D(amplitude_2, x_0_2, fwhm_2) + \
        models.Const1D(whitenoise)

p = model(ps.freq)
noise = np.random.exponential(size=len(ps.freq))

power = p*noise

plt.figure()
plt.loglog(ps.freq, power, lw=1, ds="steps-mid", c="black")
plt.loglog(ps.freq, p, lw=3, color="red")


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Let's see if it works. We've already defined our model above, but to be explicit, let's define it again:
Can you write Python code for it?

model_to_test = models.PowerLaw1D() + models.Const1D()
model_to_test.x_0_0.fixed = True


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Likelihood Ratios
The parameter estimation code has more functionality than act as a simple wrapper around scipy.optimize. For example, it allows for easy computation of likelihood ratios. Likelihood ratios are a standard way to perform comparisons between two models (though they are not always statistically meaningful, and should be used with caution!).
To demonstrate that, let's make a broken power law model
Can you write Python code for it?

# broken power law model
bpl = models.BrokenPowerLaw1D()

# add constant
bplc = bpl + c

bplc.param_names

# define starting parameters
bplc_start_pars = [2.0, 1.0, 3.0, 1.0, 2.5]

loglike_bplc = PSDLogLikelihood(ps.freq, ps.power, bplc, m=ps.m)

pval, plc_opt, bplc_opt = parest.compute_lrt(loglike, starting_pars, loglike_bplc, bplc_start_pars)

print("Likelihood Ratio: " + str(pval))


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Looks like it worked! Let's plot the result, too:
Can you write Python code for it?

plt.figure()
plt.figure()
plt.loglog(ps.freq, ps.power, ds="steps-mid", lw=2, color="black")
plt.plot(ps.freq, res.mfit, lw=3, color="red")


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Maximum Likelihood Fitting
Let's assume we've observed this periodogram from our source. We would now like to estimate the parameters.
This requires the definition of likelihood, which describes the probability of observing the data plotted above given some underlying model with a specific set of parameters. To say it differently, the likelihood encodes what we know about the underlying model (here a power law and a constant) and the statistical properties of the data (power spectra generally follow a chi-square distribution) and then allows us to compare data and model for various parameters under the assumption of the statistical uncertainties.
In order to find the best parameter set, one generally maximizes the likelihood function using an optimization algorithm. Because optimization algorithms generally minimize functions, they effectively minimize the log-likelihood, which comes out to be the same as maximizing the likelihood itself.
Below is an implementation of the $\chi^2$ likelihood as appropriate for power spectral analysis, with comments for easier understanding. The same is also implemented in posterior.py in Stingray:
Can you write Python code for it?

logmin = -1e16
class PSDLogLikelihood(object):

    def __init__(self, freq, power, model, m=1):
        """
        A Chi-square likelihood as appropriate for power spectral analysis.

        Parameters
        ----------
        freq : iterable
            x-coordinate of the data

        power : iterable
            y-coordinte of the data

        model: an Astropy Model instance
            The model to use in the likelihood.

        m : int
            1/2 of the degrees of freedom, i.e. the number of powers
            that were averaged to obtain the power spectrum input into
            this routine.

        """

        self.x = ps.freq # the x-coordinate of the data (frequency array)
        self.y = ps.power # the y-coordinate of the data (powers)
        self.model = model # an astropy.models instance
        self.m = m

        self.params = [k for k,l in self.model.fixed.items() if not l]
        self.npar = len(self.params) # number of free parameters

    def evaluate(self, pars, neg=False):
        """
        Evaluate the log-likelihood.

        Parameters
        ----------
        pars : iterable
            The list of parameters for which to evaluate the model.

        neg : bool, default False
            If True, compute the *negative* log-likelihood, otherwise
            compute the *positive* log-likelihood.

        Returns
        -------
        loglike : float
            The log-likelihood of the model

        """
        # raise an error if the length of the parameter array input into
        # this method doesn't match the number of free parameters in the model
        if np.size(pars) != self.npar:
            raise Exception("Input parameters must" +
                            " match model parameters!")

        # set parameters in self.model to the parameter set to be used for
        # evaluation
        _fitter_to_model_params(self.model, pars)

        # compute the values of the model at the positions...


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Now we can set the parameters in the model:
Can you write Python code for it?

from astropy.modeling.fitting import _fitter_to_model_params

_fitter_to_model_params(plc, [amplitude, alpha, white_noise])

psd_shape = plc(freq)


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Now we can set up the PSDPosterior object:
Can you write Python code for it?

lpost_bplc = PSDPosterior(ps.freq, ps.power, bplc, priors=priors, m=ps.m)

lpost_bplc(bplc_start_pars)


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Now we just need some starting parameters:
Can you write Python code for it?

t0 = [80, 1.5, 2.5]

parest, res = fit_powerspectrum(ps, model_to_test, t0)

res.p_opt


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Similarly, the method plot_results produces a bunch of plots:
Can you write Python code for it?

fig = sample.plot_results(nsamples=1000, fig=None, save_plot=True,
                    filename="modeling_tutorial_mcmc_corner.pdf")


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
So now we can fit this model with our new function, but first, we need to define the starting parameters for our fit. The starting parameters will be [amplitude, x_0, fwhm] for each component plus the white noise component at the end:
Can you write Python code for it?


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Something close to the parameters we put in should yield the largest log-likelihood. Feel free to play around with the test parameters to verify that this is true.
You can similarly import the PSDLogLikelihood class from stingray.modeling and do the same:
Can you write Python code for it?

from stingray.modeling import PSDLogLikelihood

loglike = PSDLogLikelihood(ps.freq, ps.power, plc, m=ps.m)
loglike(test_pars)


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
The models and API of astropy.modeling.models is explained in the astropy documentation in more detail.
Here's how you instantiate a simple 1-D Gaussian:
Can you write Python code for it?

g = models.Gaussian1D()

# Generate fake data
np.random.seed(0)
x = np.linspace(-5., 5., 200)
y = 3 * np.exp(-0.5 * (x - 1.3)**2 / 0.8**2)
y += np.random.normal(0., 0.2, x.shape)
yerr = 0.2

plt.figure(figsize=(8,5))
plt.errorbar(x, y, yerr=yerr, fmt='ko')


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
The priors are set as a dictionary of functions:
Can you write Python code for it?

import scipy.stats

# flat prior for the power law index
p_alpha = lambda alpha: ((-1. <= alpha) & (alpha <= 5.))

# flat prior for the power law amplitude
p_amplitude = lambda amplitude: ((0.01 <= amplitude) & (amplitude <= 10.0))

# normal prior for the white noise parameter
p_whitenoise = lambda white_noise: scipy.stats.norm(2.0, 0.1).pdf(white_noise)

priors = {}
priors["alpha_0"] = p_alpha
priors["amplitude_0"] = p_amplitude
priors["amplitude_1"] = p_whitenoise


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
The same outputs exist as for the Maximum Likelihood case:
Can you write Python code for it?


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
To estimate the parameters, we can use an optimization routine, such as those implemented in scipy.optimize.minimize.
We have wrapped some code around that, to make your lives easier. We will not reproduce the full code here, just demonstrate its functionality.
Now we can instantiate the PSDParEst (for PSD Parameter Estimation) object. This can do more than simply optimize a single model, but we'll get to that later.
The PSDParEst object allows one to specify the fit method to use (however, this must be one of the optimizers in scipy.optimize). The parameter max_post allows for doing maximum-a-posteriori fits on the Bayesian posterior rather than maximum likelihood fits (see below for more details). We'll set it to False for now, since we haven't defined any priors:
Can you write Python code for it?

from stingray.modeling import PSDParEst

parest = PSDParEst(ps, fitmethod="L-BFGS-B", max_post=False)


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
Unlike in the maximum likelihood case, we can also sample from the posterior probability distribution. The method sample uses the emcee package to do MCMC.
Important: Do not sample from the likelihood function. This is formally incorrect and can lead to incorrect inferences about the problem, because there is no guarantee that a posterior with improper (flat, infinite) priors will be bounded!
Important: emcee has had a major upgrade to version 3, which came with a number of API changes. To ensure compatibility with stingray, please update emcee to the latest version, if you haven't already.
Much like the optimizer, the sampling method requires a model and a set of starting parameters t0. Optionally, it can be useful to also input a covariance matrix, for example from the output of the optimizer.
Finally, the user should specify the number of walkers as well as the number of steps to use for both burn-in and sampling:
Can you write Python code for it?

sample = parest.sample(lpost, res.p_opt, cov=res.cov, nwalkers=400,
             niter=100, burnin=300, namestr="psd_modeling_test")


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
We're going to pick some fairly standard parameters for our data:
Can you write Python code for it?

# parameters for fake data.
alpha = 2.0
amplitude = 5.0
white_noise = 2.0


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
What does this data set look like?
Can you write Python code for it?

plt.figure()
plt.loglog(ps.freq, ps.power, ds="steps-mid", lw=2, color="black")


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
You can also set the priors when you instantiate the posterior object:
Can you write Python code for it?

lpost = PSDPosterior(ps.freq, ps.power, plc, priors=priors, m=ps.m)


I am working on the file "Modeling/ModelingExamples.ipynb".
The first task is:
You can find the function in the scripts sub-module:
Can you write Python code for it?

from stingray.modeling.scripts import fit_powerspectrum

parest, res = fit_powerspectrum(ps, model_to_test, t0)
res.p_opt


I am working on the file "ModelingExamples2.ipynb".
The first task is:
6-faced die with repeated labels
Consider a die where the numbers on each face are labeled, possibly with repetitions, from the set $1\dots 6$.
A 'normal' die has labels $1,2,3,4,5,6$ but we allow other labelings, for example as $1,1,3,5,5,5$ or $1,1,1,1,1,6$.
Can we construct a method to find how the die has been labeled from a sequence of outcomes?
Does my data have a single cluster or are there two clusters?
We observe a dataset of $N$ points and want to decide if there are one or two clusters. For example, the below dataset, when visualized seems to suggest two clusters; however the separation is not very clear; perhaps a single component might have been also sufficient. How can we derive a procedure that leads to a resonable answer in this ambigious situation?
<img src="clusters.png" width='180' align='center'>
One principled approach is based on Bayesian model selection. Our approach will be describing two alternative generative models for data. Each generative model will reflect our assumption what it means to have clusters. In other words, we should describe two different procedures: how to generate a dataset with a single cluster, or a datset that has two clusters. Once we have a description of each generative procedure, we may hope to convert our qualitative question (how many clusters?) into a well defined computational procedure.
Each generative procedure will be a different probability model and we will compute the marginal posterior distribution conditioned on an observed dataset.
The single cluster model will have a single cluster center, denoed as $\mu$. Once $\mu$ is generated, each observation is generated by a Gaussian distribution with variance $R$, centered around $\mu$.
Model $M =1$: Single Cluster
\begin{eqnarray}
\mu & \sim & {\mathcal N}(\mu; 0, P) \
x_i | \mu & \sim & {\mathcal N}(x; \mu, R)
\end{eqnarray}
The parameter $P$ denotes a natural range for the mean, $R$ denotes the variance of data, the amount of spread around the mean. To start simple, we will assume that these...
Can you write Python code for it?

# Parameters
P = 100
R = 10

# Number of datapoints
N = 5

mu = np.random.normal(0, np.sqrt(P))
x  = np.random.normal(mu, np.sqrt(R), size=(N))

plt.figure(figsize=(10,1))
plt.plot(mu, 0, 'r.')
plt.plot(x, np.zeros_like(x), 'x')
ax = plt.gca()
ax.set_xlim(3*np.sqrt(P)*np.array([-1,1]))
ax.set_ylim([-0.1,0.1])
ax.axis('off')
plt.show()


I am working on the file "ModelingExamples2.ipynb".
The first task is:
Computing the marginal likelihood

Model 1

\begin{eqnarray}
p(X| m=1) & = & \int d{s_{1:K}} p(X|s_{1:K}) p(s_{1:K}) =
\end{eqnarray}
Can you write Python code for it?

# %load template_equations.py
from IPython.display import display, Math, Latex, HTML
import notes_utilities as nut
from importlib import reload
reload(nut)
Latex('$\DeclareMathOperator{\trace}{Tr}$')

#L = nut.pdf2latex_gauss(x=r's', m=r'\mu',v=r'v')
L = nut.pdf2latex_mvnormal(x=r'x_t', m=r'(Ax_{t-1})',v=r'Q')
#L = nut.pdf2latex_mvnormal(x=r's', m=0,v=r'I')
#L = nut.pdf2latex_gamma(x=r'x', a=r'a',b=r'b')
#L = nut.pdf2latex_invgamma(x=r'x', a=r'a',b=r'b')
#L = nut.pdf2latex_beta(x=r'\pi', a=r'\alpha',b=r'\beta')

eq = L[0]+'='+L[1]+'='+L[2]
display(Math(eq))

L = nut.pdf2latex_mvnormal(x=r'y_t', m=r'(Cx_{t})',v=r'R')
eq = L[0]+'='+L[1]+'='+L[2]
display(Math(eq))

%connect_info


I am working on the file "ModelingExamples2.ipynb".
The first task is:
Conceptually $M_2$, $M_3$ and $M_3b$ should have the same marginal likelihood score, as the dependence should not depend on how we parametrize the conditional probability tables. However, this is dependent on the choice of the prior parameters.
How should the prior parameters of $M_2$, $M_3$ and $M_3b$ be chosen such that we get the same evidence score?
The models
$M_2$, $M_3$ and $M_3b$ are all equivlent, if the prior parameters are chosen appropriately. For $M_2$ and $M_3$, we need to take $a_1(i) = \sum_j a_{1,2}(i,j)$.
For example, if in $M_2$, the prior parameters $a_{1,2}$ are chosen as
\begin{eqnarray}
a_{1,2} & = & \left(\begin{array}{ccc} 1 & 1 & 1\ 1 & 1 & 1 \end{array} \right)
\end{eqnarray}
we need to choose in model $M_3$
\begin{eqnarray}
a_{1} & = & \left(\begin{array}{c} 3 \ 3  \end{array} \right)
\end{eqnarray}
\begin{eqnarray}
a_{2} & = & \left(\begin{array}{ccc} 1 & 1 & 1\ 1 & 1 & 1 \end{array} \right)
\end{eqnarray}
and in model $M_3b$
\begin{eqnarray}
a_{2} & = & \left(\begin{array}{ccc} 2 & 2 & 2  \end{array} \right)
\end{eqnarray}
\begin{eqnarray}
a_{1} & = & \left(\begin{array}{ccc} 1 & 1 & 1\ 1 & 1 & 1 \end{array} \right)
\end{eqnarray}
This is due to fact that the marginals of a Dirichlet distribution are also Dirichlet. In particular,
if a probability vector $x$ and corresponding parameter vector $a$ are partitioned as $x = (x_\iota, x_{-\iota})$
and $a = (a_\iota, a_{-\iota})$, the Dirichlet distribution
$$
\mathcal{D}(x_\iota, x_{-\iota}; a_\iota, a_{-\iota})
$$
has marginals
$$
\mathcal{D}(X_{\iota}, X_{-\iota}; A_{\iota}, A_{-\iota})
$$
where $X_\iota = \sum_{i \in \iota}  x_i$ and $X_{-\iota} = \sum_{i \in -\iota}  x_i$, where $A_\iota = \sum_{i \in \iota}  a_i$ and $A_{-\iota} = \sum_{i \in -\iota}  a_i$. The script below verifies that the marginals are indeed distributed according to this formula.
Can you write Python code for it?

S_1 = 2
S_2 = 10
M = S_1*S_2

a = np.ones(M)

N = 100
P = np.random.dirichlet(a, size=N)
A = np.zeros((N,S_1))
B = np.zeros((N*S_1,S_2))

for n in range(N):
    temp = P[n,:].reshape((S_1,S_2))
    A[n,:] = np.sum(temp, axis=1)
    for i in range(S_1):
        B[(n*S_1+i),:] = temp[i,:]/A[n,i]

import pylab as plt

plt.hist(A[:,0],bins=20)
plt.gca().set_xlim([0,1])
#plt.plot(B[:,0],B[:,1],'.')
plt.show()

P2 = np.random.dirichlet(S_2*np.ones(S_1), size=N)
plt.hist(P2[:,0],bins=20)
plt.gca().set_xlim([0,1])
plt.show()

import numpy as np
from notes_utilities import randgen, log_sum_exp, normalize_exp, normalize

import scipy as sc
from scipy.special import gammaln

# Log of multivariate Beta function
def log_mbeta(a):
    return sum(gammaln(a.flatten())) - gammaln(sum(a.flatten()))

a = 1
b = 1

S = np.array([[2,1],[0,1]])
#S = np.array([[2,1,0],[1,0,1]])

S_ip = np.sum(S, axis=1)
S_pj = np.sum(S, axis=0)
S_pp = np.sum(S)

gamma = 1
alpha = gamma*np.ones_like(S)

alpha_ip = np.sum(alpha, axis=1)
alpha_pj = np.sum(alpha, axis=0)
alpha_pp = np.sum(alpha)

#
log_const = a*np.log(b) -  (a+S_pp)*np.log(b+1) + gammaln(a + S_pp) - gammaln(a) - np.sum(gammaln(S+1))
print(log_const)

# inconsistent independent
alpha_wrong_ip = gamma*np.ones_like(alpha_ip)
alpha_wrong_pj = gamma*np.ones_like(alpha_pj)

# i    j
marglik_1_wrong =  log_mbeta(S_ip+alpha_wrong_ip) - log_mbeta(alpha_wrong_ip)
marglik_1_wrong += log_mbeta(S_pj+alpha_wrong_pj) - log_mbeta(alpha_wrong_pj)
# i -> j
marglik_2_wrong  =  log_mbeta(S_ip+alpha_wrong_ip) - log_mbeta(alpha_wrong_ip)
for i in range(S.shape[0]):
    marglik_2_wrong +=  log_mbeta(S[i,:]+alpha[i,:]) - log_mbeta(alpha[i,:])
# i <- j
marglik_3_wrong  =  log_mbeta(S_pj+alpha_wrong_pj) - log_mbeta(alpha_wrong_pj)
for j in range(S.shape[1]):
    marglik_3_wrong +=  log_mbeta(S[:,j]+alpha[:,j]) - log_mbeta(alpha[:,j])

# independent
marglik_1  = log_mbeta(S_ip+alpha_ip) - log_mbeta(alpha_ip)
marglik_1 += log_mbeta(S_pj+alpha_pj) - log_mbeta(alpha_pj)

# i -> j
marglik_2  = ...


I am working on the file "ModelingExamples2.ipynb".
The first task is:
Extension
We dont know the component variances
Combining into a single model
Capture
Recapture
Change point
Coin switch
Coal Mining Data
 Single Change Point
 Multiple Change Point
Bivariate Gaussian model selection
Suppose we are given a dataset $X = {x_1, x_2, \dots, x_N }$ where $x_n \in \mathbb{R}^K$ for $n=1 \dots N$ and consider two competing models:

Model $m=1$:
$\newcommand{\diag}{\text{diag}}$

Observation
\begin{eqnarray}
\text{for}\; n=1\dots N&& \
x_n| s_{1:K} & \sim &  \mathcal{N}\left(x; 0, \diag{s_1, \dots, s_K}\right) = \mathcal{N}\left(x; 0, \left(\begin{array}{ccc} s_1 & 0 & 0\0 & \ddots & 0 \ 0 & \dots & s_K \end{array} \right) \right)
\end{eqnarray}

$$
p(x_n| s_{1:K})  =
\prod_{k=1}^K \mathcal{N}(x_{k,n}; 0, s_k)
$$
$$
p(X|s_{1:K} ) = \prod_{n=1}^N p(x_n| s_{1:K})  =
\prod_{n=1}^N \prod_{k=1}^K \mathcal{N}(x_{k,n}; 0, s_k)
$$

Prior
\begin{eqnarray}
\text{for}\; k=1\dots K&& \
s_k & \sim & \mathcal{IG}(s_k; \alpha, \beta)
\end{eqnarray}

Model $m=2$:

-- Observation
\begin{eqnarray}
x_n \sim \mathcal{N}(x_n; 0, \Sigma)=\left|{ 2\pi \Sigma } \right|^{-1/2} \exp\left(-\frac12 {x_n}^\top {\Sigma}^{-1} {x_n} \right)=\exp\left( -\frac{1}{2}\trace {\Sigma}^{-1} {x_n}{x_n}^\top -\frac{1}{2}\log \left|2{\pi}\Sigma\right|\right)
\end{eqnarray}
$$
{\cal IW}(\Sigma; 2a, 2B)  =  \exp( - (a + (k+1)/2) \log |\Sigma| - \trace B\Sigma^{-1}  - \log\Gamma_k(a) + a\log |B|) \
$$
Can you write Python code for it?

# %load template_equations.py
from IPython.display import display, Math, Latex, HTML
import notes_utilities as nut
from importlib import reload
reload(nut)
Latex('$\DeclareMathOperator{\trace}{Tr}$')

#L = nut.pdf2latex_gauss(x=r's', m=r'\mu',v=r'v')
#L = nut.pdf2latex_mvnormal(x=r's', m=r'\mu',v=r'\Sigma')
L = nut.pdf2latex_mvnormal(x=r'x_n', m=0,v=r'\Sigma')
#L = nut.pdf2latex_gamma(x=r'x', a=r'a',b=r'b')
#L = nut.pdf2latex_invgamma(x=r'x', a=r'a',b=r'b')
#L = nut.pdf2latex_beta(x=r'\pi', a=r'\alpha',b=r'\beta')

eq = L[0]+'='+L[1]+'='+L[2]
display(Math(eq))
display(Latex(eq))
display(HTML(nut.eqs2html_table(L)))


I am working on the file "ModelingExamples2.ipynb".
The first task is:
Maximum A-Posteriori Estimation
$$
\pi \sim \mathcal{D}(\pi_{1:I}; a_{1:I} )
$$
where $\sum_i \pi_i  = 1$. For $n = 1\dots N$
\begin{eqnarray}
x^{(n)} & \sim & p(x|\pi) = \prod_{i=1}^{I} \pi_i^{\ind{i = x^{(n)}}}
\end{eqnarray}
$X = {x^{(1)},\dots,x^{(N)} }$
The posterior is
\begin{align}
\log p(\pi_{1:I}| X) & =^+  \log p(\pi_{1:I}, X) \
& = \log{\Gamma(\sum_{i} a_{i})} - {\sum_{i} \log \Gamma(a_{i})}
+ \sum_{{i}=1}^{I} (a_{i} - 1) \log{\pi}{i}
+ \sum{i=1}^I\sum_{n=1}^N \ind{i = x^{(n)}} \log \pi_i \
 & =^+    \sum_{i=1}^I \left(a_i - 1 +  \sum_{n=1}^N \ind{i = x^{(n)}}\right) \log \pi_i
\end{align}
Finding the parameter vector $\pi_{1:I}$ that maximizes the posterior density is a constrained optimisation problem. After omitting constant terms that do not depend on $\pi$, we form the Lagrangian
\begin{eqnarray}
\Lambda(\pi, \lambda) & = & \sum_{i=1}^I \left(a_i - 1 +  \sum_{n=1}^N \ind{i = x^{(n)}}\right) \log \pi_i   + \lambda \left( 1 - \sum_{i'} \pi_{i'} \right ) \
\frac{\partial \Lambda(\pi, \lambda)}{\partial \pi_i} & = & \left(a_i - 1 + \sum_{n=1}^N \ind{i = x^{(n)}}\right) \frac{1}{\pi_i} - \lambda = 0 \
\pi_i & = & \frac{a_i - 1 + \sum_{n=1}^N \ind{i = x^{(n)}}}{\lambda}
\end{eqnarray}
We solve for $\lambda$
\begin{eqnarray}
1 & = & \sum_i \pi_i = \frac{- I + \sum_{i=1}^I \left( a_i + \sum_{n=1}^N \ind{i = x^{(n)}  \right) }}{\lambda} \
\lambda & = &  N - I + \sum_{i=1}^I a_i
\end{eqnarray}
Setting the count of observations equal to $i$ as $C_i \equiv \sum_{n=1}^N \ind{i = x^{(n)}}$, we obtain
Hence
\begin{eqnarray}
\pi_i & = & \frac{C_i + a_i - 1}{N + \sum_{i=1}^I a_i - I}
\end{eqnarray}
Full Bayesian Inference
Setting the count of observations equal to $i$ as $C_i \equiv \sum_{n=1}^N \ind{i = x^{(n)}}$, we obtain
The posterior is
\begin{eqnarray}
\log p(\pi_{1:I}, X) & = & \log{\Gamma(\sum_{i} a_{i})} - {\sum_{i} \log \Gamma(a_{i})} +  \sum_{i=1}^I \left(\left(a_i + \sum_{n=1}^N \ind{i = x^{(n)}}\right) - 1  \right) \log \pi_i \
& =  & \log{\Gamma(\sum_{i} a_{i})} - {\sum_{i} \log...
Can you write Python code for it?

from IPython.display import display, Math, Latex, HTML
import html_utils as htm
wd = '65px'
L = [[htm.TableCell('', width=wd), htm.TableCell('$y=1$', width=wd), htm.TableCell('$y=j$', width=wd), htm.TableCell('$y=I_2$', width='80px')],
     [r'$x=1$',r'$S_{1,1}$',r'',r'$S_{1,I_2}$'],
     [r'$x=i$',r'',r'$S_{i,j}$',r''],
     [r'$x=I_1$',r'$S_{I_1,1}$',r'',r'$S_{I_1,I_2}$']]

t = htm.make_htmlTable(L)
display(HTML(str(t)))
#print(str(t))


I am working on the file "ModelingExamples2.ipynb".
The first task is:
Model $M = 2$: Two Clusters
\begin{eqnarray}
\mu_0 & \sim & {\mathcal{N}}(\mu; 0, P) \
\mu_1 & \sim & {\mathcal{N}}(\mu; 0, P) \
c_i & \sim & {\mathcal{BE}}(r; 0.5) \
x_i | \mu_0, \mu_1, c_i & \sim & {\mathcal N}(x; \mu_0, R)^{1-c_i} {\mathcal N}(x; \mu_1, R)^{c_i}
\end{eqnarray}
The parameter $P$ denotes a natural range for both means, $R$ denotes the variance of data in each cluster. The variables $r_i$ are the indicators that show the assignment of each datapoint to one of the clusters.
Can you write Python code for it?

# Parameters
P = 100
R = 2

# Number of datapoints
N = 10

# Number of clusters
M = 2

mu = np.random.normal(0, np.sqrt(P), size=(M))
c = np.random.binomial(1, 0.5, size=N)
x = np.zeros(N)
for i in range(N):
    x[i]  = np.random.normal(mu[c[i]], np.sqrt(R))

plt.figure(figsize=(10,1))
#plt.plot(mu, np.zeros_like(mu), 'r.')
plt.plot(x, np.zeros_like(x), 'x')
ax = plt.gca()
ax.set_xlim(3*np.sqrt(P)*np.array([-1,1]))
ax.set_ylim([-0.1,0.1])
ax.axis('off')
plt.show()


I am working on the file "ModelingExamples2.ipynb".
The first task is:
Our goal is deciding if the random variables $x$ and $y$ are independent or dependent, given some observations.
| |  || |
|-|-    |-|-|
| |$y$|| |
|$x$ |$3$|$5$|$9$|
| |$7$|$9$|$17$|
Independent model $M_1$
\begin{equation}
p(x, y) = p(x) p(y)
\end{equation}
\begin{align}
\pi_1 & \sim  \mathcal{D}(\pi_1; a_1) &
\pi_2 & \sim  \mathcal{D}(\pi_2; a_2) \
x^{(n)} & \sim  \mathcal{C}(x; \pi_1) &
y^{(n)} & \sim  \mathcal{C}(y; \pi_2)
\end{align}
We let

$X_{i+} = \sum_j X_{i,j}$
$X_{+j} = \sum_i X_{i,j}$

The marginal likelihood can be found as
\begin{eqnarray}
\log p(X|M_1) & = & \log{\Gamma(\sum_{i} a_{1}(i))} - {\sum_{i} \log \Gamma(a_{1}(i)} - \log{\Gamma(\sum_{i} (a_{1}(i) + \sum_{j} C(i,j)) )} + {\sum_{i} \log \Gamma(a_{1}(i) + \sum_{j} C(i,j))} \
& & +\log{\Gamma(\sum_{j} a_{2}(j)} - {\sum_{j} \log \Gamma(a_{2}(j))} - \log{\Gamma(\sum_{j} (a_{2}(j) + \sum_{i} C(i,j)) )} + {\sum_{j} \log \Gamma(a_{2}(j) + \sum_{i} C(i,j))} \
& = & \log{\Gamma(A_1)} - \sum_{i} \log \Gamma(a_{1}(i)) - \log{\Gamma(A_1+ N)} + {\sum_{i} \log \Gamma(a_{1}(i) + C_1(i))} \
& & + \log{\Gamma(A_2)} - {\sum_{j} \log \Gamma(a_{2}(j))} - \log{\Gamma(A_2 + N )} + {\sum_{j} \log \Gamma(a_{2}(j) +  C_2(j))} \
\end{eqnarray}
Dependent model $M_2$
\begin{equation}
p(x_1, x_2)
\end{equation}
$\pi_{1,2}$ is a $S_1 \times S_2$ matrix where the joint distribution of entries is Dirichlet $\mathcal{D}(\pi_{1,2}; a_{1,2})$ with $S_1 \times S_2$ parameter matrix $a_{1,2}$. Then, the probability that $p(x_1 = i, x_2 = j|\pi_{1,2}) = \pi_{1,2}(i,j)$.
\begin{eqnarray}
\pi_{1,2} & \sim & \mathcal{D}(\pi_{1,2}; a_{1,2}) \
(x_1, x_2)^{(n)} & \sim & \mathcal{C}((x_1,x_2); \pi_{1,2}) \
\end{eqnarray}
\begin{eqnarray}
\log p(X|M_2) & = & \log{\Gamma(A_{1,2})} - {\sum_{i,j} \log \Gamma(a_{1,2}(i,j))} - \log{\Gamma(A_{1,2}+ N)} + {\sum_{i,j} \log \Gamma(a_{1,2}(i,j) + C(i,j))}
\end{eqnarray}
Dependent model $M_3$
\begin{equation}
p(x_1, x_2) = p(x_1) p(x_2|x_1)
\end{equation}
\begin{eqnarray}
\pi_1 & \sim & \mathcal{D}(\pi_1; a_1) \
\pi_{2,1} & \sim &...
Can you write Python code for it?

import numpy as np
from notes_utilities import randgen, log_sum_exp, normalize_exp, normalize

import scipy as sc
from scipy.special import gammaln

#C = np.array([[3,1,9],[7,9,17]])
C = 1*np.array([[4,1,1],[1,1,6]])

#C = np.array([[0,1,1],[1,0,2]])

C_i = np.sum(C, axis=1)
C_j = np.sum(C, axis=0)

N = np.sum(C)
S_1 = C.shape[0]
S_2 = C.shape[1]

#M1 Parameter
M1 = {'a_1': S_2*np.ones(S_1), 'a_2': S_1*np.ones(S_2), 'A_1': None, 'A_2': None}
M1['A_1'] = np.sum(M1['a_1'])
M1['A_2'] = np.sum(M1['a_2'])
#p(x_1) p(x_2)
log_marglik_M1 = gammaln(M1['A_1']) - np.sum(gammaln(M1['a_1'])) - gammaln(M1['A_1'] + N) + np.sum(gammaln(M1['a_1'] + C_i)) \
            + gammaln(M1['A_2']) - np.sum(gammaln(M1['a_2'])) - gammaln(M1['A_2'] + N) + np.sum(gammaln(M1['a_2'] + C_j))

# p(x_1, x_2)
M2 = {'a_12': np.ones((S_1,S_2)), 'A_12':None}
M2['A_12'] = np.sum(M2['a_12'])
log_marglik_M2 = gammaln(M2['A_12']) - np.sum(gammaln(M2['a_12'])) - gammaln(M2['A_12'] + N) + np.sum(gammaln(M2['a_12'] + C))

M3 = {'a_1': S_2*np.ones(S_1), 'a_2': np.ones(S_2), 'A_1': None, 'A_2': None}
M3['A_1'] = np.sum(M3['a_1'])
M3['A_2'] = np.sum(M3['a_2'])

#p(x_1) p(x_2|x_1)
log_marglik_M3 = gammaln(M3['A_1']) - np.sum(gammaln(M3['a_1'])) - gammaln(M3['A_1'] + N) + np.sum(gammaln(M3['a_1'] + C_i))
for i in range(S_1):
    log_marglik_M3 +=  gammaln(M3['A_2']) - np.sum(gammaln(M3['a_2'])) - gammaln(M3['A_2'] + C_i[i]) + np.sum(gammaln(M3['a_2'] + C[i,:]))

# Beware the prior parameters
M3b = {'a_1': np.ones(S_1), 'a_2': S_1*np.ones(S_2), 'A_1': None, 'A_2': None}
M3b['A_1'] = np.sum(M3b['a_1'])
M3b['A_2'] = np.sum(M3b['a_2'])

#p(x_2) p(x_1|x_2)
log_marglik_M3b = gammaln(M3b['A_2']) - np.sum(gammaln(M3b['a_2'])) - gammaln(M3b['A_2'] + N) + np.sum(gammaln(M3b['a_2'] + C_j))
for j in range(S_2):
    log_marglik_M3b +=  gammaln(M3b['A_1']) - np.sum(gammaln(M3b['a_1'])) - gammaln(M3b['A_1'] + C_j[j]) + np.sum(gammaln(M3b['a_1'] + C[:,j]))

print('M1:', log_marglik_M1)
print('M2:', log_marglik_M2)
print('M3:', log_marglik_M3)
print('M3b:',...


I am working on the file "ModelingExamples2.ipynb".
The first task is:
Question
Are two given histograms drawn from the same distribution?
$[3,5,12,4]$
$[8, 14, 31, 14]$
Visualizing the Dirichlet Distribution
[http://blog.bogatron.net/blog/2014/02/02/visualizing-dirichlet-distributions/]
Can you write Python code for it?

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as tri
from functools import reduce
from scipy.special import gammaln

corners = np.array([[0, 0], [1, 0], [0.5, 0.75**0.5]])
triangle = tri.Triangulation(corners[:, 0], corners[:, 1])

refiner = tri.UniformTriRefiner(triangle)
trimesh = refiner.refine_triangulation(subdiv=4)

# Mid-points of triangle sides opposite of each corner
midpoints = [(corners[(i + 1) % 3] + corners[(i + 2) % 3]) / 2.0 \
             for i in range(3)]

def xy2bc(xy, tol=1.e-3):
    '''Converts 2D Cartesian coordinates to barycentric.'''
    s = [(corners[i] - midpoints[i]).dot(xy - midpoints[i]) / 0.75 \
         for i in range(3)]
    return np.clip(s, tol, 1.0 - tol)

class Dirichlet(object):
    def __init__(self, alpha):
        self._alpha = np.array(alpha)
        self._coef = gammaln(np.sum(self._alpha)) - np.sum(gammaln(self._alpha))
    def log_pdf(self, x):
        return self._coef + np.sum(np.log(x)*(self._alpha - 1))
    def pdf(self, x):
        '''Returns pdf value for `x`.'''
        return np.exp(self.log_pdf(x))

def draw_pdf_contours(dist, nlevels=200, subdiv=8, **kwargs):

    refiner = tri.UniformTriRefiner(triangle)
    trimesh = refiner.refine_triangulation(subdiv=subdiv)
    pvals = [dist.pdf(xy2bc(xy)) for xy in zip(trimesh.x, trimesh.y)]

    plt.tricontourf(trimesh, pvals, nlevels, **kwargs)
    plt.axis('equal')
    plt.xlim(0, 1)
    plt.ylim(0, 0.75**0.5)
    plt.axis('off')

draw_pdf_contours(Dirichlet([1, 3, 1]))

draw_pdf_contours(Dirichlet([1.99, 3.99, 10.99]))


I am working on the file "Modelling Coupled Elements.ipynb".
The first task is:
Accuracy of the models
The extinction cross section is now plotted for the pair of rings, using both the simpler model and the direct calculation. Additionally, the cross section of a single ring is shown. It can be seen that this fundamental mode of a single ring is split into two coupled modes. Due to the coupling impedance being complex, the hybridised modes have different widths.
Can you write Python code for it?

# normalise the extinction to the cross-sectional area of each ring
area = np.pi*(parameters['outer_radius'])**2

Q_single = extinction_single/area
Q_pair = extinction_tot/area
Q_full_model = extinction_full_model/area
Q_simple_model = extinction_simple_model/area

plt.figure(figsize=(12,4))
plt.subplot(121)
plt.plot(freqs*1e-9, Q_pair.real, label='pair')
plt.plot(freqs*1e-9, Q_single.real, label='single')
plt.plot(freqs*1e-9, np.sum(Q_simple_model.real, axis=1), label='model')
plt.xlim(freqs[0]*1e-9, freqs[-1]*1e-9)
plt.xlabel('f (GHz)')
plt.legend(loc='upper right')
plt.ylabel('Extinction efficiency')
plt.subplot(122)
plt.plot(freqs*1e-9, Q_pair.imag)
plt.plot(freqs*1e-9, Q_single.imag)
plt.plot(freqs*1e-9, np.sum(Q_simple_model.imag, axis=1))
plt.xlim(freqs[0]*1e-9, freqs[-1]*1e-9)
plt.ylabel('Normalised reactance')
plt.xlabel('f (GHz)')
plt.show()


I am working on the file "Modelling Coupled Elements.ipynb".
The first task is:
Constructing the models
We now use these singularities to construct a model for each of the rings, where $n$ represents the ring number and $m$ represents the mode number. $s=j\omega$ is the complex frequency, $s_{n,m}$ is the complex resonant frequency of each mode and $\mathbf{V}_{n, m}$ is the corresponding current of the mode. The current on each ring is represented as a sum of modes
$$\mathbf{J}{n} = \sum_m a{n,m}\mathbf{V}_{n, m}$$
This results in the following coupled equation system for the modal coefficients on each ring
$$\frac{s_{n,m}}{s}\left(s-s_{n,m}\right)a_{n,m} + \sum_{n'\neq n}\sum_{m'}\left(sL_{m,n,m',n'} + \frac{1}{s}S_{m,n,m',n'}\right)a_{n',m'} = \mathbf{V}{n, m}\cdot\mathbf{E}{inc}$$

The first term just says that the self-impedance of each mode is calculated directly from the pole expansion.
The second term is the mutual inductance $L$ and capacitance $C = S^{-1}$ between each modes of different rings. These coefficients are obtained by weighting the relevant parts of the impedance matrix, e.g.:
$$L_{m,n,m',n'} = \mathbf{V}{n, m} L{n,n'}\mathbf{V}_{n', m'}$$
The right hand side is just the projection of the incident field onto each mode

Here we construct two different models, one considering only the fundamental mode of each ring, and another considering the first and third modes. Due to symmetry, the second mode of each ring does not play a part in the hybridised modes which will be considered here.
Can you write Python code for it?

dominant_modes = refined.select([0]).add_conjugates()
simple_model = EfieModelMutualWeight(dominant_modes)

full_modes = refined.select([0, 2]).add_conjugates()
full_model = EfieModelMutualWeight(full_modes)


I am working on the file "Modelling Coupled Elements.ipynb".
The first task is:
Creating geometry
As in previous examples, we load a pair of SRRs, place them in the simulation and visualise the result.
Can you write Python code for it?

parameters={'inner_radius': 2.5e-3, 'outer_radius': 4e-3}

sim = openmodes.Simulation(notebook=True)
srr = sim.load_mesh(osp.join(openmodes.geometry_dir, "SRR.geo"),
                    parameters=parameters,
                    mesh_tol=0.7e-3)

srr1 = sim.place_part(srr)
srr2 = sim.place_part(srr, location=[0e-3, 0e-3, 2e-3])
srr2.rotate([0, 0, 1], 180)

sim.plot_3d()


I am working on the file "Modelling Coupled Elements.ipynb".
The first task is:
In the above figure, it can be seen that the simple model of interaction between the rings gives quite good agreement. This can be improved by using the model which considers the two modes of each ring. While the modes on the same ring are independent of each other, between meta-atoms all modes couple to each other, thus there are 3 distinct coupling impedances, and two distinct self impedance terms.
The results of this model are plotted below, showing the improved accuracy by accounting for the higher-order mode.
Can you write Python code for it?

plt.figure(figsize=(12,4))
plt.subplot(121)
plt.plot(freqs*1e-9, Q_pair.real, label='exact')
plt.plot(freqs*1e-9, np.sum(Q_simple_model.real, axis=1), label='single mode')
plt.plot(freqs*1e-9, np.sum(Q_full_model.real, axis=1), label='two modes')
plt.legend(loc="upper right")
plt.xlim(5.0, 7)
plt.xlabel('f (GHz)')
plt.subplot(122)
plt.plot(freqs*1e-9, Q_pair.imag)
plt.plot(freqs*1e-9, np.sum(Q_simple_model.imag, axis=1))
plt.plot(freqs*1e-9, np.sum(Q_full_model.imag, axis=1))
plt.xlim(5.3, 6.5)
plt.xlabel('f (GHz)')
plt.show()


I am working on the file "Modelling Coupled Elements.ipynb".
The first task is:
Solving scattering based on models
Now we iterate through all frequencies, and calculate the model parameters. Their accuracy is demonstrated by using them to calculate the extinction cross-section. For reference purposes, this will be compared with the direct calculation.
Can you write Python code for it?

num_freqs = 200
freqs = np.linspace(5e9, 10e9, num_freqs)

plane_wave = PlaneWaveSource([0, 1, 0], [1, 0, 0], p_inc=1.0)

extinction_tot = np.empty(num_freqs, np.complex128)
extinction_single = np.empty(num_freqs, np.complex128)
extinction_full_model = np.empty((num_freqs, len(full_modes)), np.complex128)
extinction_simple_model = np.empty((num_freqs, len(dominant_modes)), np.complex128)

# store the mutual coupling coefficients for plotting purposes
mutual_L = np.empty(num_freqs, np.complex128)
mutual_S = np.empty(num_freqs, np.complex128)

simple_vr = dominant_modes.vr
simple_vl = dominant_modes.vl

full_vr = full_modes.vr
full_vl = full_modes.vl

for freq_count, s in sim.iter_freqs(freqs):
    impedance = sim.impedance(s)
    V = sim.source_vector(plane_wave, s)

    # For reference directly calculate extinction for the complete system, and for a single ring
    extinction_tot[freq_count] = np.vdot(V, impedance.solve(V))
    extinction_single[freq_count] = np.vdot(V["E", srr1], impedance[srr1, srr1].solve(V["E", srr1]))

    # calculate based on the simple model
    Z_model = simple_model.impedance(s)
    V_model = simple_vl.dot(V)
    I_model = Z_model.solve(V_model)
    extinction_simple_model[freq_count] = V.conj().dot(simple_vr*(I_model))

    # calculate based on the full model
    Z_model = full_model.impedance(s)
    V_model = full_vl.dot(V)
    I_model = Z_model.solve(V_model)
    extinction_full_model[freq_count] = V.conj().dot(full_vr*(I_model))

    mutual_L[freq_count] = Z_model.matrices['L'][srr1, srr2][0, 0]
    mutual_S[freq_count] = Z_model.matrices['S'][srr1, srr2][0, 0]


I am working on the file "Modelling_TzW.ipynb".
The first task is:
<h3>#lets check the accuracy score....</h3>
Can you write Python code for it?

from sklearn.metrics import accuracy_score

y_pred = dfvaltest['prediction']
y_true = dfvaltest['status_group']

accuracy_score(y_true,y_pred)


I am working on the file "Modelling_TzW.ipynb".
The first task is:
<h3>#open test dataframe</h3>
Can you write Python code for it?

dftest = pd.read_csv('testsetfix.csv',delimiter=',')

dftest.head()

feat2pred = list(dftest.columns)
selfeat_p = [feat2pred[5],feat2pred[6],feat2pred[9],feat2pred[12],feat2pred[13],feat2pred[14]]
predfeats = dftest[selfeat_p]

dftest['status_group'] = clf2.predict(predfeats)

dftest.head()

dftest.loc[dftest['status_group']==3]

submission = dftest[['id','status_group']].copy()

submission['status_group'].replace(1,'functional',inplace=True)
submission['status_group'].replace(2,'non functional',inplace=True)
submission['status_group'].replace(3,'functional needs repair',inplace=True)

submission.to_csv('submission6baggedDT_77.csv',sep=',',header=True,index=False)

print "done!"

from sklearn.ensemble import BaggingClassifier

clf3 = BaggingClassifier(n_estimators=50)
clf3 = clf3.fit(X_new,labels)

dftest['status_group'] = clf3.predict(predfeats)

dfvaltest['prediction'] = clf3.predict(valfeats)

accuracy_score(y_true,y_pred)


I am working on the file "Modelo de impregnacion/modelo1/Actividad 8 Simulación de impregnación de LDPE.ipynb".
The first task is:
Calcul de c2
Ce calcul nous permet donc d'obtenir les valeurs de la concentration finale dans le plastique et donc de déterminer l'efficacité du procédé.
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Actividad 8 Simulación de impregnación de LDPE.ipynb".
The first task is:
Grapgique : f(Epaisseur) = c2
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Actividad 8 Simulación de impregnación de LDPE.ipynb".
The first task is:
Graphique : f(Cpo) = c2
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Actividad 8 Simulación de impregnación de LDPE.ipynb".
The first task is:
Graphique : f(Dp) = Cpo
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Actividad 8 Simulación de impregnación de LDPE.ipynb".
The first task is:
Graphique : f(Dp) = c2
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Actividad 8 Simulación de impregnación de LDPE.ipynb".
The first task is:
Polymère
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Actividad 8 Simulación de impregnación de LDPE.ipynb".
The first task is:
Table des valeurs
Ici, nous pouvons voir les valeurs obtenus pour chaque expériences. Nous avons donc la valeur de l'épaisseur du film utilisé, le food simulant utilisé, la concentration initiale d'antioxydant dans le plastique, la valeur de K qui est le coefficient de partition du migrant entre le polymer et le food simulant.Dp est le coefficient de diffusion de l'antioxydant dans le polymère, RMSE permet de prédire l'erreur faite sur la valeur, et enfin k est le coefficient de transfert massique.
Grâce à ces valeurs nous pouvons déterminer la concentration finale dans le plastique.
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1) repetido.ipynb".
The first task is:
Calcul de c2
Ce calcul nous permet donc d'obtenir les valeurs de la concentration finale dans le plastique et donc de déterminer l'efficacité du procédé.
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1) repetido.ipynb".
The first task is:
Calcul de la concentration finale
Nous avons besoin de différentes valeurs de concentration qui sont les suivantes :

Afin de calculer la concentration finale, nous avons besoin d'équations qui sont les suivantes :

Afin de calculer cela, il faut suivre la méthode précédente. C'est à dire, il faut connaître les propriétés principales, la structure utilisée, les conditions initales et le coefficient de partition K.
Ensuite, il faut faire une hypothèse sur la concentration de migrant au sein du polymère et du simulant alimentaire. Ensuite, il faut calculer le transfert massique de migrant a l'intérieur du polymère (Jp) et également à l'intérieur du simulant alimentaire (Jfs). Ceux sont des phénomènes de transfert de matière. Le phénomène de transfert massique est un phénomène irréversible durant lequel une grandeur physique est transportée par le biais de molécules, cela nous amène à la loi de Fick cependant, dans notre cas, la loi de Fick est simplifiée, en effet, la loi de Fick ne comportera ici qu'une seule dimension. Et ce transfert peut être défini de cette manière J = (Dp/(L/2))x(C1-C2).
Grâce au coefficient de partition (K), nous pouvons déterminer C2, cependant, il faut connaître C3, afin de connaître C3, nous devons déterminer le déterminer le transfert dans la couche limite du simulant alimentaire qui est donné par la relation suivante : J2 = k*(C3-C4). Il y a des conditions initiales, premièrement, Cpx = Cp0 et deuxièmement, au temps t = 0, C1=C2=Cp0, donc au début de la migration on a Cfs = 0. La dernière condition est que $ \frac{\partial c_{Cpx}}{\partial x}$ est égale à 0. La méthode "Regula Falsi" est utilisée afin de réduire le nombre de concentrations interfaciales. Le nombre d'itérations s'arrête losque J1=J2.
Can you write Python code for it?

class InterfazPolimero:
    def __init__ (self,a):
        self.a=a

    def Lire(self):
        self.tab = pd.read_csv(self.a,sep=" ")
        coef =self.tab.values
        self.Experiment = coef[:,0]
        self.Thickness = coef[:,1]
        self.FoodSimulant = coef[:,2]
        self.Cpo = coef[:,3]
        self.K = coef [:,4]
        self.Dp = coef[:,5]
        self.RMSE = coef[:,6]
        self.k = coef[:,7]
        self.c4 = coef[:,8]
#         self.c1 =coef[:,9]
        self.c2 = np.zeros(10)

        return self.tab

    def inicializarC2(self):
        self.c2 = np.zeros(10)
        self.dimension = np.shape(self.c2)
        print(self.dimension)
        return self.c2

    def calcul(self):
        self.tab["j1"] = (self.tab["Dp"] / (self.tab["Thickness"] / 2)) * (self.tab["Cpo"] - self.c2)
        print(self.tab["j1"])
        self.c3 = self.c2 / self.K
        self.j2 = self.k * (self.c3 - self.tab["c4"])
        return (self.tab["j1"] - self.j2) / self.tab["j1"]

    def calcul2(self):
        i = 0
        for self.tab["Thickness"], self.tab["Dp"], self.tab["K"], self.tab["k"], self.tab["c"] in enumerate(tab):
            self.sol = root(calcul,15,args=(float(self.tab["Dp"]),float(self.tab["k"]),float(self.tab["K"]),float(self.tab["c4"]),float(self.tab["Cpo"]),float(self.tab["Thickness"])))
            c2[i]= self.sol.x
            i = i + 1
        print(self.c2)
        return self.c2

    def Garder(self):
        raw_data ={"résultat" : [1.115510936772821, 1.0542169426645587, 1.041340418781726, 1.0219,1.4353658536585368, 1.0542169426645587, 1.058921125781793,1.0217682926829268, 1.05340368852459, 1.058921125781793]}
        df = pd.DataFrame(raw_data,index=["1","2","3","4","5","6","7","8","9","10"])
        df.to_csv("c2rep")
        return df

    def Graphique(self):
        plt.plot(self.tab["Dp"],self.Cpo,"^")
        plt.title("f(Dp)=Cpo")
        plt.xlabel("Dp")
        plt.ylabel("Cpo")
    def Graphique2(self):
       ...


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1) repetido.ipynb".
The first task is:
Grapgique : f(Epaisseur) = c2
Ici nous remarquons que le graphique est très étrange car les valeurs sont parfois décroissantes et parfois stagnes.
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1) repetido.ipynb".
The first task is:
Graphique : f(Dp) = Cpo
Ici nous remarquons que le coefficient de diffusion n'est pas spécialement lié à la concentration initiale. De plus, les résultats sont très étranges.
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1) repetido.ipynb".
The first task is:
Graphique : f(Dp) = c2
Ici nous remarquons que le coefficient de diffusion n'influe pas directement sur la concentration finale. Les résultats sont également très étranges.
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1) repetido.ipynb".
The first task is:
Polymère
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1).ipynb".
The first task is:
Calcul de c2
Ce calcul nous permet donc d'obtenir les valeurs de la concentration finale dans le plastique et donc de déterminer l'efficacité du procédé.
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1).ipynb".
The first task is:
Calcul de la concentration finale
Nous avons besoin de différentes valeurs de concentration qui sont les suivantes :

Afin de calculer la concentration finale, nous avons besoin d'équations qui sont les suivantes :

Afin de calculer cela, il faut suivre la méthode précédente. C'est à dire, il faut connaître les propriétés principales, la structure utilisée, les conditions initales et le coefficient de partition K.
Ensuite, il faut faire une hypothèse sur la concentration de migrant au sein du polymère et du simulant alimentaire. Ensuite, il faut calculer le transfert massique de migrant a l'intérieur du polymère (Jp) et également à l'intérieur du simulant alimentaire (Jfs). Ceux sont des phénomènes de transfert de matière. Le phénomène de transfert massique est un phénomène irréversible durant lequel une grandeur physique est transportée par le biais de molécules, cela nous amène à la loi de Fick cependant, dans notre cas, la loi de Fick est simplifiée, en effet, la loi de Fick ne comportera ici qu'une seule dimension. Et ce transfert peut être défini de cette manière J = (Dp/(L/2))x(C1-C2).
Grâce au coefficient de partition (K), nous pouvons déterminer C2, cependant, il faut connaître C3, afin de connaître C3, nous devons déterminer le déterminer le transfert dans la couche limite du simulant alimentaire qui est donné par la relation suivante : J2 = k*(C3-C4). Il y a des conditions initiales, premièrement, Cpx = Cp0 et deuxièmement, au temps t = 0, C1=C2=Cp0, donc au début de la migration on a Cfs = 0. La dernière condition est que $ \frac{\partial c_{Cpx}}{\partial x}$ est égale à 0. La méthode "Regula Falsi" est utilisée afin de réduire le nombre de concentrations interfaciales. Le nombre d'itérations s'arrête losque J1=J2.
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1).ipynb".
The first task is:
Grapgique : f(Epaisseur) = c2
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1).ipynb".
The first task is:
Graphique : f(Dp) = c2
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo1/Activité 4 (1).ipynb".
The first task is:
Table des valeurs
Ici, nous pouvons voir les valeurs obtenus pour chaque expériences. Nous avons donc la valeur de l'épaisseur du film utilisé, le food simulant utilisé, la concentration initiale d'antioxydant dans le plastique, la valeur de K qui est le coefficient de partition du migrant entre le polymer et le food simulant.Dp est le coefficient de diffusion de l'antioxydant dans le polymère, RMSE permet de prédire l'erreur faite sur la valeur, et enfin k est le coefficient de transfert massique.
Grâce à ces valeurs nous pouvons déterminer la concentration finale dans le plastique.
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo2/Activité 10.ipynb".
The first task is:
Fonction
Can you write Python code for it?

def fonction1 (self):
    return ( w / p ) *(c - c1) + E * (v / n) * (dcn / dt ) + (1 - E) * (v / n) * (dcn / dt) = 0

def fonction2 (self):
    return (dqn / dt) = (-1 /ti ) * (q -q1)

def fonction3 (self):
    return c = k * q1


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes.ipynb".
The first task is:
Fonction
Can you write Python code for it?

def fonction1 (n,v,W,p,E,dqn,qt):
    return ( W / p ) *(c - c[1]) + E * (v / n) + (1 - E) * (v / n) * (dqn / dt) == (dcn / dt )
n = 10
v = 2.31E-5
E = 0.4
dqn = 0.5
dt = 0.5
W = 0.0001471667
p = 285
t0, t1 = 0, 20
t = np.linspace(t0, t1, 100)
c0 = [0, 10]
c = np.zeros((len(t), len(y0)))
c[0, :] = c0
r = integrate.ode(fonction1).set_integrator("dopri5")
r.set_initial_value(c0, t0)
for i in range(1, t.size):
   c[i, :] = r.integrate(t[i]) # get one more value, add it to the array
   if not r.successful():
       raise RuntimeError("Could not integrate")

plt.plot(t, c)
plt.show()

# def fonction2 (t,q):
#     return (dqn / dt) == (-1 /ti ) * (q -q[1])
# dqn = 0.1
# ti = 10
# t0, t1 = 0, 20
# t = np.linspace(t0, t1, 100)
# q0 = [2, 0]
# q = np.zeros((len(t), len(y0)))
# q[0, :] = q0
# r = integrate.ode(fonction2).set_integrator("dopri5")
# r.set_initial_value(y0, t0)
# for i in range(1, t.size):
#    q[i, :] = r.integrate(t[i]) # get one more value, add it to the array
#    if not r.successful():
#        raise RuntimeError("Could not integrate")

# plt.plot(t, q)
# plt.show()

# def fonction3 (self):
#     return cc == k * q1
# k = 0.2
# q1 = 1
# t0, t1 = 0, 20
# t = np.linspace(t0, t1, 100)
# cc0 = [2, 0]
# cc = np.zeros((len(t), len(y0)))
# cc[0, :] = cc0
# plt.plot(t, cc)
# plt.show()


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes.ipynb".
The first task is:
Table
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes2-checkpoint.ipynb".
The first task is:
Ejemplo 2 funciona
Can you write Python code for it?

import numpy as np
from scipy import integrate
import matplotlib.pyplot as plt

def vdp1(t, y):
    return np.array([y[1], (1 - y[0]**2)*y[1] - y[0]])

t0, t1 = 0, 20                # start and end
t = np.linspace(t0, t1, 100)  # the points of evaluation of solution
y0 = [2, 0]                   # initial value
y = np.zeros((len(t), len(y0)))   # array for solution
y[0, :] = y0

r = integrate.ode(vdp1).set_integrator("dopri5")  # choice of method
r.set_initial_value(y0, t0)   # initial values

for i in range(1, t.size):
   y[i, :] = r.integrate(t[i]) # get one more value, add it to the array
   if not r.successful():
       raise RuntimeError("Could not integrate")

plt.plot(t, y)
plt.show()


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes2-checkpoint.ipynb".
The first task is:
Trabajo futuro

Realizar modificaciones de los parametros para observar cómo afectan al comportamiento del modelo.
Realizar un ejemplo de optimización de parámetros utilizando el modelo de Reverchon.

Referencias
[1] E. Reverchon, Mathematical modelling of supercritical extraction of sage oil, AIChE J. 42 (1996) 1765–1771.
https://onlinelibrary.wiley.com/doi/pdf/10.1002/aic.690420627
[2] Amit Rai, Kumargaurao D.Punase, Bikash Mohanty, Ravindra Bhargava, Evaluation of models for supercritical fluid extraction, International Journal of Heat and Mass Transfer Volume 72, May 2014, Pages 274-287. https://www.sciencedirect.com/science/article/pii/S0017931014000398
Ajuste de parámetros con ODEs: modelo Reverchon
Explicaciones :
- Poner los datos experimentales
- Definir las ecuaciones diferenciales ordinarias del systema con los diferentes parametros
- Calcular el valor de la ecuacion diferencial en cada punto, se necesita una otra funcion para integrar la ecuacion
- Despues tenemos que definir una funcion de minimos cuadrados para cada valor de y : minimos cuadrados es una tecnica de analisis numerico enmarcada dentro de la optimizacion matematica y se intenta encontrar la funcion continua entre los variables independentes y dependentes
- Para resolverlo se necesita las varoles iniciales para los parametros y los ecuacions ordinarias, para obtener los paramètros de la funcion. Despues se necesita hacer una interpolacion para los valores de las ODEs y para hacerlo se usa splines (spline es una funcion definida per partes por los polynomios), en Python splines es un método que se usa cuando hay problemas de interpolacion.
Can you write Python code for it?

#Datos experimentales
x_data = np.linspace(0,9,10)
y_data = np.array([0.000,0.416,0.489,0.595,0.506,0.493,0.458,0.394,0.335,0.309])

def f(y, t, k):
    """ sistema de ecuaciones diferenciales ordinarias """
    return (-k[0]*y[0], k[0]*y[0]-k[1]*y[1], k[1]*y[1])

def my_ls_func(x,teta):
    f2 = lambda y, t: f(y, t, teta)
    # calcular el valor de la ecuación diferencial en cada punto
    r = integrate.odeint(f2, y0, x)
    return r[:,1]

def f_resid(p):
    # definir la función de minimos cuadrados para cada valor de y"""

    return y_data - my_ls_func(x_data,p)

#resolver el problema de optimización
guess = [0.2, 0.3] #valores inicales para los parámetros
y0 = [1,0,0] #valores inciales para el sistema de ODEs
(c, kvg) = optimize.leastsq(f_resid, guess) #get params

print("parameter values are ",c)

# interpolar los valores de las ODEs usando splines
xeval = np.linspace(min(x_data), max(x_data),30)
gls = interpolate.UnivariateSpline(xeval, my_ls_func(xeval,c), k=3, s=0)

xeval = np.linspace(min(x_data), max(x_data), 200)
#Gráficar los resultados
pp.plot(x_data, y_data,'.r',xeval,gls(xeval),'-b')
pp.xlabel('t [=] min',{"fontsize":16})
pp.ylabel("C",{"fontsize":16})
pp.legend(('Datos','Modelo'),loc=0)
pp.show()

f_resid(guess)

#Datos experimentales
x_data = np.linspace(0,9,10)
y_data = np.array([0.000,0.416,0.489,0.595,0.506,0.493,0.458,0.394,0.335,0.309])
print(y_data)

# def f(y, t, k):
#     """ sistema de ecuaciones diferenciales ordinarias """

#     return (-k[0]*y[0], k[0]*y[0]-k[1]*y[1], k[1]*y[1])
def reverchon(x,t,Di):

    #Ecuaciones diferenciales del modelo Reverchon
    #dCdt = - (n/(e * V)) * (W * (Cn - Cm) / rho + (1 - e) * V * dqdt)
    #dqdt = - (1 / ti) * (q - qE)

    q = x[0]
    C = x[1]
    qE = C / kp
    ti = (r**2) / (15 * Di)
    dqdt = - (1 / ti) * (q - qE)
    dCdt = - (n/(e * V)) * (W * (C - Cm) / rho + (1 - e) * V * dqdt)

    return [dqdt, dCdt]

def my_ls_func(x,teta):
    f2 = lambda y, t: reverchon(y, t, teta)
    # calcular el valor de la...


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes_Revisión3-checkpoint.ipynb".
The first task is:
Ejemplo 2 funciona
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes_Revisión3-checkpoint.ipynb".
The first task is:
Evaluation des modèles pour l'extraction supercritique
L'extraction supercritique est de plus en plus utilisée afin de retirer des matières organiques de différents liquides ou matrices solides. Cela est dû au fait que les fluides supercritiques ont des avantages non négligeables par rapport aux autres solvants, ils ont des caractèreistiques comprises entre celles des gaz et celles des solides. En changeant la température et la pression ils peuvent capter des composés différents, ils sont donc très efficaces.
Le méchanisme de l'extraction supercritique est le suivant :
- Transport du fluide vers la particule, en premier lieu sur sa surface et en deuxième lieu a l'intérieur de la particule par diffusion
- Dissolution du soluté avec le fluide supercritique
- Transport du solvant de l'intérieur vers la surface de la particule
- Transport du solvant et des solutés de la surface de la particule vers la masse du solvant
Importance du modèle
Il est important d'avoir outil permettant de modéliser l'extraction supercritique car cela permet de déterminer les paramètres optimaux sans avoir à passer par l'expérience. Cela permet également d'exporter ce modèle sur des échelles plus grandes et donc sortir du laboratoire. De plus l'extraction supercritique est difficile à mettre en place car les pressions et les températures sont très élevées (Exemple pour le CO2 : 31°C et 74 bars).
A - Le modèle de Reverchon :
Afin d'utiliser ce modèle, définissons les variables qui vont y être admises, ci-dessous la nomenclature du modèle :
- Ap : Total surface of particles
- c : extract concentration in the fluid phase
- cn : fluid phase concentration in the nth stage
- kp : volumetric partition coefficient
- K : internal mass-transfer coefficient
- n : number of stages deriving fromf the bed subdivision
- q : extract concentration in the solid phase
- qn : solid phase concentration in the nth stage
- q* : concentration at the solid-fluid interface
- t : extraction time
- ti : internal diffusion time
- u : superficial velocity...
Can you write Python code for it?

import numpy as np
from scipy import integrate
from matplotlib.pylab import *


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes_Revisión3-checkpoint.ipynb".
The first task is:
Modelo Reverchon
Mathematical Modeling of Supercritical Extraction of Sage Oil
Can you write Python code for it?

P = 9 #MPa
T = 323 # K
Q = 8.83 #g/min
e = 0.4
rho = 285 #kg/m3
miu = 2.31e-5 # Pa*s
dp = 0.75e-3 # m
Dl = 0.24e-5 #m2/s
De = 8.48e-12 # m2/s
Di = 6e-13
u = 0.455e-3 #m/s
kf = 1.91e-5 #m/s
de = 0.06 # m
W = 0.160 # kg
kp = 0.2

r = 0.31 #m

n = 10
V = 12

#C = kp * qE
C = 0.1
qE = C / kp

Cn = 0.05
Cm = 0.02

t = np.linspace(0,10, 1)

N = 10

Q = np.ones(N+1)
Q[0] = 0

CC = np.ones(N+1)
CC[0] = 0
CC

def reverchon(x, t, Di, kp):

    #Ecuaciones diferenciales del modelo Reverchon
    #dCdt = - (n/(e * V)) * (W * (Cn - Cm) / rho + (1 - e) * V * dqdt)
    #dqdt = - (1 / ti) * (q - qE)

    q = x[0]
    C = x[1]
    ti = (r ** 2) / (15 * Di)
    qE = C / kp
    dqdt = - (1 / ti) * (q - qE)
    dCdt = - (n/(e * V)) * (W * (C - Cm) / rho + (1 - e) * V * dqdt)

    return [dqdt, dCdt]

reverchon([1, 2], 0, Di, kp)

x0 = [0, 0]
#t = np.linspace(0, 3000, 500)
t = np.linspace(0, 3000, 30)

resultado = odeint(reverchon, x0, t, args=(Di, kp))

qR = resultado[:, 0]
CR = resultado[:, 1]
plt.plot(t, CR)
plt.title("Modelo Reverchon")
plt.xlabel("t [=] min")
plt.ylabel("C [=] $kg/m^3$")

CR

#y_data = np.array([0.000,0.416,0.489,0.595,0.506,0.493,0.458,0.394,0.335,0.309])
datos = np.array([CR[2], CR[5], CR[7], CR[11], CR[13], CR[15], CR[17], CR[19], CR[22], CR[25]])
datos

x0 = [0, 0]
t = np.linspace(0, 3000, 500)

resultado = odeint(reverchon, x0, t)

qR = resultado[:, 0]
CR = resultado[:, 1]
plt.plot(t, qR)
plt.title("Modelo Reverchon")
plt.xlabel("t [=] min")
plt.ylabel("C solid–fluid interface [=] $kg/m^3$")

print(CR)

r = 0.31 #m
x0 = [0, 0]
t = np.linspace(0, 3000, 500)

resultado = odeint(reverchon, x0, t)

qR = resultado[:, 0]
CR = resultado[:, 1]
plt.plot(t, CR)
plt.title("Modelo Reverchon")
plt.xlabel("t [=] min")
plt.ylabel("C [=] $kg/m^3$")

r = 0.231 #m
x0 = [0, 0]
t = np.linspace(0, 3000, 500)

resultado = odeint(reverchon, x0, t)

qR = resultado[:, 0]
CR = resultado[:, 1]
plt.plot(t, CR)
plt.title("Modelo Reverchon")
plt.xlabel("t [=] min")
plt.ylabel("C [=]...


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes_Revisión3.ipynb".
The first task is:
Evaluation des modèles pour l'extraction supercritique
L'extraction supercritique est de plus en plus utilisée afin de retirer des matières organiques de différents liquides ou matrices solides. Cela est dû au fait que les fluides supercritiques ont des avantages non négligeables par rapport aux autres solvants, ils ont des caractèreistiques comprises entre celles des gaz et celles des solides. En changeant la température et la pression ils peuvent capter des composés différents, ils sont donc très efficaces.
Le méchanisme de l'extraction supercritique est le suivant :
- Transport du fluide vers la particule, en premier lieu sur sa surface et en deuxième lieu a l'intérieur de la particule par diffusion
- Dissolution du soluté avec le fluide supercritique
- Transport du solvant de l'intérieur vers la surface de la particule
- Transport du solvant et des solutés de la surface de la particule vers la masse du solvant
A - Le modèle de Reverchon :
Afin d'utiliser ce modèle, définissons les variables qui vont y être admises, ci-dessous la nomenclature du modèle :

Le modèle :
Il est basé sur l'intégration des bilans de masses différentielles tout le long de l'extraction, avec les hypothèses suivants :
- L'écoulement piston existe à l'intérieur du lit, comme le montre le schéma ci-contre :

- La dispersion axiale du lit est négligeable
- Le débit, la température et la pression sont constants
Cela nous permet d'obtenir les équations suivantes :
- $uV.\frac{\partial c_{c}}{\partial t}+eV.\frac{\partial c_{c}}{\partial t}+ AK(q-q) = 0$
- $(1-e).V.uV\frac{\partial c_{q}}{\partial t}= -AK(q-q*)$

Les conditions initiales sont les suivantes : C = 0, q=q0 à t = 0 et c(0,t) à h=0

La phase d'équilibre est : $c = k.q*$
Sachant que le fluide et la phase sont uniformes à chaque stage, nous pouvons définir le modèle en utilisant les équations différentielles ordinaires (2n). Les équations sont les suivantes :
-  $(\frac{W}{p}).(Cn- Cn-1) + e (\frac{v}{n}).(\frac{dcn}{dt})+(1-e).(\frac{v}{n}).(\frac{dcn}{dt}) = 0$
-...
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes_Revisión3.ipynb".
The first task is:
Fonction
Can you write Python code for it?


I am working on the file "Modelo de impregnacion/modelo2/Activité 10_Viernes_Revisión3.ipynb".
The first task is:
Table
Can you write Python code for it?


I am working on the file "Modes.ipynb".
The first task is:
S## solution of Poisson's Equation with unit forcing
solve
$$
  -\nabla^2 u = 1
$$
on $x\in[0,1]\times[0,1]$  with $u=0$ on $\partial\Omega$
Can you write Python code for it?

x = np.linspace(0,1,200)
X,Y = np.meshgrid(x,x)

def solvePoisson(N,X,Y,c=0):
    phi_nm = lambda n,m: np.sin(n*np.pi*X)*np.sin(m*np.pi*Y)

    u = np.zeros(X.shape)
    for n in range(1,N+1):
        for m in range(1,N+1):
            bnm = 4./(np.pi**2*m*n)*(np.cos(n*np.pi)-1.)*(np.cos(m*np.pi) - 1.)
            bnm -= 4.*c*m/n*(np.cos(n*np.pi)-1.)
            lambda_nm = np.pi**2*(n*n + m*m)
            u += bnm/lambda_nm*phi_nm(n,m)

    return u

N=50
u = solvePoisson(N,X,Y)

plt.figure(figsize=(8,6.2))
plt.contourf(X,Y,u)
plt.colorbar()
title = 'Poisson: $f=1$, N={}, $u_{{max}}={:5.5f}$'.format(N,np.max(u))
plt.title(title,fontsize=24)
plt.axis('equal')
plt.show()

N=200
u = solvePoisson(N,X,Y,c=.1)
plt.figure(figsize=(8,6.2))
plt.contourf(X,Y,u)
plt.colorbar()
title = 'Poisson: $f=1$, N={}, $u_{{max}}={:5.5f}$'.format(N,np.max(u))
plt.title(title,fontsize=24)
plt.axis('equal')
plt.show()


I am working on the file "Module - itertools.ipynb".
The first task is:
itertools
這個library提供許多generator相關的函式。

imap(func, p, q): 傳回func(p[i], q[i])
ifilter(pred_func, seq): 傳回seq中使pred_func(x)==True的值。
  如果pred_func==None，則傳回seq[i]==True的值
ifilterfalse(pred_func, seq): 傳回seq中使pred_func(x)==False的值。
  如果pred_func==None，則傳回seq[i]==False的值
izip(p, q): 傳回tuple (p[i], q[i])，如果p,q長度不相等，會以短的為主
izip_longest(p, q): 傳回tuple (p[i], q[i])，如果p,q長度不相等，會以長的為主
compress(data, sel): 傳回data[i] if sel[i]
chain(p1, p2, ...): 傳回p1[0],...,p1[-1],p2[0],...,p2[-1],...
takewhile(pred, seq): 傳回seq[i]直到pred(seq[i])==False
dropwhile(pred, seq): 傳回sen[i]，從使得pred(seq[i])==False的i開始
islice(seq [,start] ,stop [,step]): 傳回seq[range(start, stop, step)]
groupby(seq [,key]): 用來產生iterator of iterators。
  第一次使用next(groupby(seq, key))，會傳回(key, iterator)的組合。
  這個iterator會依序傳回seq[i]，直到key(seq[i])改變為止。
  例如key(seq)==[1,1,0,0,1]，則會產生三個(1, it1), (0, it2), (1, it3)，其中it1產生seq[0],seq[1]，it3產生seq[4]。
  如果沒指定key，則key==seq[i]。

itertools也有提供現成的generator:

count(start [,step]): 從start, start+step, ...開始的infinite generator
cycle(seq): 循環產生seq[0],...,seq[-1],seq[0],...的infinite generator
repeat(elem [,n]): 產生n個elem，如果n沒有指定會變成infinite generator
Can you write Python code for it?

from itertools import *

a = [1, 5, 8, 3, 6, 9, 2, 4, 7]
b = [11, 12, 13, 14]

list(imap(pow, b, a))  # 傳回 11^1, 12^5, 13^8, 14^3

list(ifilter(lambda x: x % 2, a))  # 傳回所有奇數

list(ifilterfalse(lambda x: x % 2, a))  # 傳回所有偶數

list(izip(a, b))  # 結合成tuple，以短的為主

list(izip_longest(a, b))  # 結合成tuple，以長的為主，空的地方填 None

list(izip_longest(a, b, fillvalue=20))  # 結合成tuple，以長的為主，空的地方填 20

list(compress('HELLO', [0, 1, 1, 0, 1]))  # 根據 boolean selector 選擇元素

list(takewhile(lambda x: x != 9, a))  # 當 pred_func 傳回 False 時停止

list(dropwhile(lambda x: x != 9, a))  # 當 pred_func 傳回 False 時開始

list(islice(fibonacci(), 3, 10, 2))  # 取出第 3, 5, 7, 9 個Fibonacci數

for k, it in groupby([1, 1, 2, 2, 2, 3, 1, 1]):  # 如果groupby沒有指定key，則iterable裡每個值都是自己的key
    print list(it)

for k, it in groupby(a, lambda x: x == 9):  # 當key值改變時，會產生新的iterator
    print list(it)


I am working on the file "Module - itertools.ipynb".
The first task is:
列出所有組合 (powerset)
Can you write Python code for it?

list(chain.from_iterable(combinations([1, 2, 3], r) for r in range(4)))


I am working on the file "Module - itertools.ipynb".
The first task is:
將list of list結合成一個list
Can you write Python code for it?

# 注意: list層數只會少一層，例如下面的 [8, 9] 仍然存在
list(chain.from_iterable([[1, 3], [4, 5], [6, [8, 9]]]))