source: inundation/ga/storm_surge/pyvolution/test_least_squares.py @ 474

Last change on this file since 474 was 466, checked in by ole, 21 years ago
File size: 20.6 KB
Line 
1#!/usr/bin/env python
2
3import unittest
4from math import sqrt
5
6
7from least_squares import *
8from Numeric import allclose, array, transpose
9
10def distance(x, y):
11    return sqrt( sum( (array(x)-array(y))**2 ))         
12
13def linear_function(point):
14    point = array(point)
15    return point[:,0]+point[:,1]
16   
17       
18class TestCase(unittest.TestCase):
19
20    def setUp(self):
21        pass
22       
23    def tearDown(self):
24        pass
25
26
27    def test_datapoint_at_centroid(self):
28        a = [0.0, 0.0]
29        b = [0.0, 2.0]
30        c = [2.0,0.0]
31        points = [a, b, c]
32        vertices = [ [1,0,2] ]   #bac
33
34        data = [ [2.0/3, 2.0/3] ] #Use centroid as one data point       
35       
36        interp = Interpolation(points, vertices, data)
37        assert allclose(interp.get_A(), [[1./3, 1./3, 1./3]]) 
38       
39
40
41    def test_datapoints_at_vertices(self):
42        """Test that data points coinciding with vertices yield a diagonal matrix
43        """
44       
45        a = [0.0, 0.0]
46        b = [0.0, 2.0]
47        c = [2.0,0.0]
48        points = [a, b, c]
49        vertices = [ [1,0,2] ]   #bac
50
51        data = points #Use data at vertices       
52       
53        interp = Interpolation(points, vertices, data)
54        assert allclose(interp.get_A(), [[1., 0., 0.],
55                                   [0., 1., 0.],
56                                   [0., 0., 1.]]) 
57       
58
59
60    def test_datapoints_on_edge_midpoints(self):
61        """Try datapoints midway on edges -
62        each point should affect two matrix entries equally
63        """
64       
65        a = [0.0, 0.0]
66        b = [0.0, 2.0]
67        c = [2.0,0.0]
68        points = [a, b, c]
69        vertices = [ [1,0,2] ]   #bac
70
71        data = [ [0., 1.], [1., 0.], [1., 1.] ]
72       
73        interp = Interpolation(points, vertices, data)
74       
75        assert allclose(interp.get_A(), [[0.5, 0.5, 0.0],  #Affects vertex 1 and 0   
76                                   [0.5, 0.0, 0.5],  #Affects vertex 0 and 2
77                                   [0.0, 0.5, 0.5]]) #Affects vertex 1 and 2
78
79
80    def test_datapoints_on_edges(self):
81        """Try datapoints on edges -
82        each point should affect two matrix entries in proportion
83        """
84       
85        a = [0.0, 0.0]
86        b = [0.0, 2.0]
87        c = [2.0,0.0]
88        points = [a, b, c]
89        vertices = [ [1,0,2] ]   #bac
90
91        data = [ [0., 1.5], [1.5, 0.], [1.5, 0.5] ]
92       
93        interp = Interpolation(points, vertices, data)
94       
95        assert allclose(interp.get_A(), [[0.25, 0.75, 0.0],  #Affects vertex 1 and 0
96                                   [0.25, 0.0, 0.75],  #Affects vertex 0 and 2
97                                   [0.0, 0.25, 0.75]]) #Affects vertex 1 and 2
98
99    def test_arbitrary_datapoints(self):
100        """Try arbitrary datapoints
101        """
102
103        from Numeric import sum
104       
105        a = [0.0, 0.0]
106        b = [0.0, 2.0]
107        c = [2.0,0.0]
108        points = [a, b, c]
109        vertices = [ [1,0,2] ]   #bac
110
111        data = [ [0.2, 1.5], [0.123, 1.768], [1.43, 0.44] ]
112       
113        interp = Interpolation(points, vertices, data)
114
115        assert allclose(sum(interp.get_A(), axis=1), 1.0)
116       
117
118    # this causes a memory error in scipy.sparce       
119    def test_more_triangles(self):
120       
121        a = [-1.0, 0.0]
122        b = [3.0, 4.0]
123        c = [4.0,1.0]
124        d = [-3.0, 2.0] #3
125        e = [-1.0,-2.0]
126        f = [1.0, -2.0] #5
127
128        points = [a, b, c, d,e,f]
129        triangles = [[0,1,3],[1,0,2],[0,4,5], [0,5,2]] #abd bac aef afc
130
131        #Data points
132        data_points = [ [-3., 2.0], [-2, 1], [0.0, 1], [0, 3], [2, 3], [-1.0/3,-4./3] ]
133        interp = Interpolation(points, triangles, data_points) 
134
135        answer = [[0.0, 0.0, 0.0,  1.0, 0.0, 0.0],   #Affects point d     
136                  [0.5, 0.0, 0.0, 0.5, 0.0, 0.0],    #Affects points a and d
137                  [0.75, 0.25, 0.0, 0.0, 0.0, 0.0],  #Affects points a and b
138                  [0.0, 0.5, 0.0, 0.5, 0.0, 0.0],    #Affects points a and d
139                  [0.25, 0.75, 0.0, 0.0, 0.0, 0.0],  #Affects points a and b
140                  [1./3, 0.0, 0.0, 0.0, 1./3, 1./3]] #Affects points a,e and f
141
142        assert allclose(interp.get_A(), answer)
143
144
145
146
147    def test_smooth_attributes_to_mesh(self):
148        a = [0.0, 0.0]
149        b = [0.0, 5.0]
150        c = [5.0, 0.0]
151        points = [a, b, c]
152        triangles = [ [1,0,2] ]   #bac
153         
154        d1 = [1.0, 1.0]
155        d2 = [1.0, 3.0]
156        d3 = [3.0,1.0]
157        z1 = 2
158        z2 = 4
159        z3 = 4
160        data_coords = [d1, d2, d3] 
161       
162        interp = Interpolation(points, triangles, data_coords, alpha=5.0e-20)
163        z = [z1, z2, z3]
164        f = interp.fit(z)
165        answer = [0, 5., 5.]
166
167        #print "f\n",f
168        #print "answer\n",answer
169       
170        assert allclose(f, answer,atol=1e-7)
171       
172       
173    def test_smooth_att_to_meshII(self):
174       
175        a = [0.0, 0.0]
176        b = [0.0, 5.0]
177        c = [5.0, 0.0]
178        points = [a, b, c]
179        triangles = [ [1,0,2] ]   #bac
180         
181        d1 = [1.0, 1.0]
182        d2 = [1.0, 2.0]
183        d3 = [3.0,1.0]
184        data_coords = [d1, d2, d3]       
185        z = linear_function(data_coords)
186        interp = Interpolation(points, triangles, data_coords, alpha=0.0)
187        f = interp.fit(z)
188        answer = linear_function(points)
189       
190        assert allclose(f, answer)
191   
192    def test_smooth_attributes_to_meshIII(self):
193       
194        a = [-1.0, 0.0]
195        b = [3.0, 4.0]
196        c = [4.0,1.0]
197        d = [-3.0, 2.0] #3
198        e = [-1.0,-2.0]
199        f = [1.0, -2.0] #5
200
201        vertices = [a, b, c, d,e,f]
202        triangles = [[0,1,3],[1,0,2],[0,4,5], [0,5,2]] #abd bac aef afc
203
204        point_coords = [[-2.0, 2.0],
205                        [-1.0, 1.0],
206                        [0.0,2.0],
207                        [1.0, 1.0],
208                        [2.0, 1.0],
209                        [0.0,0.0],
210                        [1.0, 0.0],
211                        [0.0, -1.0],
212                        [-0.2,-0.5],
213                        [-0.9, -1.5],
214                        [0.5, -1.9],
215                        [3.0,1.0]]
216
217        z = linear_function(point_coords)
218        interp = Interpolation(vertices, triangles, point_coords, alpha=0.0)
219
220        #print 'z',z
221        f = interp.fit(z)
222        answer = linear_function(vertices)
223        #print "f\n",f
224        #print "answer\n",answer
225        assert allclose(f, answer)
226       
227
228    def test_smooth_attributes_to_meshIV(self):
229        """ Testing 2 attributes smoothed to the mesh
230        """
231       
232        a = [0.0, 0.0]
233        b = [0.0, 5.0]
234        c = [5.0, 0.0]
235        points = [a, b, c]
236        triangles = [ [1,0,2] ]   #bac
237         
238        d1 = [1.0, 1.0]
239        d2 = [1.0, 3.0]
240        d3 = [3.0,1.0]
241        z1 = [2,4]
242        z2 = [4,8]
243        z3 = [4,8]
244        data_coords = [ d1, d2, d3] 
245       
246        interp = Interpolation(points, triangles, data_coords, alpha=0.0)
247        z = [z1, z2, z3]
248        f =  interp.fit_points(z)
249        answer = [[0,0], [5., 10.], [5., 10.]]
250        assert allclose(f, answer)
251       
252    def test_interpolate_attributes_to_points(self):
253        v0 = [0.0, 0.0]
254        v1 = [0.0, 5.0]
255        v2 = [5.0, 0.0]
256       
257        vertices = [v0, v1, v2]
258        triangles = [ [1,0,2] ]   #bac
259         
260        d0 = [1.0, 1.0]
261        d1 = [1.0, 2.0]
262        d2 = [3.0,1.0]
263        point_coords = [ d0, d1, d2]
264       
265        interp = Interpolation(vertices, triangles, point_coords)
266        f = linear_function(vertices)
267        z = interp.interpolate(f)
268        answer = linear_function(point_coords)
269       
270
271        assert allclose(z, answer)
272
273       
274    def test_interpolate_attributes_to_pointsII(self):
275        a = [-1.0, 0.0]
276        b = [3.0, 4.0]
277        c = [4.0,1.0]
278        d = [-3.0, 2.0] #3
279        e = [-1.0,-2.0]
280        f = [1.0, -2.0] #5
281
282        vertices = [a, b, c, d,e,f]
283        triangles = [[0,1,3],[1,0,2],[0,4,5], [0,5,2]] #abd bac aef afc
284
285         
286        point_coords = [[-2.0, 2.0],
287                        [-1.0, 1.0],
288                        [0.0,2.0],
289                        [1.0, 1.0],
290                        [2.0, 1.0],
291                        [0.0,0.0],
292                        [1.0, 0.0],
293                        [0.0, -1.0],
294                        [-0.2,-0.5],
295                        [-0.9, -1.5],
296                        [0.5, -1.9],
297                        [3.0,1.0]]
298       
299        interp = Interpolation(vertices, triangles, point_coords)
300        f = linear_function(vertices)
301        z = interp.interpolate(f)
302        answer = linear_function(point_coords)
303        #print "z",z
304        #print "answer",answer
305        assert allclose(z, answer)
306   
307    def test_interpolate_attributes_to_pointsIII(self):
308        v0 = [0.0, 0.0]
309        v1 = [0.0, 5.0]
310        v2 = [5.0, 0.0]
311       
312        vertices = [v0, v1, v2]
313        triangles = [ [1,0,2] ]   #bac
314         
315        d0 = [1.0, 1.0]
316        d1 = [1.0, 2.0]
317        d2 = [3.0,1.0]
318        point_coords = [ d0, d1, d2]
319       
320        interp = Interpolation(vertices, triangles, point_coords)
321        f = [ [0., 0.],  [5., 10.],  [5., 10.]] #linear_function(vertices)
322        #print "f",f
323       
324        z = interp.interpolate(f)
325        answer = [ [2., 4.],  [3., 6.],  [4., 8.]]
326
327        #print "***********"
328        #print "z",z
329        #print "answer",answer
330        #print "***********"
331
332        assert allclose(z, answer)
333   
334    def test_interpolate_attributes_to_pointsIV(self):
335        a = [-1.0, 0.0]
336        b = [3.0, 4.0]
337        c = [4.0,1.0]
338        d = [-3.0, 2.0] #3
339        e = [-1.0,-2.0]
340        f = [1.0, -2.0] #5
341
342        vertices = [a, b, c, d,e,f]
343        triangles = [[0,1,3],[1,0,2],[0,4,5], [0,5,2]] #abd bac aef afc
344
345         
346        point_coords = [[-2.0, 2.0],
347                        [-1.0, 1.0],
348                        [0.0,2.0],
349                        [1.0, 1.0],
350                        [2.0, 1.0],
351                        [0.0,0.0],
352                        [1.0, 0.0],
353                        [0.0, -1.0],
354                        [-0.2,-0.5],
355                        [-0.9, -1.5],
356                        [0.5, -1.9],
357                        [3.0,1.0]]
358       
359        interp = Interpolation(vertices, triangles, point_coords)
360        f = array([linear_function(vertices),2*linear_function(vertices) ])
361        f = transpose(f)
362        #print "f",f
363        z = interp.interpolate(f)
364        answer = [linear_function(point_coords),
365             
366     2*linear_function(point_coords) ]
367        answer = transpose(answer)
368        #print "z",z
369        #print "answer",answer
370        assert allclose(z, answer)
371       
372    def test_smooth_attributes_to_mesh_function(self):
373        """ Testing 2 attributes smoothed to the mesh
374        """
375        """Test multiple attributes
376        """
377       
378        a = [0.0, 0.0]
379        b = [0.0, 5.0]
380        c = [5.0, 0.0]
381        points = [a, b, c]
382        triangles = [ [1,0,2] ]   #bac
383         
384        d1 = [1.0, 1.0]
385        d2 = [1.0, 3.0]
386        d3 = [3.0,1.0]
387        z1 = [2,4]
388        z2 = [4,8]
389        z3 = [4,8]
390        data_coords = [ d1, d2, d3]
391        z = [z1, z2, z3]
392       
393        f = fit_to_mesh(points, triangles, data_coords, z, alpha=0.0)
394        answer = [[0, 0], [5., 10.], [5., 10.]]
395       
396        assert allclose(f, answer)
397
398
399
400    #Tests of smoothing matrix   
401    def test_smoothing_matrix_one_triangle(self):
402        from Numeric import dot
403        a = [0.0, 0.0]
404        b = [0.0, 2.0]
405        c = [2.0,0.0]
406        points = [a, b, c]
407       
408        vertices = [ [1,0,2] ]   #bac
409
410        interp = Interpolation(points, vertices)
411
412        assert allclose(interp.get_D(), [[1, -0.5, -0.5],
413                                   [-0.5, 0.5, 0],
414                                   [-0.5, 0, 0.5]])
415
416        #Define f(x,y) = x
417        f = array([0,0,2]) #Value at global vertex 2
418
419        #Check that int (df/dx)**2 + (df/dy)**2 dx dy =
420        #           int 1 dx dy = area = 2
421        assert dot(dot(f, interp.get_D()), f) == 2
422       
423        #Define f(x,y) = y
424        f = array([0,2,0])  #Value at global vertex 1
425
426        #Check that int (df/dx)**2 + (df/dy)**2 dx dy =
427        #           int 1 dx dy = area = 2
428        assert dot(dot(f, interp.get_D()), f) == 2
429
430        #Define f(x,y) = x+y
431        f = array([0,2,2])  #Values at global vertex 1 and 2
432
433        #Check that int (df/dx)**2 + (df/dy)**2 dx dy =
434        #           int 2 dx dy = 2*area = 4
435        assert dot(dot(f, interp.get_D()), f) == 4       
436       
437
438
439    def test_smoothing_matrix_more_triangles(self):
440        from Numeric import dot
441       
442        a = [0.0, 0.0]
443        b = [0.0, 2.0]
444        c = [2.0,0.0]
445        d = [0.0, 4.0]
446        e = [2.0, 2.0]
447        f = [4.0,0.0]
448
449        points = [a, b, c, d, e, f]
450        #bac, bce, ecf, dbe, daf, dae
451        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
452
453        interp = Interpolation(points, vertices)
454
455
456        #assert allclose(interp.get_D(), [[1, -0.5, -0.5],
457        #                           [-0.5, 0.5, 0],
458        #                           [-0.5, 0, 0.5]])
459
460        #Define f(x,y) = x
461        f = array([0,0,2,0,2,4]) #f evaluated at points a-f
462
463        #Check that int (df/dx)**2 + (df/dy)**2 dx dy =
464        #           int 1 dx dy = total area = 8
465        assert dot(dot(f, interp.get_D()), f) == 8
466       
467        #Define f(x,y) = y
468        f = array([0,2,0,4,2,0]) #f evaluated at points a-f
469
470        #Check that int (df/dx)**2 + (df/dy)**2 dx dy =
471        #           int 1 dx dy = area = 8
472        assert dot(dot(f, interp.get_D()), f) == 8
473
474        #Define f(x,y) = x+y
475        f = array([0,2,2,4,4,4])  #f evaluated at points a-f   
476
477        #Check that int (df/dx)**2 + (df/dy)**2 dx dy =
478        #           int 2 dx dy = 2*area = 16
479        assert dot(dot(f, interp.get_D()), f) == 16       
480
481
482    def test_fit_and_interpolation(self):
483        from mesh import Mesh
484       
485        a = [0.0, 0.0]
486        b = [0.0, 2.0]
487        c = [2.0, 0.0]
488        d = [0.0, 4.0]
489        e = [2.0, 2.0]
490        f = [4.0, 0.0]
491
492        points = [a, b, c, d, e, f]
493        #bac, bce, ecf, dbe, daf, dae
494        triangles = [[1,0,2], [1,2,4], [4,2,5], [3,1,4]]
495
496        #Get (enough) datapoints
497        data_points = [[ 0.66666667, 0.66666667],
498                       [ 1.33333333, 1.33333333],
499                       [ 2.66666667, 0.66666667],
500                       [ 0.66666667, 2.66666667],
501                       [ 0.0, 1.0],
502                       [ 0.0, 3.0],
503                       [ 1.0, 0.0],
504                       [ 1.0, 1.0],
505                       [ 1.0, 2.0],
506                       [ 1.0, 3.0],                                         
507                       [ 2.0, 1.0],
508                       [ 3.0, 0.0],
509                       [ 3.0, 1.0]]                                         
510       
511        interp = Interpolation(points, triangles, data_points, alpha=0.0)
512
513        z = linear_function(data_points)
514        answer = linear_function(points)
515
516        f = interp.fit(z)
517
518        #print "f",f
519        #print "answer",answer
520        assert allclose(f, answer)
521
522        #Map back
523        z1 = interp.interpolate(f)
524        #print "z1\n", z1
525        #print "z\n",z
526        assert allclose(z, z1)
527
528
529    def test_smoothing_and_interpolation(self):
530       
531        a = [0.0, 0.0]
532        b = [0.0, 2.0]
533        c = [2.0, 0.0]
534        d = [0.0, 4.0]
535        e = [2.0, 2.0]
536        f = [4.0, 0.0]
537
538        points = [a, b, c, d, e, f]
539        #bac, bce, ecf, dbe, daf, dae
540        triangles = [[1,0,2], [1,2,4], [4,2,5], [3,1,4]]
541
542        #Get (too few!) datapoints
543        data_points = [[ 0.66666667, 0.66666667],
544                       [ 1.33333333, 1.33333333],
545                       [ 2.66666667, 0.66666667],
546                       [ 0.66666667, 2.66666667]]
547
548        z = linear_function(data_points)
549        answer = linear_function(points)       
550
551        #Make interpolator with too few data points and no smoothing
552        interp = Interpolation(points, triangles, data_points, alpha=0.0)
553        #Must raise an exception       
554        try:
555            f = interp.fit(z)
556        except:
557            pass
558
559        #Now try with smoothing parameter
560        interp = Interpolation(points, triangles, data_points, alpha=1.0e-13)
561       
562        f = interp.fit(z)
563        #f will be different from answerr due to smoothing
564        assert allclose(f, answer,atol=5)
565
566        #Map back
567        z1 = interp.interpolate(f)
568        assert allclose(z, z1)
569
570    def test_fit_to_mesh_file(self):
571        from load_mesh.loadASCII import mesh_file_to_mesh_dictionary, \
572             export_trianglulation_file   
573        import tempfile
574        import os
575       
576        # create a .tsh file, no user outline
577        mesh_dic = {}
578        mesh_dic['generatedpointlist'] = [[0.0, 0.0],
579                                          [0.0, 5.0],
580                                          [5.0, 0.0]]
581        mesh_dic['generatedtrianglelist'] =  [[0, 2, 1]]
582        mesh_dic['generatedsegmentlist'] = [[0, 1], [2, 0], [1, 2]]
583        mesh_dic['generatedtriangleattributelist'] = [['']]
584        mesh_dic['generatedpointattributelist'] = [[], [], []]
585        mesh_dic['generatedpointattributetitlelist'] = []
586        mesh_dic['generatedtriangleneighborlist'] = [[-1, -1, -1]]
587        mesh_dic['generatedsegmentmarkerlist'] = ['external',
588                                                  'external',
589                                                  'external']       
590        mesh_file = tempfile.mktemp(".tsh")
591        export_trianglulation_file(mesh_file,mesh_dic)
592       
593        # create an .xya file
594        point_file = tempfile.mktemp(".xya")
595        fd = open(point_file,'w')
596        fd.write("elevation, stage \n 1.0, 1.0,2.,4 \n 1.0, 3.0,4,8 \n 3.0,1.0,4.,8 \n")
597        fd.close()
598       
599        mesh_output_file = "new_trianlge.tsh"
600        fit_to_mesh_file(mesh_file,
601                         point_file,
602                         mesh_output_file,
603                         alpha = 0.0) 
604        # load in the .tsh file we just wrote
605        mesh_dic = mesh_file_to_mesh_dictionary(mesh_output_file)
606
607        assert allclose(mesh_dic['generatedpointattributelist'],
608                        [[0.0, 0.0],
609                         [5.0, 10.0],
610                         [5.0,10.0]])
611       
612        self.failUnless(mesh_dic['generatedpointattributetitlelist']  ==
613                        ['elevation','stage'],
614                        'test_fit_to_mesh_file failed')
615       
616        #clean up
617        os.remove(mesh_file)
618        os.remove(point_file)
619       
620    def test_fit_to_mesh_fileII(self):
621        from load_mesh.loadASCII import mesh_file_to_mesh_dictionary, \
622             export_trianglulation_file   
623        import tempfile
624        import os
625       
626        # create a .tsh file, no user outline
627        mesh_dic = {}
628        mesh_dic['generatedpointlist'] = [[0.0, 0.0],
629                                          [0.0, 5.0],
630                                          [5.0, 0.0]]
631        mesh_dic['generatedtrianglelist'] =  [[0, 2, 1]]
632        mesh_dic['generatedsegmentlist'] = [[0, 1], [2, 0], [1, 2]]
633        mesh_dic['generatedtriangleattributelist'] = [['']]
634        mesh_dic['generatedpointattributelist'] = [[1,2], [1,2], [1,2]]
635        mesh_dic['generatedpointattributetitlelist'] = ['density', 'temp']
636        mesh_dic['generatedtriangleneighborlist'] = [[-1, -1, -1]]
637        mesh_dic['generatedsegmentmarkerlist'] = ['external',
638                                                  'external',
639                                                  'external']       
640        mesh_file = tempfile.mktemp(".tsh")
641        export_trianglulation_file(mesh_file,mesh_dic)
642       
643        # create an .xya file
644        point_file = tempfile.mktemp(".xya")
645        fd = open(point_file,'w')
646        fd.write("elevation, stage \n 1.0, 1.0,2.,4 \n 1.0, 3.0,4,8 \n 3.0,1.0,4.,8 \n")
647        fd.close()
648       
649        mesh_output_file = "new_trianlge.tsh"
650        fit_to_mesh_file(mesh_file,
651                         point_file,
652                         mesh_output_file,
653                         alpha = 0.0) 
654        # load in the .tsh file we just wrote
655        mesh_dic = mesh_file_to_mesh_dictionary(mesh_output_file)
656
657        assert allclose(mesh_dic['generatedpointattributelist'],
658                        [[1.0, 2.0,0.0, 0.0],
659                         [1.0, 2.0,5.0, 10.0],
660                         [1.0, 2.0,5.0,10.0]])
661       
662        self.failUnless(mesh_dic['generatedpointattributetitlelist']  ==
663                        ['density', 'temp','elevation','stage'],
664                        'test_fit_to_mesh_file failed')
665       
666        #clean up
667        os.remove(mesh_file)
668        os.remove(point_file)
669       
670#-------------------------------------------------------------
671if __name__ == "__main__":
672    suite = unittest.makeSuite(TestCase,'test')
673    runner = unittest.TextTestRunner()   #(verbosity=2)
674    runner.run(suite)
675
676   
677   
678
679
680
Note: See TracBrowser for help on using the repository browser.