Skip to content

Commit 692b568

Browse files
committed
Implement analytical computation of covariance of variance estimators for tunable model multifidelity model
1 parent d6d1368 commit 692b568

File tree

2 files changed

+81
-9
lines changed

2 files changed

+81
-9
lines changed

pyapprox/benchmarks/multifidelity_benchmarks.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,80 @@ def get_kurtosis(self):
134134
(self.A1**4*(93+5*np.cos(4*self.theta1)))/1274,
135135
-(1/30)*self.A2**4*(-7+np.cos(4*self.theta2))])
136136

137+
def _covariance_of_variances(
138+
self, nsamples, E_f0_sq_f1_sq, E_f0_sq, E_f1_sq, E_f1, E_f0_sq_f1,
139+
E_f0, E_f0_f1_sq, E_f0_f1):
140+
E_u20_u21 = (E_f0_sq_f1_sq-E_f0_sq*E_f1_sq -
141+
2*E_f1*E_f0_sq_f1 + 2*E_f1**2*E_f0_sq -
142+
2*E_f0*E_f0_f1_sq + 2*E_f0**2*E_f1_sq +
143+
4*E_f0*E_f1*E_f0_f1-4*E_f0**2*E_f1**2)
144+
return E_u20_u21/nsamples + 1/(nsamples*(nsamples-1))*(
145+
E_f0_f1**2 - 2*E_f0_f1*E_f0*E_f1 + (E_f0*E_f1)**2)
146+
147+
def get_covariance_of_variances(self, nsamples):
148+
t0, t1, t2 = self.theta0, self.theta1, self.theta2
149+
s1, s2 = self.shifts
150+
E_f0_sq_f1 = self.A0**2*s1/11
151+
E_f0_f1_sq = 2*self.A0*self.A1*s1*np.cos(t1-t0)/9
152+
E_f0_sq_f1_sq = (
153+
self.A0**2*(7614*self.A1**2+19278*s1**2 +
154+
3739*self.A1**2*np.cos(2*(t1 - t0)) +
155+
1121*self.A1**2*np.cos(2*(t1 + t0))))/212058
156+
157+
E_f0_sq_f2 = self.A0**2*s2/11
158+
E_f0_f2_sq = 2*self.A0*self.A2*s2*np.cos(t2-t0)/7
159+
E_f0_sq_f2_sq = (
160+
self.A0**2*(98*(23*self.A2**2+39*s2**2) +
161+
919*self.A2**2*np.cos(2*(t2-t0)) +
162+
61*self.A2**2*np.cos(2*(t2+t0))))/42042
163+
164+
E_f1_sq_f2 = (
165+
(self.A1**2*s2)/7 + s1**2*s2 +
166+
2/5*self.A1*self.A2*s1*np.cos(t1-t2))
167+
E_f1_f2_sq = (
168+
(self.A2**2*s1)/3 + s1*s2**2 +
169+
2/5*self.A1*self.A2*s2*np.cos(t1-t2))
170+
E_f1_sq_f2_sq = (
171+
(5*self.A1**2*self.A2**2)/63 + (self.A2**2*s1**2)/3 +
172+
(self.A1**2*s2**2)/7 + s1**2*s2**2 +
173+
4/5*self.A1*self.A2*s1*s2*np.cos(t1-t2) +
174+
(113*(self.A1**2*self.A2**2*np.cos(2*(t1-t2)))/3150 -
175+
(13*self.A1**2*self.A2**2*np.cos(2*(t1 + t2)))/3150))
176+
177+
E_f0, E_f1, E_f2 = self.get_means()
178+
cov = self.get_covariance_matrix()
179+
E_f0_sq = cov[0, 0]+E_f0**2
180+
E_f1_sq = cov[0, 0]+E_f1**2
181+
E_f2_sq = cov[0, 0]+E_f2**2
182+
183+
E_f0_f1 = cov[0, 1]+E_f0*E_f1
184+
E_f0_f2 = cov[0, 2]+E_f0*E_f2
185+
E_f1_f2 = cov[1, 2]+E_f1*E_f2
186+
187+
Cmat = np.zeros((3, 3))
188+
Cmat[0, 1] = self._covariance_of_variances(
189+
nsamples, E_f0_sq_f1_sq, E_f0_sq, E_f1_sq, E_f1, E_f0_sq_f1,
190+
E_f0, E_f0_f1_sq, E_f0_f1)
191+
Cmat[1, 0] = Cmat[0, 1]
192+
193+
Cmat[0, 2] = self._covariance_of_variances(
194+
nsamples, E_f0_sq_f2_sq, E_f0_sq, E_f2_sq, E_f2, E_f0_sq_f2,
195+
E_f0, E_f0_f2_sq, E_f0_f2)
196+
Cmat[2, 0] = Cmat[0, 2]
197+
198+
Cmat[1, 2] = self._covariance_of_variances(
199+
nsamples, E_f1_sq_f2_sq, E_f1_sq, E_f2_sq, E_f2, E_f1_sq_f2,
200+
E_f1, E_f1_f2_sq, E_f1_f2)
201+
Cmat[2, 1] = Cmat[1, 2]
202+
203+
variances = np.diag(cov)
204+
kurtosis = self.get_kurtosis()
205+
C_mat_diag = (kurtosis-(nsamples-3)/(nsamples-1)*variances**2)/nsamples
206+
for ii in range(3):
207+
Cmat[ii, ii] = C_mat_diag[ii]
208+
209+
return Cmat
210+
137211

138212
class ShortColumnModelEnsemble(object):
139213
def __init__(self):

pyapprox/benchmarks/tests/test_benchmarks.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,20 +143,18 @@ def test_tunable_multifidelity_model(self):
143143
for m, mu in zip(g.fun.models, g.fun.get_means())])
144144
assert np.allclose(ref_kurtosis, kurtosis)
145145

146-
nsamples = 100
147-
variances = np.diag(g.fun.get_covariance_matrix())
148-
variance_est_variance = (
149-
kurtosis-(nsamples-3)/(nsamples-1)*variances**2)/nsamples
150-
print(variance_est_variance)
151-
146+
nsamples = 1000
152147
ntrials = int(1e4)
153148
estimator_vals = np.empty((ntrials, 3))
154149
for ii in range(ntrials):
155150
samples = g.variable.rvs(nsamples)
156151
estimator_vals[ii] = [m(samples).var() for m in g.fun.models]
157-
# print(estimator_vals.var(axis=0))
158-
assert np.allclose(estimator_vals.var(axis=0), variance_est_variance,
159-
rtol=3e-2)
152+
153+
C = g.fun.get_covariance_of_variances(nsamples)
154+
# print(np.cov(estimator_vals.T))
155+
# print(C)
156+
# print((C-np.cov(estimator_vals.T))/C)
157+
assert np.allclose(C, np.cov(estimator_vals.T), rtol=4e-2)
160158

161159

162160
if __name__ == "__main__":

0 commit comments

Comments
 (0)