Coverage for tests/test_gaussianProcess.py: 3%

1236 statements  

« prev     ^ index     » next       coverage.py v6.4, created at 2022-06-02 03:42 -0700

1# 

2# LSST Data Management System 

3# Copyright 2008, 2009, 2010 LSST Corporation. 

4# 

5# This product includes software developed by the 

6# LSST Project (http://www.lsst.org/). 

7# 

8# This program is free software: you can redistribute it and/or modify 

9# it under the terms of the GNU General Public License as published by 

10# the Free Software Foundation, either version 3 of the License, or 

11# (at your option) any later version. 

12# 

13# This program is distributed in the hope that it will be useful, 

14# but WITHOUT ANY WARRANTY; without even the implied warranty of 

15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

16# GNU General Public License for more details. 

17# 

18# You should have received a copy of the LSST License Statement and 

19# the GNU General Public License along with this program. If not, 

20# see < http://www.lsstcorp.org/LegalNotices/ > . 

21# 

22 

23import os 

24import unittest 

25 

26import numpy as np 

27 

28import lsst.utils.tests 

29import lsst.afw.math as afwMath 

30import lsst.pex.exceptions as pex 

31 

32testPath = os.path.abspath(os.path.dirname(__file__)) 

33 

34 

35class KdTreeGaussianProcessTestCase(lsst.utils.tests.TestCase): 

36 

37 def testKdTreeGetData(self): 

38 """ 

39 Test that KdTree.getData() throws exceptions when it should and returns 

40 the correct data when it should. 

41 """ 

42 rng = np.random.RandomState(112) 

43 data = rng.random_sample((10, 10)) 

44 kd = afwMath.KdTreeD() 

45 kd.Initialize(data) 

46 

47 # test that an exception is thrown if you ask for a point with 

48 # a negative index 

49 with self.assertRaises(RuntimeError) as context: 

50 kd.getData(-1, 0) 

51 self.assertIn("Asked for point that does not exist", 

52 context.exception.args[0]) 

53 

54 # test that an exception is thrown if you ask for a point beyond 

55 # the number of points stored in the tree 

56 with self.assertRaises(RuntimeError) as context: 

57 kd.getData(10, 0) 

58 self.assertIn("Asked for point that does not exist", 

59 context.exception.args[0]) 

60 

61 # test that an exception is thrown if you ask for dimensions that 

62 # don't exist 

63 with self.assertRaises(RuntimeError) as context: 

64 kd.getData(0, -1) 

65 self.assertIn("points of that many dimensions", 

66 context.exception.args[0]) 

67 

68 with self.assertRaises(RuntimeError) as context: 

69 kd.getData(0, 10) 

70 self.assertIn("points of that many dimensions", 

71 context.exception.args[0]) 

72 

73 # test that the correct values are returned when they should be 

74 for ix in range(10): 

75 for iy in range(10): 

76 self.assertAlmostEqual( 

77 data[ix][iy], kd.getData(ix, iy), places=10) 

78 

79 def testKdTreeGetDataVec(self): 

80 """ 

81 Test that KdTree.getData(int) throws exceptions when it should and returns 

82 the correct data when it should. 

83 """ 

84 rng = np.random.RandomState(112) 

85 data = rng.random_sample((10, 10)) 

86 kd = afwMath.KdTreeD() 

87 kd.Initialize(data) 

88 

89 # test that an exception is thrown if you ask for a point with 

90 # a negative index 

91 with self.assertRaises(RuntimeError) as context: 

92 kd.getData(-1) 

93 self.assertIn("point that does not exist", 

94 context.exception.args[0]) 

95 

96 # test that an exception is thrown if you ask for a point beyond 

97 # the number of points stored in the tree 

98 with self.assertRaises(RuntimeError) as context: 

99 kd.getData(10) 

100 self.assertIn("point that does not exist", 

101 context.exception.args[0]) 

102 

103 # test that the correct values are returned when they should be 

104 for ix in range(10): 

105 vv = kd.getData(ix) 

106 for iy in range(10): 

107 self.assertAlmostEqual(data[ix][iy], vv[iy], places=10) 

108 

109 def testKdTreeNeighborExceptions(self): 

110 """ 

111 This test will test that KdTree throws exceptions when you ask it for 

112 nonsensical number of nearest neighbors. 

113 """ 

114 rng = np.random.RandomState(112) 

115 data = rng.random_sample((10, 10)) 

116 kd = afwMath.KdTreeD() 

117 kd.Initialize(data) 

118 pt = rng.random_sample(10).astype(float) 

119 neighdex = np.zeros((5), dtype=np.int32) 

120 distances = np.zeros((5), dtype=float) 

121 

122 # ask for a negative number of neighbors 

123 with self.assertRaises(RuntimeError) as context: 

124 kd.findNeighbors(neighdex, distances, pt, -2) 

125 self.assertIn("zero or a negative number of neighbors", 

126 context.exception.args[0]) 

127 

128 # ask for zero neighbors 

129 with self.assertRaises(RuntimeError) as context: 

130 kd.findNeighbors(neighdex, distances, pt, 0) 

131 self.assertIn("zero or a negative number of neighbors", 

132 context.exception.args[0]) 

133 

134 # ask for more neighbors than you have data 

135 with self.assertRaises(RuntimeError) as context: 

136 kd.findNeighbors(neighdex, distances, pt, 11) 

137 self.assertIn("more neighbors than kd tree contains", 

138 context.exception.args[0]) 

139 

140 # try sending neighdex of wrong size 

141 neighdex_bad = np.zeros((1), dtype=np.int32) 

142 with self.assertRaises(RuntimeError) as context: 

143 kd.findNeighbors(neighdex_bad, distances, pt, 5) 

144 self.assertIn("Size of neighdex", 

145 context.exception.args[0]) 

146 

147 # try sending distances array of wrong size 

148 distances_bad = np.zeros((1), dtype=float) 

149 with self.assertRaises(RuntimeError) as context: 

150 kd.findNeighbors(neighdex, distances_bad, pt, 5) 

151 self.assertIn("Size of dd", 

152 context.exception.args[0]) 

153 

154 # run something that works 

155 kd.findNeighbors(neighdex, distances, pt, 5) 

156 

157 def testKdTree(self): 

158 """ 

159 This test will test the construction of KdTree in the pathological case 

160 where many of the input data points are identical. 

161 """ 

162 pp = 100 

163 dd = 5 

164 data = np.zeros((pp, dd), dtype=float) 

165 tol = 1.0e-10 

166 

167 with open(os.path.join(testPath, "data", "kd_test_data.sav"), "r") as f: 

168 ff = f.readlines() 

169 

170 for i in range(len(ff)): 

171 s = ff[i].split() 

172 for j in range(dd): 

173 data[i][j] = float(s[j]) 

174 

175 kd = afwMath.KdTreeD() 

176 

177 kd.Initialize(data) 

178 

179 kds = afwMath.KdTreeD() 

180 

181 kds.Initialize(data) 

182 

183 kds.removePoint(2) 

184 

185 worstErr = -1.0 

186 for i in range(100): 

187 if i > 2: 

188 dd = 0.0 

189 for j in range(5): 

190 dd = dd+(kd.getData(i, j)-kds.getData(i-1, j)) * \ 

191 (kd.getData(i, j)-kds.getData(i-1, j)) 

192 if dd > worstErr: 

193 worstErr = dd 

194 self.assertLess(worstErr, tol) 

195 

196 kd.removePoint(2) 

197 

198 kds.removePoint(10) 

199 

200 for i in range(99): 

201 if i > 10: 

202 dd = 0.0 

203 for j in range(5): 

204 dd = dd+(kd.getData(i, j)-kds.getData(i-1, j)) * \ 

205 (kd.getData(i, j)-kds.getData(i-1, j)) 

206 if dd > worstErr: 

207 worstErr = dd 

208 self.assertLess(worstErr, tol) 

209 

210 kd.removePoint(10) 

211 

212 kds.removePoint(21) 

213 

214 for i in range(98): 

215 if i > 21: 

216 dd = 0.0 

217 for j in range(5): 

218 dd = dd+(kd.getData(i, j)-kds.getData(i-1, j)) * \ 

219 (kd.getData(i, j)-kds.getData(i-1, j)) 

220 if dd > worstErr: 

221 worstErr = dd 

222 self.assertLess(worstErr, tol) 

223 print("\nworst distance error in kdTest ", worstErr, "\n") 

224 

225 def testKdTreeNeighbors(self): 

226 """ 

227 Test that KdTree.findNeighbors() does find the nearest neighbors 

228 """ 

229 rng = np.random.RandomState(112) 

230 data = rng.random_sample((10, 10)) 

231 kd = afwMath.KdTreeD() 

232 kd.Initialize(data) 

233 pt = rng.random_sample(10).astype(float) 

234 neighdex = np.zeros((5), dtype=np.int32) 

235 distances = np.zeros((5), dtype=float) 

236 kd.findNeighbors(neighdex, distances, pt, 5) 

237 

238 # check that the distances to the nearest neighbors are 

239 # correctly reported 

240 for ix in range(len(neighdex)): 

241 dd_true = np.sqrt(np.power(pt - data[neighdex[ix]], 2).sum()) 

242 self.assertAlmostEqual(dd_true, distances[ix], places=10) 

243 

244 # check that the distances are returned in ascending order 

245 for ix in range(len(distances)-1): 

246 self.assertGreaterEqual(distances[ix+1], distances[ix]) 

247 

248 # check that the actual nearest neighbors were found 

249 dd_true = np.sqrt(np.power(pt-data, 2).sum(axis=1)) 

250 sorted_dexes = np.argsort(dd_true) 

251 for ix in range(len(neighdex)): 

252 self.assertEqual(neighdex[ix], sorted_dexes[ix]) 

253 

254 def testKdTreeAddPoint(self): 

255 """ 

256 Test the behavior of KdTree.addPoint 

257 """ 

258 data = np.array([[1.0, 0.0, 2.0], [1.1, 2.5, 0.0], [4.5, 6.1, 0.0]]) 

259 kd = afwMath.KdTreeD() 

260 kd.Initialize(data) 

261 

262 # test that, if you try to add an improperly-sized point, an exception 

263 # is thrown 

264 with self.assertRaises(RuntimeError) as context: 

265 kd.addPoint(np.array([1.1]*2)) 

266 self.assertIn("incorrect dimensionality", 

267 context.exception.args[0]) 

268 

269 with self.assertRaises(RuntimeError) as context: 

270 kd.addPoint(np.array([1.1]*4)) 

271 self.assertIn("incorrect dimensionality", 

272 context.exception.args[0]) 

273 

274 # test that adding a correctly sized-point works 

275 # (i.e. that the new point is added to the tree's data) 

276 kd.addPoint(np.array([1.1]*3)) 

277 

278 self.assertEqual(kd.getNPoints(), 4) 

279 for ix in range(3): 

280 for iy in range(3): 

281 self.assertAlmostEqual( 

282 data[ix][iy], kd.getData(ix, iy), places=10) 

283 

284 for ix in range(3): 

285 self.assertAlmostEqual(kd.getData(3, ix), 1.1, places=10) 

286 

287 # check that the new point is accounted for in findNeighbors() 

288 neighdex = np.ones(2, dtype=np.int32) 

289 distances = np.ones(2, dtype=float) 

290 vv = np.array([1.2]*3) 

291 kd.findNeighbors(neighdex, distances, vv, 2) 

292 self.assertEqual(neighdex[0], 3) 

293 self.assertEqual(neighdex[1], 0) 

294 

295 def testKdTreeRemovePoint(self): 

296 """ 

297 Test the behavior of KdTree.removePoint() 

298 """ 

299 data = np.array([[1.5, 1.5, 1.5], [2.0, 2.0, 2.0], 

300 [4.0, 4.0, 4.0], [3.0, 3.0, 3.0]]) 

301 kd = afwMath.KdTreeD() 

302 kd.Initialize(data) 

303 self.assertEqual(kd.getNPoints(), 4) 

304 

305 # test that an exception is raised if you try to remove a non-existent 

306 # point 

307 with self.assertRaises(RuntimeError) as context: 

308 kd.removePoint(-1) 

309 self.assertIn("point that doesn't exist", 

310 context.exception.args[0]) 

311 

312 with self.assertRaises(RuntimeError) as context: 

313 kd.removePoint(4) 

314 self.assertIn("point that doesn't exist", 

315 context.exception.args[0]) 

316 

317 # test that things work correctly when you do remove a point 

318 kd.removePoint(1) 

319 self.assertEqual(kd.getNPoints(), 3) 

320 for ix in range(3): 

321 self.assertAlmostEqual(kd.getData(0, ix), 1.5, places=10) 

322 self.assertAlmostEqual(kd.getData(1, ix), 4.0, places=10) 

323 self.assertAlmostEqual(kd.getData(2, ix), 3.0, places=10) 

324 

325 neighdex = np.zeros(2, dtype=np.int32) 

326 distances = np.zeros(2, dtype=float) 

327 kd.findNeighbors(neighdex, distances, np.array([2.0, 2.0, 2.0]), 2) 

328 self.assertEqual(neighdex[0], 0) 

329 self.assertEqual(neighdex[1], 2) 

330 

331 # test that an exception is raised when you try to remove the last 

332 # point 

333 kd.removePoint(0) 

334 kd.removePoint(0) 

335 with self.assertRaises(RuntimeError) as context: 

336 kd.removePoint(0) 

337 self.assertIn("There is only one point", 

338 context.exception.args[0]) 

339 

340 def testKdTreeGetTreeNode(self): 

341 """ 

342 Test that KdTree.GetTreeNode raises exceptions if you give it bad inputs 

343 """ 

344 data = np.array([[1.5, 1.5, 1.5], [2.0, 2.0, 2.0], 

345 [4.0, 4.0, 4.0], [3.0, 3.0, 3.0]]) 

346 kd = afwMath.KdTreeD() 

347 kd.Initialize(data) 

348 

349 vv = np.ones(4, dtype=np.int32) 

350 vv_small = np.ones(1, dtype=np.int32) 

351 vv_large = np.ones(5, dtype=np.int32) 

352 

353 with self.assertRaises(RuntimeError) as context: 

354 kd.getTreeNode(vv_small, 0) 

355 self.assertIn("Need to pass a 4-element", 

356 context.exception.args[0]) 

357 

358 with self.assertRaises(RuntimeError) as context: 

359 kd.getTreeNode(vv_large, 0) 

360 self.assertIn("Need to pass a 4-element", 

361 context.exception.args[0]) 

362 

363 with self.assertRaises(RuntimeError) as context: 

364 kd.getTreeNode(vv, -1) 

365 self.assertIn("point that does not exist", 

366 context.exception.args[0]) 

367 

368 with self.assertRaises(RuntimeError) as context: 

369 kd.getTreeNode(vv, 4) 

370 self.assertIn("point that does not exist", 

371 context.exception.args[0]) 

372 

373 # make sure that a call with good inputs passes 

374 kd.getTreeNode(vv, 0) 

375 

376 

377class GaussianProcessTestCase(lsst.utils.tests.TestCase): 

378 

379 def testConstructorExceptions(self): 

380 """ 

381 Test that exceptions are raised when constructor is given 

382 improper inputs 

383 """ 

384 rng = np.random.RandomState(22) 

385 

386 # when you pass a different number of data points and function 

387 # values in 

388 data = rng.random_sample((10, 4)) 

389 fn_values = rng.random_sample(11) 

390 with self.assertRaises(RuntimeError) as context: 

391 afwMath.GaussianProcessD( 

392 data, fn_values, afwMath.SquaredExpCovariogramD()) 

393 self.assertIn("did not pass in the same number", 

394 context.exception.args[0]) 

395 

396 max_val = np.ones(4) 

397 min_val = np.ones(4) 

398 with self.assertRaises(RuntimeError) as context: 

399 afwMath.GaussianProcessD(data, min_val, max_val, fn_values, 

400 afwMath.SquaredExpCovariogramD()) 

401 self.assertIn("did not pass in the same number", 

402 context.exception.args[0]) 

403 

404 many_fn_values = rng.random_sample((11, 3)) 

405 with self.assertRaises(RuntimeError) as context: 

406 afwMath.GaussianProcessD( 

407 data, many_fn_values, afwMath.SquaredExpCovariogramD()) 

408 self.assertIn("did not pass in the same number", 

409 context.exception.args[0]) 

410 

411 with self.assertRaises(RuntimeError) as context: 

412 afwMath.GaussianProcessD(data, min_val, max_val, many_fn_values, 

413 afwMath.SquaredExpCovariogramD()) 

414 self.assertIn("did not pass in the same number", 

415 context.exception.args[0]) 

416 

417 fn_values = rng.random_sample(data.shape[0]) 

418 many_fn_values = rng.random_sample((10, 3)) 

419 

420 # when you pass in improperly sized min and max val arrays 

421 bad_max_val = np.ones(3) 

422 bad_min_val = np.zeros(3) 

423 with self.assertRaises(RuntimeError) as context: 

424 afwMath.GaussianProcessD(data, bad_min_val, max_val, 

425 fn_values, afwMath.SquaredExpCovariogramD()) 

426 self.assertIn("min/max values have different dimensionality", 

427 context.exception.args[0]) 

428 

429 with self.assertRaises(RuntimeError) as context: 

430 afwMath.GaussianProcessD(data, min_val, bad_max_val, 

431 fn_values, afwMath.SquaredExpCovariogramD()) 

432 self.assertIn("min/max values have different dimensionality", 

433 context.exception.args[0]) 

434 

435 with self.assertRaises(RuntimeError) as context: 

436 afwMath.GaussianProcessD(data, bad_min_val, max_val, 

437 many_fn_values, afwMath.SquaredExpCovariogramD()) 

438 self.assertIn("min/max values have different dimensionality", 

439 context.exception.args[0]) 

440 

441 with self.assertRaises(RuntimeError) as context: 

442 afwMath.GaussianProcessD(data, min_val, bad_max_val, 

443 many_fn_values, afwMath.SquaredExpCovariogramD()) 

444 self.assertIn("min/max values have different dimensionality", 

445 context.exception.args[0]) 

446 

447 # check that the constructor runs when it should 

448 afwMath.GaussianProcessD( 

449 data, fn_values, afwMath.SquaredExpCovariogramD()) 

450 

451 afwMath.GaussianProcessD(data, min_val, max_val, fn_values, 

452 afwMath.SquaredExpCovariogramD()) 

453 

454 afwMath.GaussianProcessD(data, many_fn_values, 

455 afwMath.SquaredExpCovariogramD()) 

456 

457 afwMath.GaussianProcessD(data, min_val, max_val, many_fn_values, 

458 afwMath.SquaredExpCovariogramD()) 

459 

460 def testGetDataExceptions(self): 

461 """ 

462 Test that getData() returns exceptions on bad input 

463 """ 

464 rng = np.random.RandomState(111) 

465 data = rng.random_sample((14, 3)) 

466 fn = rng.random_sample(14) 

467 gp = afwMath.GaussianProcessD( 

468 data, fn, afwMath.SquaredExpCovariogramD()) 

469 indices = np.array([0, 5, 7], dtype=np.int32) 

470 indices_bad = np.array([0, 5, 16], dtype=np.int32) 

471 fn_out_good = np.zeros(3) 

472 fn_out_bad = np.zeros(4) 

473 pts_out_good = np.zeros((3, 3)) 

474 pts_out_bad_ct = np.zeros((5, 3)) 

475 pts_out_bad_dim = np.zeros((3, 7)) 

476 

477 # check that an exception is raised if we pass in an invalid 

478 # index 

479 with self.assertRaises(RuntimeError) as context: 

480 gp.getData(pts_out_good, fn_out_good, indices_bad) 

481 self.assertIn("point that does not exist", 

482 context.exception.args[0]) 

483 

484 # check that an exception is raised if pts_out asks for 

485 # the wrong number of points 

486 with self.assertRaises(RuntimeError) as context: 

487 gp.getData(pts_out_bad_ct, fn_out_good, indices) 

488 self.assertIn("enough room in your pts array", 

489 context.exception.args[0]) 

490 

491 # check that an exception is raised if pts_out expects 

492 # points of the wrong dimensionality 

493 with self.assertRaises(RuntimeError) as context: 

494 gp.getData(pts_out_bad_dim, fn_out_good, indices) 

495 self.assertIn("points of the wrong dimensionality", 

496 context.exception.args[0]) 

497 

498 # check that an exception is raised if fn_out expects 

499 # the wrong number of points 

500 with self.assertRaises(RuntimeError) as context: 

501 gp.getData(pts_out_good, fn_out_bad, indices) 

502 self.assertIn("room in your function value array", 

503 context.exception.args[0]) 

504 

505 # check that getData runs safely when given good input 

506 gp.getData(pts_out_good, fn_out_good, indices) 

507 

508 fn_many = rng.random_sample((14, 5)) 

509 gp_many = afwMath.GaussianProcessD( 

510 data, fn_many, afwMath.SquaredExpCovariogramD()) 

511 

512 # check that a GaussianProcess with many functions throws an 

513 # exception when you try to run getData designed for just one 

514 # function 

515 with self.assertRaises(RuntimeError) as context: 

516 gp_many.getData(pts_out_good, fn_out_good, indices) 

517 self.assertIn("enough room for all of the functions", 

518 context.exception.args[0]) 

519 

520 # now test on a GaussianProcess with many functions 

521 

522 fn_out_good = np.zeros((3, 5)) 

523 fn_out_bad_ct = np.zeros((4, 5)) 

524 fn_out_bad_fn = np.zeros((3, 6)) 

525 

526 # check that an exception is raised when pts_out expects 

527 # the wrong number of points 

528 with self.assertRaises(RuntimeError) as context: 

529 gp_many.getData(pts_out_bad_ct, fn_out_good, indices) 

530 self.assertIn("room in your pts array", 

531 context.exception.args[0]) 

532 

533 # check that an exception is raised when pts_out expects 

534 # pts of the wrong dimensionality 

535 with self.assertRaises(RuntimeError) as context: 

536 gp_many.getData(pts_out_bad_dim, fn_out_good, indices) 

537 self.assertIn("points of the wrong dimensionality", 

538 context.exception.args[0]) 

539 

540 # check that an exception is raised when fn_out expects the 

541 # wrong number of pts 

542 with self.assertRaises(RuntimeError) as context: 

543 gp_many.getData(pts_out_good, fn_out_bad_ct, indices) 

544 self.assertIn("room in your function value array", 

545 context.exception.args[0]) 

546 

547 # check that an exception is raised when fn_out expects the 

548 # wrong number of functions 

549 with self.assertRaises(RuntimeError) as context: 

550 gp_many.getData(pts_out_good, fn_out_bad_fn, indices) 

551 self.assertIn("enough room for all of the functions", 

552 context.exception.args[0]) 

553 

554 # check that an exception is raised when one of the indices is 

555 # invalid 

556 with self.assertRaises(RuntimeError) as context: 

557 gp_many.getData(pts_out_good, fn_out_good, indices_bad) 

558 self.assertIn("point that does not exist", 

559 context.exception.args[0]) 

560 

561 # check that getData runs safely when given good input 

562 gp_many.getData(pts_out_good, fn_out_good, indices) 

563 

564 def testGetData(self): 

565 """ 

566 Test that getData actually returns what you expect 

567 """ 

568 rng = np.random.RandomState(131) 

569 data = rng.random_sample((14, 3)) 

570 fn = rng.random_sample(14) 

571 gp = afwMath.GaussianProcessD( 

572 data, fn, afwMath.SquaredExpCovariogramD()) 

573 pts_out = np.zeros((4, 3)) 

574 fn_out = np.zeros(4) 

575 indices = np.array([4, 1, 12, 8], dtype=np.int32) 

576 gp.getData(pts_out, fn_out, indices) 

577 

578 for ii in range(len(indices)): 

579 self.assertAlmostEqual(fn_out[ii], fn[indices[ii]], 10) 

580 for jj in range(3): 

581 self.assertAlmostEqual(pts_out[ii][jj], data[indices[ii]][jj]) 

582 

583 # now test with a max and min array 

584 max_arr = np.array([0.3]*3) 

585 min_arr = np.array([0.12]*3) 

586 gp = afwMath.GaussianProcessD(data, min_arr, max_arr, 

587 fn, afwMath.SquaredExpCovariogramD()) 

588 

589 gp.getData(pts_out, fn_out, indices) 

590 

591 for ii in range(len(indices)): 

592 self.assertAlmostEqual(fn_out[ii], fn[indices[ii]], 10) 

593 for jj in range(3): 

594 self.assertAlmostEqual(pts_out[ii][jj], data[indices[ii]][jj]) 

595 

596 # now test on a GaussianProcess with many functions 

597 fn_many = rng.random_sample((14, 6)) 

598 fn_out = np.zeros((4, 6)) 

599 gp = afwMath.GaussianProcessD( 

600 data, fn_many, afwMath.SquaredExpCovariogramD()) 

601 

602 gp.getData(pts_out, fn_out, indices) 

603 

604 for ii in range(len(indices)): 

605 for jj in range(6): 

606 self.assertAlmostEqual( 

607 fn_out[ii][jj], fn_many[indices[ii]][jj], 10) 

608 for jj in range(3): 

609 self.assertAlmostEqual(pts_out[ii][jj], data[indices[ii]][jj]) 

610 

611 # with min and max array 

612 gp = afwMath.GaussianProcessD(data, min_arr, max_arr, 

613 fn_many, afwMath.SquaredExpCovariogramD()) 

614 

615 gp.getData(pts_out, fn_out, indices) 

616 

617 for ii in range(len(indices)): 

618 for jj in range(6): 

619 self.assertAlmostEqual( 

620 fn_out[ii][jj], fn_many[indices[ii]][jj], 10) 

621 for jj in range(3): 

622 self.assertAlmostEqual(pts_out[ii][jj], data[indices[ii]][jj]) 

623 

624 def testInterpolateExceptions(self): 

625 """ 

626 Test that interpolate() raises exceptions when given improper 

627 arguments 

628 """ 

629 rng = np.random.RandomState(88) 

630 data = rng.random_sample((13, 5)) 

631 fn = rng.random_sample(13) 

632 many_fn = rng.random_sample((13, 3)) 

633 gg = afwMath.GaussianProcessD( 

634 data, fn, afwMath.SquaredExpCovariogramD()) 

635 gg_many = afwMath.GaussianProcessD( 

636 data, many_fn, afwMath.SquaredExpCovariogramD()) 

637 

638 var = np.zeros(1) 

639 

640 many_var = np.zeros(3) 

641 many_mu = np.zeros(3) 

642 

643 # test that an exception is raised if you try to interpolate at 

644 # a point with an incorrect number of dimensions 

645 bad_pt = rng.random_sample(3) 

646 with self.assertRaises(RuntimeError) as context: 

647 gg.interpolate(var, bad_pt, 5) 

648 self.assertIn("point with different dimensionality", 

649 context.exception.args[0]) 

650 

651 with self.assertRaises(RuntimeError) as context: 

652 gg_many.interpolate(many_mu, many_var, bad_pt, 5) 

653 self.assertIn("point with different dimensionality", 

654 context.exception.args[0]) 

655 

656 good_pt = rng.random_sample(5) 

657 

658 # test that an exception is raised if you try to ask for an improper 

659 # number of nearest neighbors when interpolating 

660 with self.assertRaises(RuntimeError) as context: 

661 gg.interpolate(var, good_pt, 0) 

662 self.assertIn("zero or negative number of neighbors", 

663 context.exception.args[0]) 

664 

665 with self.assertRaises(RuntimeError) as context: 

666 gg.interpolate(var, good_pt, -1) 

667 self.assertIn("zero or negative number of neighbors", 

668 context.exception.args[0]) 

669 

670 with self.assertRaises(RuntimeError) as context: 

671 gg.interpolate(var, good_pt, 14) 

672 self.assertIn("more neighbors than you have", 

673 context.exception.args[0]) 

674 

675 with self.assertRaises(RuntimeError) as context: 

676 gg_many.interpolate(many_mu, many_var, good_pt, 0) 

677 self.assertIn("zero or negative number of neighbors", 

678 context.exception.args[0]) 

679 

680 with self.assertRaises(RuntimeError) as context: 

681 gg_many.interpolate(many_mu, many_var, good_pt, -1) 

682 self.assertIn("zero or negative number of neighbors", 

683 context.exception.args[0]) 

684 

685 with self.assertRaises(RuntimeError) as context: 

686 gg_many.interpolate(many_mu, many_var, good_pt, 14) 

687 self.assertIn("more neighbors than you have", 

688 context.exception.args[0]) 

689 

690 # make sure that a Gaussian Process interpolating many functions 

691 # does not let you call the interpolate() method that returns 

692 # a scalar 

693 with self.assertRaises(RuntimeError) as context: 

694 gg_many.interpolate(many_var, good_pt, 4) 

695 self.assertIn("You need to call the version", 

696 context.exception.args[0]) 

697 

698 # test that the many-function interpolate throws an exception 

699 # on improperly-sized mu and variance arrays 

700 bad_var = np.zeros(6) 

701 bad_mu = np.zeros(6) 

702 

703 with self.assertRaises(RuntimeError) as context: 

704 gg_many.interpolate(bad_mu, many_var, good_pt, 5) 

705 self.assertIn("mu and/or var arrays are improperly sized", 

706 context.exception.args[0]) 

707 

708 with self.assertRaises(RuntimeError) as context: 

709 gg_many.interpolate(many_mu, bad_var, good_pt, 5) 

710 self.assertIn("mu and/or var arrays are improperly sized", 

711 context.exception.args[0]) 

712 

713 # if you try to pass a variance array with len != 1 to 

714 # the single value interpolate() 

715 with self.assertRaises(RuntimeError) as context: 

716 gg.interpolate(many_var, good_pt, 5) 

717 self.assertIn("variance array is the incorrect size", 

718 context.exception.args[0]) 

719 

720 gg.interpolate(var, good_pt, 5) 

721 gg_many.interpolate(many_mu, many_var, good_pt, 5) 

722 

723 def testSelfInterpolateExceptions(self): 

724 """ 

725 Test that selfInterpolate raises exceptions on bad arguments. 

726 """ 

727 rng = np.random.RandomState(632) 

728 data = rng.random_sample((15, 4)) 

729 fn = rng.random_sample(15) 

730 gg = afwMath.GaussianProcessD( 

731 data, fn, afwMath.SquaredExpCovariogramD()) 

732 many_fn = rng.random_sample((15, 3)) 

733 gg_many = afwMath.GaussianProcessD( 

734 data, many_fn, afwMath.SquaredExpCovariogramD()) 

735 

736 var_good = np.zeros(3) 

737 mu_good = np.zeros(3) 

738 

739 var_bad = np.zeros(5) 

740 mu_bad = np.zeros(5) 

741 

742 # test that an exception is raised when you try to use scalar 

743 # selfInterpolation() on a many-function GaussianProcess 

744 with self.assertRaises(RuntimeError) as context: 

745 gg_many.selfInterpolate(var_good, 11, 6) 

746 self.assertIn("that accepts mu and variance array", 

747 context.exception.args[0]) 

748 

749 # test that an exception is raised when you pass a var_array that is 

750 # too large into a scalar GaussianProcess 

751 with self.assertRaises(RuntimeError) as context: 

752 gg.selfInterpolate(var_good, 11, 6) 

753 self.assertIn("variance array is the incorrect size", 

754 context.exception.args[0]) 

755 

756 # test that an exception is thrown when you pass in improperly-sized 

757 # mu and/or var arrays 

758 with self.assertRaises(RuntimeError) as context: 

759 gg_many.selfInterpolate(mu_good, var_bad, 11, 6) 

760 self.assertIn("mu and/or var arrays are improperly sized", 

761 context.exception.args[0]) 

762 

763 with self.assertRaises(RuntimeError) as context: 

764 gg_many.selfInterpolate(mu_bad, var_good, 11, 6) 

765 self.assertIn("mu and/or var arrays are improperly sized", 

766 context.exception.args[0]) 

767 

768 # make surethat selfInterpolate runs when it should 

769 gg_many.selfInterpolate(mu_good, var_good, 11, 6) 

770 var_one = np.zeros(1) 

771 gg.selfInterpolate(var_one, 11, 6) 

772 

773 def testBatchInterpolateExceptions(self): 

774 """ 

775 Test that batchInterpolate() throws exceptions on bad input 

776 """ 

777 rng = np.random.RandomState(88) 

778 rng = np.random.RandomState(632) 

779 data = rng.random_sample((15, 4)) 

780 fn = rng.random_sample(15) 

781 gg = afwMath.GaussianProcessD( 

782 data, fn, afwMath.SquaredExpCovariogramD()) 

783 

784 pts_good = rng.random_sample((11, 4)) 

785 pts_bad = rng.random_sample((11, 3)) 

786 mu_good = np.zeros(11) 

787 mu_bad = np.zeros(9) 

788 var_good = np.zeros(11) 

789 var_bad = np.zeros(9) 

790 

791 # test for exception on points of incorrect size 

792 with self.assertRaises(RuntimeError) as context: 

793 gg.batchInterpolate(mu_good, var_good, pts_bad) 

794 self.assertIn("wrong dimensionality", 

795 context.exception.args[0]) 

796 

797 with self.assertRaises(RuntimeError) as context: 

798 gg.batchInterpolate(mu_good, pts_bad) 

799 self.assertIn("wrong dimensionality", 

800 context.exception.args[0]) 

801 

802 # test for exception on output arrays of incorrect size 

803 with self.assertRaises(RuntimeError) as context: 

804 gg.batchInterpolate(mu_bad, var_good, pts_good) 

805 self.assertIn("do not have room for all of the points", 

806 context.exception.args[0]) 

807 

808 with self.assertRaises(RuntimeError) as context: 

809 gg.batchInterpolate(mu_bad, pts_good) 

810 self.assertIn("does not have enough room for all of the points", 

811 context.exception.args[0]) 

812 

813 with self.assertRaises(RuntimeError) as context: 

814 gg.batchInterpolate(mu_good, var_bad, pts_good) 

815 self.assertIn("do not have room", 

816 context.exception.args[0]) 

817 

818 # test that it runs properly with good inputs 

819 gg.batchInterpolate(mu_good, var_good, pts_good) 

820 gg.batchInterpolate(mu_good, pts_good) 

821 

822 fn_many = rng.random_sample((15, 6)) 

823 gg_many = afwMath.GaussianProcessD( 

824 data, fn_many, afwMath.SquaredExpCovariogramD()) 

825 

826 # test that a GaussianProcess on many functions raises an exception 

827 # when you call batchInterpolate with output arrays that only have 

828 # room for one function 

829 with self.assertRaises(RuntimeError) as context: 

830 gg_many.batchInterpolate(mu_good, var_good, pts_good) 

831 self.assertIn("do not have room for all of the functions", 

832 context.exception.args[0]) 

833 

834 with self.assertRaises(RuntimeError) as context: 

835 gg_many.batchInterpolate(mu_good, pts_good) 

836 self.assertIn("does not have enough room for all of the functions", 

837 context.exception.args[0]) 

838 

839 mu_good = np.zeros((11, 6)) 

840 mu_bad_fn = np.zeros((11, 5)) 

841 mu_bad_pts = np.zeros((10, 6)) 

842 var_good = np.zeros((11, 6)) 

843 var_bad_fn = np.zeros((11, 5)) 

844 var_bad_pts = np.zeros((10, 6)) 

845 

846 # test that a Gaussian Process on many functions raises an exception 

847 # when you try to interpolate on points of the wrong dimensionality 

848 with self.assertRaises(RuntimeError) as context: 

849 gg_many.batchInterpolate(mu_good, var_good, pts_bad) 

850 self.assertIn("wrong dimensionality", 

851 context.exception.args[0]) 

852 

853 with self.assertRaises(RuntimeError) as context: 

854 gg_many.batchInterpolate(mu_good, pts_bad) 

855 self.assertIn("do not have the correct dimensionality", 

856 context.exception.args[0]) 

857 

858 # test that a Gaussian Process on many functions rases an exception 

859 # when the output arrays are of the wrong size 

860 with self.assertRaises(RuntimeError) as context: 

861 gg_many.batchInterpolate(mu_bad_fn, var_good, pts_good) 

862 self.assertIn("do not have room for all of the functions", 

863 context.exception.args[0]) 

864 

865 with self.assertRaises(RuntimeError) as context: 

866 gg_many.batchInterpolate(mu_bad_pts, var_good, pts_good) 

867 self.assertIn("do not have room for all of the points", 

868 context.exception.args[0]) 

869 

870 with self.assertRaises(RuntimeError) as context: 

871 gg_many.batchInterpolate(mu_bad_pts, pts_good) 

872 self.assertIn("does not have enough room for all of the points", 

873 context.exception.args[0]) 

874 

875 with self.assertRaises(RuntimeError) as context: 

876 gg_many.batchInterpolate(mu_bad_fn, pts_good) 

877 self.assertIn("does not have enough room for all of the functions", 

878 context.exception.args[0]) 

879 

880 with self.assertRaises(RuntimeError) as context: 

881 gg_many.batchInterpolate(mu_good, var_bad_fn, pts_good) 

882 self.assertIn("do not have room for all of the functions", 

883 context.exception.args[0]) 

884 

885 with self.assertRaises(RuntimeError) as context: 

886 gg_many.batchInterpolate(mu_good, var_bad_pts, pts_good) 

887 self.assertIn("do not have room for all of the points", 

888 context.exception.args[0]) 

889 

890 # check that a Gaussian Process on many functions runs properly 

891 # when given good inputs 

892 gg_many.batchInterpolate(mu_good, var_good, pts_good) 

893 gg_many.batchInterpolate(mu_good, pts_good) 

894 

895 def testTooManyNeighbors(self): 

896 """ 

897 Test that GaussianProcess checks if too many neighbours are requested 

898 """ 

899 nData = 100 # number of data points 

900 dimen = 10 # dimension of each point 

901 data = np.zeros((nData, dimen)) 

902 fn = np.zeros(nData) 

903 gg = afwMath.GaussianProcessD( 

904 data, fn, afwMath.SquaredExpCovariogramD()) 

905 test = np.zeros(dimen) 

906 sigma = np.empty(1) 

907 mu_arr = np.empty(1) 

908 

909 with self.assertRaises(pex.Exception) as context: 

910 gg.interpolate(sigma, test, 2*nData) 

911 self.assertIn("more neighbors than", 

912 context.exception.args[0]) 

913 

914 with self.assertRaises(pex.Exception) as context: 

915 gg.interpolate(sigma, test, -5) 

916 self.assertIn("zero or negative number of neighbors", 

917 context.exception.args[0]) 

918 

919 with self.assertRaises(pex.Exception) as context: 

920 gg.selfInterpolate(sigma, 0, 2*nData) 

921 self.assertIn("more neighbors than", 

922 context.exception.args[0]) 

923 

924 with self.assertRaises(pex.Exception) as context: 

925 gg.selfInterpolate(sigma, 0, -5) 

926 self.assertIn("zero or negative number of neighbors", 

927 context.exception.args[0]) 

928 

929 with self.assertRaises(pex.Exception) as context: 

930 gg.selfInterpolate(sigma, -1, nData-1) 

931 self.assertIn("point that does not exist", 

932 context.exception.args[0]) 

933 

934 with self.assertRaises(pex.Exception) as context: 

935 gg.selfInterpolate(sigma, nData, nData-1) 

936 self.assertIn("point that does not exist", 

937 context.exception.args[0]) 

938 

939 with self.assertRaises(RuntimeError) as context: 

940 gg.interpolate(mu_arr, sigma, 2*nData) 

941 self.assertIn("more neighbors than", 

942 context.exception.args[0]) 

943 

944 with self.assertRaises(pex.Exception) as context: 

945 gg.interpolate(mu_arr, sigma, 2*nData) 

946 self.assertIn("more neighbors than", 

947 context.exception.args[0]) 

948 

949 with self.assertRaises(pex.Exception) as context: 

950 gg.interpolate(mu_arr, sigma, -5) 

951 self.assertIn("zero or negative number of neighbors", 

952 context.exception.args[0]) 

953 

954 def testInterpolate(self): 

955 """ 

956 This will test GaussianProcess.interpolate using both the squared 

957 exponential covariogram and the neural network covariogram on data 

958 that was generated with known answers. 

959 

960 The test will check that the code returns the correct values of both 

961 mu (interpolated function value) and sig2 (the variance) 

962 

963 This test uses the GaussianProcess constructor that does not normalize 

964 coordinate values with minima and maxima. 

965 """ 

966 

967 pp = 2000 # number of data points 

968 dd = 10 # number of dimensions 

969 kk = 15 # number of nearest neighbors being used 

970 tol = 1.0e-3 # the largest relative error that will be tolerated 

971 

972 data = np.zeros((pp, dd), dtype=float) # input data points 

973 fn = np.zeros((pp), dtype=float) # input function values 

974 test = np.zeros((dd), dtype=float) # query points 

975 sigma = np.zeros((1), dtype=float) # variance 

976 

977 xx = afwMath.SquaredExpCovariogramD() 

978 xx.setEllSquared(100.0) 

979 

980 # read in the input data 

981 with open(os.path.join(testPath, "data", "gp_exp_covar_data.sav"), "r") as f: 

982 ff = f.readlines() 

983 

984 for i in range(len(ff)): 

985 s = ff[i].split() 

986 fn[i] = float(s[10]) 

987 for j in range(10): 

988 data[i][j] = float(s[j]) 

989 

990 # first try the squared exponential covariogram (the default) 

991 try: 

992 gg = afwMath.GaussianProcessD(data, fn, xx) 

993 except pex.Exception as e: 

994 print(e.what()) 

995 

996 gg.setLambda(0.001) 

997 

998 # now, read in the test points and their corresponding known solutions 

999 with open(os.path.join(testPath, "data", "gp_exp_covar_solutions.sav"), "r") as f: 

1000 ff = f.readlines() 

1001 

1002 worstMuErr = -1.0 # keep track of the worst fractional error in mu 

1003 worstSigErr = -1.0 # keep track of the worst fractional error in the variance 

1004 

1005 for z in range(len(ff)): 

1006 s = ff[z].split() # s will store the zth line of the solution file 

1007 for i in range(dd): 

1008 test[i] = float(s[i]) # read in the test point coordinates 

1009 

1010 mushld = float(s[dd + kk]) # read in what mu should be 

1011 # read in what the variance should be 

1012 sigshld = float(s[dd + kk + 1]) 

1013 

1014 mu = gg.interpolate(sigma, test, kk) 

1015 

1016 err = (mu - mushld) 

1017 if mushld != 0.0: 

1018 err = err/mushld 

1019 

1020 if err < 0.0: 

1021 err = -1.0 * err 

1022 if z == 0 or err > worstMuErr: 

1023 worstMuErr = err 

1024 

1025 err = (sigma[0] - sigshld) 

1026 if sigshld != 0.0: 

1027 err = err/sigshld 

1028 

1029 if err < 0.0: 

1030 err = -1.0 * err 

1031 if z == 0 or err > worstSigErr: 

1032 worstSigErr = err 

1033 

1034 print("\nThe errors for squared exponent covariogram\n") 

1035 print("worst mu error ", worstMuErr) 

1036 print("worst sig2 error ", worstSigErr) 

1037 

1038 self.assertLess(worstMuErr, tol) 

1039 self.assertLess(worstSigErr, tol) 

1040 

1041 # now try with the Neural Network covariogram 

1042 

1043 kk = 50 

1044 

1045 nn = afwMath.NeuralNetCovariogramD() 

1046 nn.setSigma0(1.23) 

1047 nn.setSigma1(0.452) 

1048 

1049 gg.setCovariogram(nn) 

1050 gg.setLambda(0.0045) 

1051 

1052 with open(os.path.join(testPath, "data", "gp_nn_solutions.sav"), "r") as f: 

1053 ff = f.readlines() 

1054 

1055 worstMuErr = -1.0 

1056 worstSigErr = -1.0 

1057 

1058 for z in range(len(ff)): 

1059 s = ff[z].split() 

1060 for i in range(dd): 

1061 test[i] = float(s[i]) 

1062 

1063 mushld = float(s[dd + kk]) 

1064 sigshld = float(s[dd + kk + 1]) 

1065 

1066 mu = gg.interpolate(sigma, test, kk) 

1067 

1068 err = (mu - mushld) 

1069 if mushld != 0.0: 

1070 err = err/mushld 

1071 

1072 if err < 0.0: 

1073 err = -1.0 * err 

1074 if z == 0 or err > worstMuErr: 

1075 worstMuErr = err 

1076 

1077 err = (sigma[0] - sigshld) 

1078 if sigshld != 0.0: 

1079 err = err/sigshld 

1080 

1081 if err < 0.0: 

1082 err = -1.0 * err 

1083 if z == 0 or err > worstSigErr: 

1084 worstSigErr = err 

1085 

1086 print("\nThe errors for neural net covariogram\n") 

1087 print("worst mu error ", worstMuErr) 

1088 print("worst sig2 error ", worstSigErr) 

1089 

1090 self.assertLess(worstMuErr, tol) 

1091 self.assertLess(worstSigErr, tol) 

1092 

1093 def testMinMax(self): 

1094 """ 

1095 This test will test GaussianProcess.interpolate using the constructor 

1096 that normalizes data point coordinates by minima and maxima. 

1097 

1098 It will only use the squared exponential covariogram (since testInterpolate() presumably 

1099 tested the performance of the neural network covariogram; this test is only concerned 

1100 with the alternate constructor) 

1101 

1102 This test proceeds largely like testInterpolate above 

1103 """ 

1104 pp = 2000 

1105 dd = 10 

1106 kk = 50 

1107 tol = 1.0e-4 

1108 data = np.zeros((pp, dd), dtype=float) 

1109 fn = np.zeros((pp), dtype=float) 

1110 test = np.zeros((dd), dtype=float) 

1111 sigma = np.zeros((1), dtype=float) 

1112 

1113 mins = np.zeros((dd), dtype=float) 

1114 maxs = np.zeros((dd), dtype=float) 

1115 

1116 nn = afwMath.NeuralNetCovariogramD() 

1117 nn.setSigma0(0.555) 

1118 nn.setSigma1(0.112) 

1119 

1120 with open(os.path.join(testPath, "data", "gp_exp_covar_data.sav"), "r") as f: 

1121 ff = f.readlines() 

1122 

1123 for i in range(len(ff)): 

1124 s = ff[i].split() 

1125 fn[i] = float(s[10]) 

1126 for j in range(10): 

1127 data[i][j] = float(s[j]) 

1128 

1129 for i in range(pp): 

1130 for j in range(dd): 

1131 if (i == 0) or (data[i][j] < mins[j]): 

1132 mins[j] = data[i][j] 

1133 if (i == 0) or (data[i][j] > maxs[j]): 

1134 maxs[j] = data[i][j] 

1135 

1136 mins[2] = 0.0 

1137 maxs[2] = 10.0 

1138 try: 

1139 gg = afwMath.GaussianProcessD(data, mins, maxs, fn, nn) 

1140 except pex.Exception as e: 

1141 print(e.what()) 

1142 

1143 gg.setLambda(0.0045) 

1144 

1145 with open(os.path.join(testPath, "data", "gp_minmax_solutions.sav"), "r") as f: 

1146 ff = f.readlines() 

1147 

1148 worstMuErr = -1.0 

1149 worstSigErr = -1.0 

1150 for z in range(len(ff)): 

1151 s = ff[z].split() 

1152 for i in range(dd): 

1153 test[i] = float(s[i]) 

1154 

1155 mushld = float(s[dd + kk]) 

1156 sigshld = float(s[dd + kk + 1]) 

1157 

1158 mu = gg.interpolate(sigma, test, kk) 

1159 

1160 err = (mu - mushld) 

1161 if mushld != 0.0: 

1162 err = err/mushld 

1163 

1164 if err < 0.0: 

1165 err = -1.0 * err 

1166 if z == 0 or err > worstMuErr: 

1167 worstMuErr = err 

1168 

1169 err = (sigma[0] - sigshld) 

1170 if sigshld != 0.0: 

1171 err = err/sigshld 

1172 

1173 if err < 0.0: 

1174 err = -1.0 * err 

1175 if z == 0 or err > worstSigErr: 

1176 worstSigErr = err 

1177 

1178 print("\nThe errors for Gaussian process using min-max normalization\n") 

1179 print("worst mu error ", worstMuErr) 

1180 print("worst sig2 error ", worstSigErr) 

1181 

1182 self.assertLess(worstMuErr, tol) 

1183 self.assertLess(worstSigErr, tol) 

1184 

1185 def testAddPointExceptions(self): 

1186 """ 

1187 Test that addPoint() raises exceptions when it should 

1188 """ 

1189 rng = np.random.RandomState(44) 

1190 data = rng.random_sample((10, 3)) 

1191 fn = rng.random_sample(10) 

1192 gg = afwMath.GaussianProcessD( 

1193 data, fn, afwMath.SquaredExpCovariogramD()) 

1194 fn_many = rng.random_sample((10, 5)) 

1195 gg_many = afwMath.GaussianProcessD( 

1196 data, fn_many, afwMath.SquaredExpCovariogramD()) 

1197 

1198 pt_good = rng.random_sample(3) 

1199 pt_bad = rng.random_sample(6) 

1200 fn_good = rng.random_sample(5) 

1201 fn_bad = rng.random_sample(4) 

1202 

1203 # test that, when you add a point of the wrong dimensionality, 

1204 # an exception is raised 

1205 with self.assertRaises(RuntimeError) as context: 

1206 gg.addPoint(pt_bad, 5.0) 

1207 self.assertIn("dimensionality", 

1208 context.exception.args[0]) 

1209 

1210 with self.assertRaises(RuntimeError) as context: 

1211 gg.addPoint(pt_bad, fn_good) 

1212 self.assertIn("dimensionality", 

1213 context.exception.args[0]) 

1214 

1215 # test that a GaussianProcess on many functions raises an exception 

1216 # when you try to add a point with just one function value 

1217 with self.assertRaises(RuntimeError) as context: 

1218 gg_many.addPoint(pt_good, 5.0) 

1219 self.assertIn("calling the wrong addPoint", 

1220 context.exception.args[0]) 

1221 

1222 # test that a GaussianProcess on many functions raises an 

1223 # exception when you try to add a point with the wrong number 

1224 # of function values 

1225 with self.assertRaises(RuntimeError) as context: 

1226 gg_many.addPoint(pt_good, fn_bad) 

1227 self.assertIn("number of function values", 

1228 context.exception.args[0]) 

1229 

1230 # check that, given good inputs, addPoint will run 

1231 gg.addPoint(pt_good, 5.0) 

1232 gg_many.addPoint(pt_good, fn_good) 

1233 

1234 # since we started with 10 data points, we should now have 11 

1235 self.assertEqual(gg.getNPoints(), 11) 

1236 self.assertEqual(gg_many.getNPoints(), 11) 

1237 

1238 def testAddPoint(self): 

1239 """ 

1240 Test that getData works as expected after running addPoint() 

1241 """ 

1242 rng = np.random.RandomState(99) 

1243 data = rng.random_sample((15, 4)) 

1244 fn = rng.random_sample(15) 

1245 gp = afwMath.GaussianProcessD( 

1246 data, fn, afwMath.SquaredExpCovariogramD()) 

1247 self.assertEqual(gp.getNPoints(), 15) 

1248 pt_add = rng.random_sample(4) 

1249 fn_add = 0.98453 

1250 gp.addPoint(pt_add, fn_add) 

1251 self.assertEqual(gp.getNPoints(), 16) 

1252 fn_out = np.zeros(1) 

1253 pt_out = np.zeros((1, 4)) 

1254 indices = np.array([15], dtype=np.int32) 

1255 gp.getData(pt_out, fn_out, indices) 

1256 for ii in range(4): 

1257 self.assertAlmostEqual(pt_out[0][ii], pt_add[ii], 10) 

1258 self.assertAlmostEqual(fn_out[0], fn_add, 10) 

1259 

1260 # now try it with a GaussianProcess on many functions 

1261 fn = rng.random_sample((15, 3)) 

1262 gp = afwMath.GaussianProcessD( 

1263 data, fn, afwMath.SquaredExpCovariogramD()) 

1264 self.assertEqual(gp.getNPoints(), 15) 

1265 pt_add = rng.random_sample(4) 

1266 fn_add = rng.random_sample(3) 

1267 gp.addPoint(pt_add, fn_add) 

1268 self.assertEqual(gp.getNPoints(), 16) 

1269 fn_out = np.zeros((1, 3)) 

1270 gp.getData(pt_out, fn_out, indices) 

1271 for ii in range(4): 

1272 self.assertEqual(pt_out[0][ii], pt_add[ii], 10) 

1273 for ii in range(3): 

1274 self.assertEqual(fn_out[0][ii], fn_add[ii], 10) 

1275 

1276 def testAdditionInterpolation(self): 

1277 """ 

1278 This will test the performance of interpolation after adding new points 

1279 to GaussianProcess' data set 

1280 """ 

1281 pp = 1000 

1282 dd = 10 

1283 kk = 15 

1284 tol = 1.0e-4 

1285 

1286 data = np.zeros((pp, dd), dtype=float) 

1287 fn = np.zeros((pp), dtype=float) 

1288 test = np.zeros((dd), dtype=float) 

1289 sigma = np.zeros((1), dtype=float) 

1290 

1291 xx = afwMath.SquaredExpCovariogramD() 

1292 xx.setEllSquared(5.0) 

1293 

1294 with open(os.path.join(testPath, "data", "gp_additive_test_root.sav"), "r") as f: 

1295 ff = f.readlines() 

1296 

1297 for i in range(len(ff)): 

1298 s = ff[i].split() 

1299 fn[i] = float(s[10]) 

1300 for j in range(10): 

1301 data[i][j] = float(s[j]) 

1302 

1303 # establish the Gaussian Process 

1304 try: 

1305 gg = afwMath.GaussianProcessD(data, fn, xx) 

1306 except pex.Exception as e: 

1307 print(e.what()) 

1308 

1309 gg.setLambda(0.002) 

1310 

1311 # now add new points to it and see if GaussianProcess.interpolate performs 

1312 # correctly 

1313 with open(os.path.join(testPath, "data", "gp_additive_test_data.sav"), "r") as f: 

1314 ff = f.readlines() 

1315 

1316 for z in range(len(ff)): 

1317 s = ff[z].split() 

1318 for i in range(dd): 

1319 test[i] = float(s[i]) 

1320 mushld = float(s[dd]) 

1321 try: 

1322 gg.addPoint(test, mushld) 

1323 except pex.Exception as e: 

1324 print(e.what()) 

1325 

1326 with open(os.path.join(testPath, "data", "gp_additive_test_solutions.sav"), "r") as f: 

1327 ff = f.readlines() 

1328 

1329 worstMuErr = -1.0 

1330 worstSigErr = -1.0 

1331 

1332 for z in range(len(ff)): 

1333 s = ff[z].split() 

1334 for i in range(dd): 

1335 test[i] = float(s[i]) 

1336 

1337 mushld = float(s[dd + kk]) 

1338 sigshld = float(s[dd + kk + 1]) 

1339 

1340 mu = gg.interpolate(sigma, test, kk) 

1341 

1342 err = (mu - mushld) 

1343 if mushld != 0: 

1344 err = err/mushld 

1345 if err < 0.0: 

1346 err = -1.0 * err 

1347 if z == 0 or err > worstMuErr: 

1348 worstMuErr = err 

1349 

1350 err = (sigma[0] - sigshld) 

1351 if sigshld != 0: 

1352 err = err/sigshld 

1353 if err < 0.0: 

1354 err = -1.0 * err 

1355 if z == 0 or err > worstSigErr: 

1356 worstSigErr = err 

1357 

1358 print("\nThe errors for the test of adding points to the Gaussian process\n") 

1359 print("worst mu error ", worstMuErr) 

1360 print("worst sig2 error ", worstSigErr) 

1361 

1362 self.assertLess(worstMuErr, tol) 

1363 self.assertLess(worstSigErr, tol) 

1364 

1365 def testBatch(self): 

1366 """ 

1367 This test will test GaussianProcess.batchInterpolate both with 

1368 and without variance calculation 

1369 """ 

1370 pp = 100 

1371 dd = 10 

1372 tol = 1.0e-3 

1373 

1374 data = np.zeros((pp, dd), dtype=float) 

1375 fn = np.zeros((pp), dtype=float) 

1376 

1377 with open(os.path.join(testPath, "data", "gp_exp_covar_data.sav"), "r") as f: 

1378 ff = f.readlines() 

1379 

1380 for i in range(100): 

1381 s = ff[i].split() 

1382 for j in range(dd): 

1383 data[i][j] = float(s[j]) 

1384 fn[i] = float(s[dd]) 

1385 

1386 xx = afwMath.SquaredExpCovariogramD() 

1387 xx.setEllSquared(2.0) 

1388 

1389 try: 

1390 gg = afwMath.GaussianProcessD(data, fn, xx) 

1391 except pex.Exception as e: 

1392 print(e.what()) 

1393 

1394 gg.setLambda(0.0032) 

1395 

1396 with open(os.path.join(testPath, "data", "gp_batch_solutions.sav"), "r") as f: 

1397 ff = f.readlines() 

1398 

1399 ntest = len(ff) 

1400 mushld = np.zeros((ntest), dtype=float) 

1401 varshld = np.zeros((ntest), dtype=float) 

1402 mu = np.zeros((ntest), dtype=float) 

1403 var = np.zeros((ntest), dtype=float) 

1404 

1405 queries = np.zeros((ntest, dd), dtype=float) 

1406 

1407 for i in range(ntest): 

1408 s = ff[i].split() 

1409 for j in range(dd): 

1410 queries[i][j] = float(s[j]) 

1411 mushld[i] = float(s[dd]) 

1412 varshld[i] = float(s[dd + 1]) 

1413 

1414 # test with variance calculation 

1415 gg.batchInterpolate(mu, var, queries) 

1416 

1417 worstMuErr = -1.0 

1418 worstVarErr = -1.0 

1419 for i in range(ntest): 

1420 err = mu[i]-mushld[i] 

1421 if mushld[i] != 0.0: 

1422 err = err/mushld[i] 

1423 if err < 0.0: 

1424 err = -1.0 * err 

1425 if err > worstMuErr: 

1426 worstMuErr = err 

1427 

1428 err = var[i]-varshld[i] 

1429 if varshld[i] != 0.0: 

1430 err = err/varshld[i] 

1431 if err < 0.0: 

1432 err = -1.0 * err 

1433 if err > worstVarErr: 

1434 worstVarErr = err 

1435 

1436 # test without variance interpolation 

1437 # continue keeping track of worstMuErr 

1438 gg.batchInterpolate(mu, queries) 

1439 for i in range(ntest): 

1440 err = mu[i]-mushld[i] 

1441 if mushld[i] != 0.0: 

1442 err = err/mushld[i] 

1443 if err < 0.0: 

1444 err = -1.0 * err 

1445 if err > worstMuErr: 

1446 worstMuErr = err 

1447 

1448 self.assertLess(worstMuErr, tol) 

1449 self.assertLess(worstVarErr, tol) 

1450 

1451 print("\nThe errors for batch interpolation\n") 

1452 print("worst mu error ", worstMuErr) 

1453 print("worst sig2 error ", worstVarErr) 

1454 

1455 def testSelf(self): 

1456 """ 

1457 This test will test GaussianProcess.selfInterpolation 

1458 """ 

1459 pp = 2000 

1460 dd = 10 

1461 tol = 1.0e-3 

1462 kk = 20 

1463 

1464 data = np.zeros((pp, dd), dtype=float) 

1465 fn = np.zeros((pp), dtype=float) 

1466 

1467 with open(os.path.join(testPath, "data", "gp_exp_covar_data.sav"), "r") as f: 

1468 ff = f.readlines() 

1469 

1470 for i in range(pp): 

1471 s = ff[i].split() 

1472 for j in range(dd): 

1473 data[i][j] = float(s[j]) 

1474 fn[i] = float(s[dd]) 

1475 

1476 xx = afwMath.SquaredExpCovariogramD() 

1477 xx.setEllSquared(20.0) 

1478 try: 

1479 gg = afwMath.GaussianProcessD(data, fn, xx) 

1480 except pex.Exception as e: 

1481 print(e.what()) 

1482 

1483 gg.setKrigingParameter(30.0) 

1484 gg.setLambda(0.00002) 

1485 

1486 with open(os.path.join(testPath, "data", "gp_self_solutions.sav"), "r") as f: 

1487 ff = f.readlines() 

1488 

1489 variance = np.zeros((1), dtype=float) 

1490 

1491 worstMuErr = -1.0 

1492 worstSigErr = -1.0 

1493 

1494 for i in range(pp): 

1495 s = ff[i].split() 

1496 mushld = float(s[0]) 

1497 sig2shld = float(s[1]) 

1498 

1499 try: 

1500 mu = gg.selfInterpolate(variance, i, kk) 

1501 except pex.Exception as e: 

1502 print(e.what()) 

1503 

1504 err = mu - mushld 

1505 if mushld != 0.0: 

1506 err = err/mushld 

1507 if err < 0.0: 

1508 err = err * (-1.0) 

1509 if i == 0 or err > worstMuErr: 

1510 worstMuErr = err 

1511 

1512 err = variance[0] - sig2shld 

1513 if sig2shld != 0.0: 

1514 err = err/sig2shld 

1515 if err < 0.0: 

1516 err = err * (-1.0) 

1517 if i == 0 or err > worstSigErr: 

1518 worstSigErr = err 

1519 

1520 print("\nThe errors for self interpolation\n") 

1521 print("worst mu error ", worstMuErr) 

1522 print("worst sig2 error ", worstSigErr) 

1523 self.assertLess(worstMuErr, tol) 

1524 self.assertLess(worstSigErr, tol) 

1525 

1526 def testVector(self): 

1527 """ 

1528 This will test interpolate using a vector of functions 

1529 """ 

1530 

1531 tol = 1.0e-3 

1532 data = np.zeros((2000, 10), dtype=float) 

1533 fn = np.zeros((2000, 4), dtype=float) 

1534 mu = np.zeros((4), dtype=float) 

1535 sig = np.zeros((4), dtype=float) 

1536 mushld = np.zeros((4), dtype=float) 

1537 vv = np.zeros((10), dtype=float) 

1538 vvf = np.zeros((4), dtype=float) 

1539 

1540 kk = 30 

1541 

1542 with open(os.path.join(testPath, "data", "gp_vector_data.sav"), "r") as f: 

1543 ff = f.readlines() 

1544 

1545 for i in range(len(ff)): 

1546 s = ff[i].split() 

1547 for j in range(10): 

1548 data[i][j] = float(s[j]) 

1549 for j in range(4): 

1550 fn[i][j] = float(s[j+10]) 

1551 

1552 nn = afwMath.NeuralNetCovariogramD() 

1553 nn.setSigma0(2.25) 

1554 nn.setSigma1(0.76) 

1555 try: 

1556 gg = afwMath.GaussianProcessD(data, fn, nn) 

1557 except pex.Exception as e: 

1558 print(e.what()) 

1559 

1560 gg.setLambda(0.0045) 

1561 

1562 worstMuErr = -1.0 

1563 worstSigErr = -1.0 

1564 

1565 with open(os.path.join(testPath, "data", "gp_vector_solutions.sav"), "r") as f: 

1566 ff = f.readlines() 

1567 

1568 for i in range(len(ff)): 

1569 s = ff[i].split() 

1570 for j in range(10): 

1571 vv[j] = float(s[j]) 

1572 for j in range(4): 

1573 mushld[j] = float(s[j+10]) 

1574 sigshld = float(s[14]) 

1575 

1576 gg.interpolate(mu, sig, vv, kk) 

1577 

1578 for j in range(4): 

1579 muErr = (mu[j]-mushld[j])/mushld[j] 

1580 sigErr = (sig[j]-sigshld)/sigshld 

1581 if muErr < 0.0: 

1582 muErr = -1.0 * muErr 

1583 if sigErr < 0.0: 

1584 sigErr = -1.0 * sigErr 

1585 if (muErr > worstMuErr): 

1586 worstMuErr = muErr 

1587 if (sigErr > worstSigErr): 

1588 worstSigErr = sigErr 

1589 

1590 print("\nThe errors for vector interpolation\n") 

1591 print("worst mu error ", worstMuErr) 

1592 print("worst sig2 error ", worstSigErr) 

1593 self.assertLess(worstMuErr, tol) 

1594 self.assertLess(worstSigErr, tol) 

1595 

1596 worstMuErr = -1.0 

1597 worstSigErr = -1.0 

1598 

1599 with open(os.path.join(testPath, "data", "gp_vector_selfinterpolate_solutions.sav"), "r") as f: 

1600 ff = f.readlines() 

1601 

1602 for i in range(len(ff)): 

1603 s = ff[i].split() 

1604 try: 

1605 gg.selfInterpolate(mu, sig, i, kk) 

1606 except pex.Exception as e: 

1607 print(e.what()) 

1608 

1609 for j in range(4): 

1610 mushld[j] = float(s[j]) 

1611 sigshld = float(s[4]) 

1612 

1613 for j in range(4): 

1614 muErr = (mu[j]-mushld[j])/mushld[j] 

1615 if muErr < -1.0: 

1616 muErr = -1.0 * muErr 

1617 if muErr > worstMuErr: 

1618 worstMuErr = muErr 

1619 

1620 sigErr = (sig[j]-sigshld)/sigshld 

1621 if sigErr < -1.0: 

1622 sigErr = -1.0*sigErr 

1623 if sigErr > worstSigErr: 

1624 worstSigErr = sigErr 

1625 

1626 print("\nThe errors for vector self interpolation\n") 

1627 print("worst mu error ", worstMuErr) 

1628 print("worst sig2 error ", worstSigErr) 

1629 self.assertLess(worstMuErr, tol) 

1630 self.assertLess(worstSigErr, tol) 

1631 

1632 queries = np.zeros((100, 10), dtype=float) 

1633 batchMu = np.zeros((100, 4), dtype=float) 

1634 batchSig = np.zeros((100, 4), dtype=float) 

1635 batchMuShld = np.zeros((100, 4), dtype=float) 

1636 batchSigShld = np.zeros((100, 4), dtype=float) 

1637 batchData = np.zeros((200, 10), dtype=float) 

1638 batchFunctions = np.zeros((200, 4), dtype=float) 

1639 

1640 with open(os.path.join(testPath, "data", "gp_vectorbatch_data.sav"), "r") as f: 

1641 ff = f.readlines() 

1642 

1643 for i in range(len(ff)): 

1644 s = ff[i].split() 

1645 for j in range(10): 

1646 batchData[i][j] = float(s[j]) 

1647 for j in range(4): 

1648 batchFunctions[i][j] = float(s[j+10]) 

1649 

1650 try: 

1651 ggbatch = afwMath.GaussianProcessD(batchData, batchFunctions, nn) 

1652 except pex.Exception as e: 

1653 print(e.what()) 

1654 

1655 ggbatch.setLambda(0.0045) 

1656 

1657 with open(os.path.join(testPath, "data", "gp_vectorbatch_solutions.sav"), "r") as f: 

1658 ff = f.readlines() 

1659 

1660 for i in range(len(ff)): 

1661 s = ff[i].split() 

1662 for j in range(10): 

1663 queries[i][j] = float(s[j]) 

1664 for j in range(4): 

1665 batchMuShld[i][j] = float(s[j+10]) 

1666 sigShld = float(s[14]) 

1667 for j in range(4): 

1668 batchSigShld[i][j] = sigShld 

1669 

1670 ggbatch.batchInterpolate(batchMu, batchSig, queries) 

1671 worstMuErr = -1.0 

1672 worstSigErr = -1.0 

1673 for i in range(100): 

1674 for j in range(4): 

1675 muErr = (batchMu[i][j]-batchMuShld[i][j])/batchMuShld[i][j] 

1676 sigErr = (batchSig[i][j]-batchSigShld[i][j])/batchSigShld[i][j] 

1677 if muErr < 0.0: 

1678 muErr = muErr * (-1.0) 

1679 if sigErr < 0.0: 

1680 sigErr = sigErr * (-1.0) 

1681 

1682 if muErr > worstMuErr: 

1683 worstMuErr = muErr 

1684 if sigErr > worstSigErr: 

1685 worstSigErr = sigErr 

1686 

1687 print("\nThe errors for vector batch interpolation with variance\n") 

1688 print("worst mu error ", worstMuErr) 

1689 print("worst sig2 error ", worstSigErr) 

1690 self.assertLess(worstMuErr, tol) 

1691 self.assertLess(worstSigErr, tol) 

1692 

1693 ggbatch.batchInterpolate(batchMu, queries) 

1694 worstMuErr = -1.0 

1695 worstSigErr = -1.0 

1696 for i in range(100): 

1697 for j in range(4): 

1698 muErr = (batchMu[i][j]-batchMuShld[i][j])/batchMuShld[i][j] 

1699 if muErr < 0.0: 

1700 muErr = muErr * (-1.0) 

1701 

1702 if muErr > worstMuErr: 

1703 worstMuErr = muErr 

1704 

1705 print("\nThe errors for vector batch interpolation without variance\n") 

1706 print("worst mu error ", worstMuErr) 

1707 self.assertLess(worstMuErr, tol) 

1708 

1709 with open(os.path.join(testPath, "data", "gp_vector_add_data.sav"), "r") as f: 

1710 ff = f.readlines() 

1711 

1712 for i in range(len(ff)): 

1713 s = ff[i].split() 

1714 for j in range(10): 

1715 vv[j] = float(s[j]) 

1716 for j in range(4): 

1717 vvf[j] = float(s[j+10]) 

1718 try: 

1719 gg.addPoint(vv, vvf) 

1720 except pex.Exception as e: 

1721 print(e.what()) 

1722 

1723 with open(os.path.join(testPath, "data", "gp_vector_add_solutions.sav"), "r") as f: 

1724 ff = f.readlines() 

1725 

1726 for i in range(len(ff)): 

1727 s = ff[i].split() 

1728 try: 

1729 gg.selfInterpolate(mu, sig, i, kk) 

1730 except pex.Exception as e: 

1731 print(e.what()) 

1732 

1733 for j in range(4): 

1734 mushld[j] = float(s[j]) 

1735 sigshld = float(s[4]) 

1736 

1737 for j in range(4): 

1738 muErr = (mu[j]-mushld[j])/mushld[j] 

1739 if muErr < 0.0: 

1740 muErr = -1.0 * muErr 

1741 if muErr > worstMuErr: 

1742 worstMuErr = muErr 

1743 

1744 sigErr = (sig[j]-sigshld)/sigshld 

1745 if sigErr < 0.0: 

1746 sigErr = -1.0*sigErr 

1747 if sigErr > worstSigErr: 

1748 worstSigErr = sigErr 

1749 

1750 print("\nThe errors for vector add interpolation\n") 

1751 print("worst mu error ", worstMuErr) 

1752 print("worst sig2 error ", worstSigErr) 

1753 

1754 self.assertLess(worstMuErr, tol) 

1755 self.assertLess(worstSigErr, tol) 

1756 

1757 def testRemovePointException(self): 

1758 """ 

1759 Test that an exception is raised if you try to remove 

1760 a point that does not exist from a Gaussian Process 

1761 """ 

1762 rng = np.random.RandomState(118) 

1763 data = rng.random_sample((13, 6)) 

1764 fn = rng.random_sample(13) 

1765 gg = afwMath.GaussianProcessD( 

1766 data, fn, afwMath.SquaredExpCovariogramD()) 

1767 

1768 with self.assertRaises(RuntimeError) as context: 

1769 gg.removePoint(-1) 

1770 self.assertIn("doesn't exist", 

1771 context.exception.args[0]) 

1772 

1773 with self.assertRaises(RuntimeError) as context: 

1774 gg.removePoint(13) 

1775 self.assertIn("doesn't exist", 

1776 context.exception.args[0]) 

1777 

1778 # test that it runs fine 

1779 gg.removePoint(11) 

1780 self.assertEqual(gg.getNPoints(), 12) 

1781 

1782 def testRemovePoint(self): 

1783 """ 

1784 Test that, after a point is removed, getData works as you would expect 

1785 """ 

1786 rng = np.random.RandomState(99) 

1787 data = rng.random_sample((15, 4)) 

1788 fn = rng.random_sample(15) 

1789 gp = afwMath.GaussianProcessD( 

1790 data, fn, afwMath.SquaredExpCovariogramD()) 

1791 self.assertEqual(gp.getNPoints(), 15) 

1792 gp.removePoint(6) 

1793 self.assertEqual(gp.getNPoints(), 14) 

1794 indices = np.array([9, 5, 4, 11], dtype=np.int32) 

1795 fn_out = np.zeros(4) 

1796 pts_out = np.zeros((4, 4)) 

1797 gp.getData(pts_out, fn_out, indices) 

1798 for ii in range(len(indices)): 

1799 if indices[ii] >= 6: 

1800 target = indices[ii]+1 

1801 else: 

1802 target = indices[ii] 

1803 for jj in range(4): 

1804 self.assertAlmostEqual(pts_out[ii][jj], data[target][jj], 10) 

1805 self.assertAlmostEqual(fn_out[ii], fn[target], 10) 

1806 

1807 # now test it on a GaussianProcess on many functions 

1808 fn = rng.random_sample((15, 5)) 

1809 gp = afwMath.GaussianProcessD( 

1810 data, fn, afwMath.SquaredExpCovariogramD()) 

1811 self.assertEqual(gp.getNPoints(), 15) 

1812 gp.removePoint(6) 

1813 self.assertEqual(gp.getNPoints(), 14) 

1814 indices = np.array([9, 5, 4, 11], dtype=np.int32) 

1815 fn_out = np.zeros((4, 5)) 

1816 pts_out = np.zeros((4, 4)) 

1817 gp.getData(pts_out, fn_out, indices) 

1818 for ii in range(len(indices)): 

1819 if indices[ii] >= 6: 

1820 target = indices[ii]+1 

1821 else: 

1822 target = indices[ii] 

1823 for jj in range(4): 

1824 self.assertAlmostEqual(pts_out[ii][jj], data[target][jj], 10) 

1825 for jj in range(5): 

1826 self.assertAlmostEqual(fn_out[ii][jj], fn[target][jj], 10) 

1827 

1828 def testSubtractionInterpolation(self): 

1829 """ 

1830 This will test interpolate after subtracting points 

1831 """ 

1832 

1833 tol = 1.0e-3 

1834 data = np.zeros((2000, 10), dtype=float) 

1835 fn = np.zeros((2000, 4), dtype=float) 

1836 mu = np.zeros((4), dtype=float) 

1837 sig = np.zeros((4), dtype=float) 

1838 mushld = np.zeros((4), dtype=float) 

1839 vv = np.zeros((10), dtype=float) 

1840 kk = 30 

1841 

1842 with open(os.path.join(testPath, "data", "gp_subtraction_data.sav"), "r") as f: 

1843 ff = f.readlines() 

1844 

1845 for i in range(len(ff)): 

1846 s = ff[i].split() 

1847 for j in range(10): 

1848 data[i][j] = float(s[j]) 

1849 for j in range(4): 

1850 fn[i][j] = float(s[j+10]) 

1851 

1852 xx = afwMath.SquaredExpCovariogramD() 

1853 xx.setEllSquared(2.3) 

1854 try: 

1855 gg = afwMath.GaussianProcessD(data, fn, xx) 

1856 except pex.Exception as e: 

1857 print(e.what()) 

1858 

1859 gg.setLambda(0.002) 

1860 

1861 j = 1 

1862 for i in range(1000): 

1863 try: 

1864 gg.removePoint(j) 

1865 except pex.Exception as e: 

1866 print(e.what()) 

1867 

1868 j = j+1 

1869 

1870 worstMuErr = -1.0 

1871 worstSigErr = -1.0 

1872 

1873 with open(os.path.join(testPath, "data", "gp_subtraction_solutions.sav"), "r") as f: 

1874 ff = f.readlines() 

1875 

1876 for i in range(len(ff)): 

1877 s = ff[i].split() 

1878 for j in range(10): 

1879 vv[j] = float(s[j]) 

1880 for j in range(4): 

1881 mushld[j] = float(s[j+10]) 

1882 sigshld = float(s[14]) 

1883 

1884 gg.interpolate(mu, sig, vv, kk) 

1885 

1886 for j in range(4): 

1887 muErr = (mu[j]-mushld[j])/mushld[j] 

1888 sigErr = (sig[j]-sigshld)/sigshld 

1889 if muErr < 0.0: 

1890 muErr = -1.0 * muErr 

1891 if sigErr < 0.0: 

1892 sigErr = -1.0 * sigErr 

1893 if (muErr > worstMuErr): 

1894 worstMuErr = muErr 

1895 if (sigErr > worstSigErr): 

1896 worstSigErr = sigErr 

1897 

1898 print("\nThe errors for subtraction interpolation\n") 

1899 print("worst mu error ", worstMuErr) 

1900 print("worst sig2 error ", worstSigErr) 

1901 self.assertLess(worstMuErr, tol) 

1902 self.assertLess(worstSigErr, tol) 

1903 

1904 worstMuErr = -1.0 

1905 worstSigErr = -1.0 

1906 

1907 with open(os.path.join(testPath, "data", "gp_subtraction_selfinterpolate_solutions.sav"), "r") as f: 

1908 ff = f.readlines() 

1909 

1910 for i in range(len(ff)): 

1911 s = ff[i].split() 

1912 try: 

1913 gg.selfInterpolate(mu, sig, i, kk) 

1914 except pex.Exception as e: 

1915 print(e.what()) 

1916 

1917 for j in range(4): 

1918 mushld[j] = float(s[j]) 

1919 sigshld = float(s[4]) 

1920 

1921 for j in range(4): 

1922 muErr = (mu[j]-mushld[j])/mushld[j] 

1923 if muErr < 0.0: 

1924 muErr = -1.0 * muErr 

1925 if muErr > worstMuErr: 

1926 worstMuErr = muErr 

1927 

1928 sigErr = (sig[j]-sigshld)/sigshld 

1929 if sigErr < 0.0: 

1930 sigErr = -1.0*sigErr 

1931 if sigErr > worstSigErr: 

1932 worstSigErr = sigErr 

1933 

1934 print("\nThe errors for subtraction self interpolation\n") 

1935 print("worst mu error ", worstMuErr) 

1936 print("worst sig2 error ", worstSigErr) 

1937 self.assertLess(worstMuErr, tol) 

1938 self.assertLess(worstSigErr, tol) 

1939 

1940 

1941class MemoryTester(lsst.utils.tests.MemoryTestCase): 

1942 pass 

1943 

1944 

1945def setup_module(module): 

1946 lsst.utils.tests.init() 

1947 

1948 

1949if __name__ == "__main__": 1949 ↛ 1950line 1949 didn't jump to line 1950, because the condition on line 1949 was never true

1950 lsst.utils.tests.init() 

1951 unittest.main()