source: branches/source_numpy_conversion/anuga/utilities/test_numerical_tools.py @ 6982

Last change on this file since 6982 was 5902, checked in by rwilson, 16 years ago

NumPy? conversion.

File size: 10.7 KB
Line 
1#!/usr/bin/env python
2
3
4import unittest
5import numpy
6
7from math import sqrt, pi
8from anuga.config import epsilon
9from numerical_tools import *
10
11def test_function(x, y):
12    return x+y
13
14class Test_Numerical_Tools(unittest.TestCase):
15    def setUp(self):
16        pass
17
18    def tearDown(self):
19        pass
20
21    def test_angle1(self):
22        """Test angles between one vector and the x-axis
23        """
24        assert numpy.allclose(angle([1.0, 0.0])/pi*180, 0.0)       
25        assert numpy.allclose(angle([1.0, 1.0])/pi*180, 45.0)
26        assert numpy.allclose(angle([0.0, 1.0])/pi*180, 90.0)           
27        assert numpy.allclose(angle([-1.0, 1.0])/pi*180, 135.0)         
28        assert numpy.allclose(angle([-1.0, 0.0])/pi*180, 180.0)
29        assert numpy.allclose(angle([-1.0, -1.0])/pi*180, 225.0)
30        assert numpy.allclose(angle([0.0, -1.0])/pi*180, 270.0)
31        assert numpy.allclose(angle([1.0, -1.0])/pi*180, 315.0)
32               
33                                                         
34    def test_angle2(self):
35        """Test angles between two arbitrary vectors
36        """   
37       
38        assert numpy.allclose(angle([1.0, 0.0], [1.0, 1.0])/pi*180, 315.0)
39        assert numpy.allclose(angle([1.0, 1.0], [1.0, 0.0])/pi*180, 45.0)
40               
41        assert numpy.allclose(angle([-1.0, -1.0], [1.0, 1.0])/pi*180, 180)     
42        assert numpy.allclose(angle([-1.0, -1.0], [-1.0, 1.0])/pi*180, 90.0)   
43       
44        assert numpy.allclose(angle([-1.0, 0.0], [1.0, 1.0])/pi*180, 135.0)
45        assert numpy.allclose(angle([0.0, -1.0], [1.0, 1.0])/pi*180, 225.0)     
46       
47        assert numpy.allclose(angle([1.0, -1.0], [1.0, 1.0])/pi*180, 270.0)     
48        assert numpy.allclose(angle([1.0, 0.0], [0.0, 1.0])/pi*180, 270.0)
49
50        #From test_get_boundary_polygon_V
51        v_prev = [-0.5, -0.5]
52        vc = [ 0.0,  -0.5]
53        assert numpy.allclose(angle(vc, v_prev)/pi*180, 45.0)
54
55        vc = [ 0.5,  0.0]
56        assert numpy.allclose(angle(vc, v_prev)/pi*180, 135.0)
57
58        vc = [ -0.5,  0.5]
59        assert numpy.allclose(angle(vc, v_prev)/pi*180, 270.0)               
60
61
62    def test_anglediff(self):
63        assert numpy.allclose(anglediff([0.0, 1.], [1.0, 1.0])/pi*180, 45.0)
64
65       
66    def test_ensure_numeric(self):
67        A = [1,2,3,4]
68        B = ensure_numeric(A)
69        assert isinstance(B, numpy.ndarray)
70        assert B.dtype.char == 'l'
71        assert B[0] == 1 and B[1] == 2 and B[2] == 3 and B[3] == 4
72
73        A = [1,2,3.14,4]
74        B = ensure_numeric(A)
75        assert isinstance(B, numpy.ndarray)
76        assert B.dtype.char == 'd'
77        assert B[0] == 1 and B[1] == 2 and B[2] == 3.14 and B[3] == 4
78
79        A = [1,2,3,4]
80        B = ensure_numeric(A, numpy.float)
81        assert isinstance(B, numpy.ndarray)
82        assert B.dtype.char == 'd'
83        assert B[0] == 1.0 and B[1] == 2.0 and B[2] == 3.0 and B[3] == 4.0
84
85        A = [1,2,3,4]
86        B = ensure_numeric(A, numpy.float)
87        assert isinstance(B, numpy.ndarray)
88        assert B.dtype.char == 'd'
89        assert B[0] == 1.0 and B[1] == 2.0 and B[2] == 3.0 and B[3] == 4.0
90
91        A = numpy.array([1,2,3,4])
92        B = ensure_numeric(A)
93        assert isinstance(B, numpy.ndarray)
94        assert B.dtype.char == 'l'       
95        assert numpy.alltrue(A == B)   
96        assert A is B   #Same object
97
98        A = numpy.array([1,2,3,4])
99        B = ensure_numeric(A, numpy.float)
100        assert isinstance(B, numpy.ndarray)
101        assert B.dtype.char == 'd'       
102        assert numpy.alltrue(A == B)   
103        assert A is not B   #Not the same object
104
105        # Check scalars
106        A = 1
107        B = ensure_numeric(A, numpy.float)
108        #print A, B[0], len(B), type(B)
109        #print B.shape
110        assert numpy.alltrue(A == B)
111
112        B = ensure_numeric(A, numpy.int)       
113        #print A, B
114        #print B.shape
115        assert numpy.alltrue(A == B)
116
117    def NO_test_ensure_numeric_char(self):
118        # Error situation
119        B = ensure_numeric('hello', numpy.int)
120        print 'B=%s %s' % (str(B), type(B))
121        assert numpy.allclose(B, [104, 101, 108, 108, 111])
122
123
124    def test_gradient(self):
125        x0 = 0.0; y0 = 0.0; z0 = 0.0
126        x1 = 1.0; y1 = 0.0; z1 = -1.0
127        x2 = 0.0; y2 = 1.0; z2 = 0.0
128
129        zx, zy = gradient(x0, y0, x1, y1, x2, y2, z0, z1, z2)
130
131        assert zx == -1.0
132        assert zy == 0.0
133
134
135    def test_gradient_more(self):
136        x0 = 2.0/3; y0 = 2.0/3
137        x1=  8.0/3; y1 = 2.0/3
138        x2 = 2.0/3; y2 = 8.0/3
139
140        q0 = 2.0+2.0/3
141        q1 = 8.0+2.0/3
142        q2 = 2.0+8.0/3
143
144        #Gradient of fitted pwl surface
145        a, b = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2)
146
147        assert abs(a - 3.0) < epsilon
148        assert abs(b - 1.0) < epsilon
149
150
151    def test_gradient2(self):
152        """Test two-point gradient
153        """
154       
155        x0 = 5.0; y0 = 5.0; z0 = 10.0
156        x1 = 8.0; y1 = 2.0; z1 = 1.0
157        x2 = 8.0; y2 = 8.0; z2 = 10.0
158
159        #Reference
160        zx, zy = gradient(x0, y0, x1, y1, x2, y2, z0, z1, z2)
161        a, b = gradient2(x0, y0, x1, y1, z0, z1)
162       
163        assert zx == a
164        assert zy == b
165
166        z2_computed = z0 + a*(x2-x0) + b*(y2-y0)
167        assert z2_computed == z2
168
169       
170    def test_gradient2_more(self):
171        """Test two-point gradient more
172        """
173        x0 = 2.0; y0 = 2.0
174        x1 = 8.0; y1 = 3.0
175        x2 = 1.0; y2 = 8.0
176
177        q0 = 2.0
178        q1 = 8.0
179        q2 = q0
180
181        #Gradient of fitted pwl surface
182        a_ref, b_ref = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2)
183        a, b = gradient2(x0, y0, x1, y1, q0, q1)       
184
185        assert a == a_ref
186        assert b == b_ref
187
188
189    def test_machine_precision(self):
190        """test_machine_precision(self):
191        Test the function that calculates epsilon. As this varies on
192        different machines, this is only an indication.
193        """
194
195        eps = get_machine_precision()
196
197        assert eps < 1.0e-12, 'Machine precision should be better than 1.0e-12'
198        assert eps > 0.0
199        assert 1.0+eps/2 == 1.0
200       
201       
202    def test_histogram(self):
203        """Test histogram with different bin boundaries
204        """
205       
206        a = [1,1,1,1,1,2,1,3,2,3,1,2,3,4,1]
207
208        #There are four elements greater than or equal to 3
209        bins = [3]
210        assert numpy.allclose(histogram(a, bins), [4])
211
212        bins = [ min(a) ]
213        assert numpy.allclose(histogram(a, bins), [len(a)])
214
215        bins = [ max(a)+0.00001 ]
216        assert numpy.allclose(histogram(a, bins), [0])       
217       
218        bins = [1,2,3,4]
219        assert numpy.allclose(histogram(a, bins), [8,3,3,1])
220
221        bins = [1.1,2,3.1,4]
222        #print histogram(a, bins)
223        assert numpy.allclose(histogram(a, bins), [0,6,0,1])
224
225        bins = [0,1.5,2,3]
226        assert numpy.allclose(histogram(a, bins), [8,0,3,4])
227        assert numpy.allclose(histogram(a, [0,3]), histogram(a, [-0.5,3]))
228
229        # Check situation with #bins >= #datapoints
230        a = [1.7]
231        bins = [0,1.5,2,3]
232        assert numpy.allclose(histogram(a, bins), [0,1,0,0])
233
234        a = [1.7]
235        bins = [0]
236        assert numpy.allclose(histogram(a, bins), [1])
237
238        a = [-1.7]
239        bins = [0]
240        assert numpy.allclose(histogram(a, bins), [0])
241
242        a = [-1.7]
243        bins = [-1.7]
244        assert numpy.allclose(histogram(a, bins), [1])       
245       
246
247    def test_that_C_extension_compiles(self):
248        FN = 'util_ext.c'
249        try:
250            import util_ext
251        except:
252            from compile import compile
253
254            try:
255                compile(FN)
256            except:
257                raise 'Could not compile %s' %FN
258            else:
259                import util_ext
260
261
262    def test_gradient_C_extension(self):
263        from util_ext import gradient as gradient_c
264
265        x0 = 2.0/3; y0 = 2.0/3
266        x1=  8.0/3; y1 = 2.0/3
267        x2 = 2.0/3; y2 = 8.0/3
268
269        q0 = 2.0+2.0/3
270        q1 = 8.0+2.0/3
271        q2 = 2.0+8.0/3
272
273        #Gradient of fitted pwl surface
274        a, b = gradient_c(x0, y0, x1, y1, x2, y2, q0, q1, q2)
275
276        assert abs(a - 3.0) < epsilon
277        assert abs(b - 1.0) < epsilon
278
279
280    def test_gradient_C_extension3(self):
281        from util_ext import gradient as gradient_c
282
283        from numpy.random import uniform, seed
284        seed(53)    # numeric was seed(17, 53)
285
286        x0, x1, x2, y0, y1, y2 = uniform(0.0,3.0,6)
287
288        q0 = uniform(0.0, 10.0, 4)
289        q1 = uniform(1.0, 3.0, 4)
290        q2 = uniform(7.0, 20.0, 4)
291
292        for i in range(4):
293            #Gradient of fitted pwl surface
294            a_ref, b_ref = gradient_python(x0, y0, x1, y1, x2, y2,
295                                           q0[i], q1[i], q2[i])
296
297            #print a_ref, b_ref
298            a, b = gradient_c(x0, y0, x1, y1, x2, y2,
299                              q0[i], q1[i], q2[i])
300
301            #print a, a_ref, b, b_ref
302            assert abs(a - a_ref) < epsilon
303            assert abs(b - b_ref) < epsilon
304
305     
306    def test_err(self):
307        x = [2,5] # diff at first position = 4, 4^2 = 16
308        y = [6,7] # diff at secnd position = 2, 2^2 = 4
309        # 16 + 4 = 20
310       
311        # If there is x and y, n=2 and relative=False, this will calc;
312        # sqrt(sum_over_x&y((xi - yi)^2))
313        err__1 = err(x,y,2,False)
314       
315        assert err__1 == sqrt(20)
316        #print "err_", err_
317        #rmsd_1 = err__1*sqrt(1./len(x))
318        #print "err__1*sqrt(1./len(x))", err__1*sqrt(1./len(x))
319        #print "sqrt(10)", sqrt(10)
320       
321        x = [2,7,100]
322        y = [5,10,103]
323        err__2 = err(x,y,2,False)
324        assert err__2 == sqrt(27)
325        #rmsd_2 = err__2*sqrt(1./len(x))
326        #print "err__2*sqrt(1./len(x))", err__2*sqrt(1./len(x))
327
328        x = [2,5,2,7,100]
329        y = [6,7,5,10,103]
330        err_3 = err(x,y,2,False)
331        assert err_3 == sqrt(47)
332       
333        #rmsd_3 = err_3*sqrt(1./len(x))
334        #print "err__3*sqrt(1./len(x))", err__3*sqrt(1./len(x))
335        #print "rmsd_3", rmsd_3
336        #print "sqrt(err_1*err__1+err__2*err__2)/sqrt(5)", \
337        # sqrt(err__1*err__1+err__2*err__2)/sqrt(5)
338        #print "(rmsd_1 + rmsd_2)/2.", (rmsd_1 + rmsd_2)/2.
339        #print "sqrt((rmsd_1*rmsd_1 + rmsd_2*rmsd_2))/2.", \
340        #sqrt((rmsd_1*rmsd_1 + rmsd_2*rmsd_2))/2.
341       
342    def test_norm(self):
343        x = norm(ensure_numeric([3,4]))
344        assert x == 5.
345
346                                   
347
348#-------------------------------------------------------------
349if __name__ == "__main__":
350    suite = unittest.makeSuite(Test_Numerical_Tools,'test')
351    #suite = unittest.makeSuite(Test_Numerical_Tools,'test_err')
352    runner = unittest.TextTestRunner()
353    runner.run(suite)
Note: See TracBrowser for help on using the repository browser.