-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathexample_wall_models.py
More file actions
292 lines (245 loc) · 10.4 KB
/
Copy pathexample_wall_models.py
File metadata and controls
292 lines (245 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
import numpy as np
#import matplotlib; matplotlib.use('Qt4Agg')
#import matplotlib.pylab as pylab; pylab.get_current_fig_manager().window.raise_()
import matplotlib.pyplot as plt
import chaospy as cp
from monte_carlo import generate_sample_matrices_mc
from monte_carlo import calculate_sensitivity_indices_mc
unit_mmhg_pa = 133.3
unit_pa_mmhg = 1./unit_mmhg_pa
unit_cm2_m2 = 1. / 100. / 100.
unit_m2_cm2 = 1. / unit_cm2_m2
# begin quadratic area model
def quadratic_area_model(pressure_range, samples):
"""
calculate the arterial vessel wall for a set pressure range
from 75 to 140 mmHg for a given set of reference wave speeds
area and pressure.
:param
pressure_range: np.array
pressure range for which to calculate the arterial area
samples: np.array with shape (4:n_samples)
sample matrix where
first indices correspond to
a_s: reference area
c_s: reference waves seed
p_s: reference pressure
rho: blood density
and n_samples to the number of samples
:return:
arterial pressure : np.array
of size n_samples
"""
pressure_range = pressure_range.reshape(pressure_range.shape[0], 1)
a_s, c_s, p_s, rho = samples
beta = 2*rho*c_s**2/np.sqrt(a_s)*a_s
#C_Laplace = (2. * ((P - Ps) * As / betaLaplace + np.sqrt(As))) * As / betaLaplace
return ((pressure_range - p_s)*a_s/beta + np.sqrt(a_s))**2.
# end quadratic area model
# begin exponential area model
def logarithmic_area_model(pressure_range, samples):
"""
calculate the arterial vessel wall for a set pressure range
from 75 to 140 mmHg for a given set of reference wave speeds
area and pressure.
:param
pressure_range: np.array
pressure range for which to calculate the arterial area
samples: np.array with shape (4:n_samples)
sample matrix where
first indices correspond to
a_s: reference area
c_s: reference waves seed
p_s: reference pressure
rho: blood density
and n_samples to the number of samples
:return:
arterial pressure : np.array
of size n_samples
"""
pressure_range = pressure_range.reshape(pressure_range.shape[0], 1)
a_s, c_s, p_s, rho = samples
beta = 2.0*rho*c_s**2./p_s
#C_hayashi = 2.0 * As / betaHayashi * (1.0 + np.log(P / Ps) / betaHayashi) / P
return a_s*(1.0 + np.log(pressure_range / p_s)/beta) ** 2.0
# end exponential area model
# start deterministic comparison
pressure_range = np.linspace(45, 180, 100) * unit_mmhg_pa
a_s = 5.12 * unit_cm2_m2
c_s = 6.25609258389
p_s = 100 * unit_mmhg_pa
rho = 1045.
plt.figure()
for model, name in [(quadratic_area_model, 'Quadratic model'), (logarithmic_area_model, 'Logarithmic model')]:
y_area = model(pressure_range, (a_s, c_s, p_s, rho))
plt.plot(pressure_range * unit_pa_mmhg, y_area * unit_m2_cm2, label=name)
plt.xlabel('Pressure [mmHg]')
plt.ylabel('Area [cm2]')
plt.legend()
plt.tight_layout()
# end deterministic comparison
# Create marginal and joint distributions
dev = 0.05
a_s = 5.12 * unit_cm2_m2
A_s = cp.Uniform(a_s * (1. - dev), a_s*(1. + dev))
c_s = 6.25609258389
C_s = cp.Uniform(c_s * (1. - dev), c_s*(1. + dev))
p_s = 100 * unit_mmhg_pa
P_s = cp.Uniform(p_s * (1. - dev), p_s*(1. + dev))
rho = 1045.
Rho = cp.Uniform(rho * (1. - dev), rho*(1. + dev))
jpdf = cp.J(A_s, C_s, P_s, Rho)
# End Create marginal and joint distributions
# scatter plots
pressure_range = np.linspace(45, 180, 100) * unit_mmhg_pa
Ns = 200
sample_scheme = 'R'
samples = jpdf.sample(Ns, sample_scheme)
for model, name, color in [(quadratic_area_model, 'Quadratic model', '#dd3c30'), (logarithmic_area_model, 'Logarithmic model', '#2775b5')]:
# evaluate the model for all samples
Y_area = model(pressure_range, samples)
plt.figure()
plt.title('{}: evaluations Y_area'.format(name))
plt.plot(pressure_range * unit_pa_mmhg, Y_area * unit_m2_cm2)
plt.xlabel('Pressure [mmHg]')
plt.ylabel('Area [cm2]')
plt.ylim([3.5,7.])
plt.figure()
plt.title('{}: scatter plots'.format(name))
for k in range(len(jpdf)):
plt.subplot(len(jpdf)/2, len(jpdf)/2, k+1)
plt.plot(samples[k], Y_area[0]*unit_m2_cm2, '.', color=color)
plt.ylabel('Area [cm2]')
plt.ylim([3.45, 4.58])
xlbl = 'Z' + str(k)
plt.xlabel(xlbl)
plt.tight_layout()
# end scatter plots
# start Monte Carlo
pressure_range = np.linspace(45, 180, 100) * unit_mmhg_pa
Ns = 50000
sample_method = 'R'
number_of_parameters = len(jpdf)
# 1. Generate sample matrices
A, B, C = generate_sample_matrices_mc(Ns, number_of_parameters, jpdf, sample_method)
plt.figure('mean')
print("\n Uncertainty measures (averaged)\n")
print('\n E(Y) | Std(Y) \n')
for model, name, color in [(quadratic_area_model, 'Quadratic model', '#dd3c30'),
(logarithmic_area_model, 'Logarithmic model', '#2775b5')]:
# evaluate the model for all samples
Y_A = model(pressure_range, A.T)
Y_B = model(pressure_range, B.T)
Y_C = np.empty((len(pressure_range), Ns, number_of_parameters))
for i in range(number_of_parameters):
Y_C[:, :, i] = model(pressure_range, C[i, :, :].T)
# calculate statistics
plotMeanConfidenceAlpha = 5.
Y = np.hstack([Y_A, Y_B])
expected_value = np.mean(Y, axis=1)
variance = np.var(Y, axis=1)
std = np.sqrt(np.var(Y, axis=1))
prediction_interval = np.percentile(Y, [plotMeanConfidenceAlpha / 2., 100. - plotMeanConfidenceAlpha / 2.], axis=1)
print('{:2.5f} | {:2.5f} : {}'.format(np.mean(expected_value)* unit_m2_cm2, np.mean(std)* unit_m2_cm2, name))
# 3. Approximate the sensitivity indices
S, ST = calculate_sensitivity_indices_mc(Y_A, Y_B, Y_C)
## Plots
plt.figure('mean')
plt.plot(pressure_range * unit_pa_mmhg, expected_value * unit_m2_cm2, label=name, color=color)
plt.fill_between(pressure_range * unit_pa_mmhg, prediction_interval[0] * unit_m2_cm2,
prediction_interval[1] * unit_m2_cm2, alpha=0.3, color=color)
plt.xlabel('Pressure [mmHg]')
plt.ylabel('Area [cm2]')
plt.legend()
plt.tight_layout()
plt.figure()
plt.title('{}: sensitvity indices'.format(name))
colorsPie = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
labels = ['Area', 'wave speed', 'pressure', 'density']
firstOrderIndicesTimeAverage = np.mean(S * variance, axis=1) / np.mean(variance)
totalIndicesTimeAverage = np.mean(ST * variance, axis=1) / np.mean(variance)
N = 4
ind = np.arange(N) # the x locations for the groups
width = 0.35 # the width of the bars
rects1 = plt.bar(ind, firstOrderIndicesTimeAverage, width, color=colorsPie, alpha=0.5)
rects2 = plt.bar(ind + width, totalIndicesTimeAverage, width, color=colorsPie, hatch='.')
ax = plt.gca()
# add some text for labels, title and axes ticks
ax.set_ylabel('Si')
ax.set_xticks(ind + width)
ax.set_xticklabels(labels)
ax.set_xlim([-width, N + width])
ax.set_ylim([0, 1])
ax.spines['top'].set_visible(False)
ax.tick_params(axis='x', top='off')
ax.spines['right'].set_visible(False)
ax.tick_params(axis='y', right='off')
plt.tight_layout()
# end Monte Carlo
# start polynomial chaos
# orthogonal C_polynomial from marginals
polynomial_order = 3
Ns = 100
print("\n Uncertainty measures (averaged)\n")
print('\n E(Y) | Std(Y) \n')
plt.figure('mean')
for model, name, color in [(quadratic_area_model, 'Quadratic model', '#dd3c30'),
(logarithmic_area_model, 'Logarithmic model', '#2775b5')]:
sample_scheme = 'R'
# create samples
samples = jpdf.sample(Ns, sample_scheme)
# create orthogonal polynomials
orthogonal_polynomials = cp.orth_ttr(polynomial_order, jpdf)
# evaluate the model for all samples
Y_area = model(pressure_range, samples)
# polynomial chaos expansion
polynomial_expansion = cp.fit_regression(orthogonal_polynomials, samples, Y_area.T)
# calculate statistics
plotMeanConfidenceAlpha = 5
expected_value = cp.E(polynomial_expansion, jpdf)
variance = cp.Var(polynomial_expansion, jpdf)
standard_deviation = cp.Std(polynomial_expansion, jpdf)
prediction_interval = cp.Perc(polynomial_expansion,
[plotMeanConfidenceAlpha / 2., 100 - plotMeanConfidenceAlpha / 2.],
jpdf)
print('{:2.5f} | {:2.5f} : {}'.format(np.mean(expected_value) * unit_m2_cm2, np.mean(std) * unit_m2_cm2, name))
# compute sensitivity indices
S = cp.Sens_m(polynomial_expansion, jpdf)
ST = cp.Sens_t(polynomial_expansion, jpdf)
plt.figure('mean')
plt.plot(pressure_range * unit_pa_mmhg, expected_value * unit_m2_cm2, label=name, color=color)
plt.fill_between(pressure_range * unit_pa_mmhg, prediction_interval[0] * unit_m2_cm2,
prediction_interval[1] * unit_m2_cm2, alpha=0.3, color=color)
plt.xlabel('Pressure [mmHg]')
plt.ylabel('Area [cm2]')
plt.legend()
plt.tight_layout()
plt.figure(name)
plt.title('{}: sensitvity indices'.format(name))
colorsPie = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
labels = ['Area', 'wave speed', 'pressure', 'density']
N = 4
ind = np.arange(N) # the x locations for the groups
width = 0.35 # the width of the bars
#firstOrderIndicesTimeAverage = S[:, 50]
#totalIndicesTimeAverage = ST[:, 50]
#rects1 = plt.bar(ind, firstOrderIndicesTimeAverage, width, color=colorsPie, alpha=0.5)
#rects2 = plt.bar(ind + width, totalIndicesTimeAverage, width, color=colorsPie, hatch='.')
firstOrderIndicesTimeAverage = np.mean(S*variance,axis=1)/np.mean(variance)
totalIndicesTimeAverage = np.mean(ST*variance,axis=1)/np.mean(variance)
rects1 = plt.bar(ind, firstOrderIndicesTimeAverage, width, color=colorsPie, alpha = 0.5)
rects2 = plt.bar(ind + width, totalIndicesTimeAverage, width, color=colorsPie, hatch = '.')
ax = plt.gca()
# add some text for labels, title and axes ticks
ax.set_ylabel('Si')
ax.set_xticks(ind + width)
ax.set_xticklabels(labels)
ax.set_xlim([-width, N + width])
ax.set_ylim([0, 1])
ax.spines['top'].set_visible(False)
ax.tick_params(axis='x', top='off')
ax.spines['right'].set_visible(False)
ax.tick_params(axis='y', right='off')
plt.tight_layout()
# end polynomial chaos
plt.show()