1 package Math::GSL::Eigen::Test;
2 use base q{Test::Class};
3 use Test::More tests => 39;
4 use Math::GSL qw/:all/;
5 use Math::GSL::Test qw/:all/;
6 use Math::GSL::Eigen qw/:all/;
7 use Math::GSL::Matrix qw/:all/;
8 use Math::GSL::Vector qw/:all/;
9 use Math::GSL::Complex qw/:all/;
10 use Math::GSL::Machine qw/:all/;
11 use Math::GSL::MatrixComplex qw/:all/;
15 sub make_fixture : Test(setup) {
17 $self->{eigen} = gsl_eigen_symm_alloc(2);
20 sub teardown : Test(teardown) {
23 sub GSL_EIGEN_SYMM_ALLOC : Tests {
25 isa_ok($self->{eigen}, 'Math::GSL::Eigen');
28 sub GSL_EIGEN_SYMMV_ALLOC : Tests {
29 my $eigen = gsl_eigen_symmv_alloc(5);
30 isa_ok($eigen, 'Math::GSL::Eigen');
33 sub GSL_EIGEN_HERM_ALLOC : Tests {
34 my $eigen = gsl_eigen_herm_alloc(5);
35 isa_ok($eigen, 'Math::GSL::Eigen');
38 sub GSL_EIGEN_HERMV_ALLOC : Tests {
39 my $eigen = gsl_eigen_hermv_alloc(5);
40 isa_ok($eigen, 'Math::GSL::Eigen');
43 sub GSL_EIGEN_NONSYMM_ALLOC : Tests {
44 my $eigen = gsl_eigen_nonsymm_alloc(5);
45 isa_ok($eigen, 'Math::GSL::Eigen');
48 sub GSL_EIGEN_NONSYMMV_ALLOC : Tests {
49 my $eigen = gsl_eigen_nonsymmv_alloc(5);
50 isa_ok($eigen, 'Math::GSL::Eigen');
53 sub GSL_EIGEN_GENSYMM_ALLOC : Tests {
54 my $eigen = gsl_eigen_gensymm_alloc(5);
55 isa_ok($eigen, 'Math::GSL::Eigen');
58 sub GSL_EIGEN_GENSYMMV_ALLOC : Tests {
59 my $eigen = gsl_eigen_gensymmv_alloc(5);
60 isa_ok($eigen, 'Math::GSL::Eigen');
63 sub GSL_EIGEN_GENHERM_ALLOC : Tests {
64 my $eigen = gsl_eigen_genherm_alloc(5);
65 isa_ok($eigen, 'Math::GSL::Eigen');
68 sub GSL_EIGEN_GENHERMV_ALLOC : Tests {
69 my $eigen = gsl_eigen_genhermv_alloc(5);
70 isa_ok($eigen, 'Math::GSL::Eigen');
73 sub GSL_EIGEN_GEN_ALLOC : Tests {
74 my $eigen = gsl_eigen_gen_alloc(5);
75 isa_ok($eigen, 'Math::GSL::Eigen');
78 sub GSL_EIGEN_GENV_ALLOC : Tests {
79 my $eigen = gsl_eigen_genv_alloc(5);
80 isa_ok($eigen, 'Math::GSL::Eigen');
83 sub GSL_EIGEN_SYMM : Tests {
85 my $m = gsl_matrix_alloc(2,2);
86 my $v = Math::GSL::Vector->new(2);
87 gsl_matrix_set_identity($m);
88 ok_status(gsl_eigen_symm($m, $v->raw, $self->{eigen}));
89 ok_similar( [ sort $v->as_list ], [ 1, 1 ] );
92 sub GSL_EIGEN_SYMMV : Tests {
93 my $w = gsl_eigen_symmv_alloc(2);
94 my $m = gsl_matrix_alloc(2,2);
95 gsl_matrix_set($m, 0, 0, 2);
96 gsl_matrix_set($m, 0, 1, 1);
97 gsl_matrix_set($m, 1, 0, 1);
98 gsl_matrix_set($m, 1, 1, 2);
99 my $eval = gsl_vector_alloc(2);
100 my $evec = gsl_matrix_alloc(2,2);
101 ok_status(gsl_eigen_symmv($m, $eval, $evec, $w));
102 is_similar(gsl_vector_get($eval, 0), 3);
103 is_similar(gsl_vector_get($eval, 1), 1);
104 my $x = gsl_matrix_get($evec, 0, 0);
106 #this is the eigenvector for the eigenvalue 1, which is the second
107 #eigenvalue in the $eval vector, but the GSL documentation says the first
108 #eigenvector should correspond to the first eigenvalue... where'e the error?
110 is_similar(gsl_matrix_get($evec, 0, 1), -$x);
112 is_similar (sqrt($x**2+$x**2), 1);
114 $x = gsl_matrix_get($evec, 1, 0);
115 is_similar(gsl_matrix_get($evec, 1, 1), $x);
116 is_similar(sqrt($x**2+$x**2), 1);
118 my $v1 = gsl_vector_alloc(2);
119 my $v2 = gsl_vector_alloc(2);
120 gsl_matrix_get_col($v1, $evec, 0);
121 gsl_matrix_get_col($v2, $evec, 1);
122 gsl_vector_mul($v1, $v2);
123 is_similar(gsl_vector_get($v1, 0) + gsl_vector_get($v1, 1) , 0);
126 sub GSL_EIGEN_SYMMV_SORT : Tests {
127 my $w = gsl_eigen_symmv_alloc(2);
128 my $m = gsl_matrix_alloc(2,2);
129 gsl_matrix_set($m, 0, 0, 2);
130 gsl_matrix_set($m, 0, 1, 1);
131 gsl_matrix_set($m, 1, 0, 1);
132 gsl_matrix_set($m, 1, 1, 2);
133 my $eval = gsl_vector_alloc(2);
134 my $evec = gsl_matrix_alloc(2,2);
135 ok_status(gsl_eigen_symmv($m, $eval, $evec, $w));
136 ok_status(gsl_eigen_symmv_sort ($eval, $evec, $GSL_EIGEN_SORT_VAL_ASC));
137 is_similar(gsl_vector_get($eval, 0), 1);
138 is_similar(gsl_vector_get($eval, 1), 3);
139 my $x = gsl_matrix_get($evec, 0, 0);
140 ok_similar(gsl_matrix_get($evec, 0, 1), -$x);
141 ok_similar(sqrt($x**2+$x**2), 1);
143 $x = gsl_matrix_get($evec, 1, 0);
144 ok_similar(gsl_matrix_get($evec, 1, 1), $x);
145 ok_similar(sqrt($x**2+$x**2), 1);
147 my $v1 = gsl_vector_alloc(2);
148 my $v2 = gsl_vector_alloc(2);
149 gsl_matrix_get_col($v1, $evec, 0);
150 gsl_matrix_get_col($v2, $evec, 1);
151 gsl_vector_mul($v1, $v2);
152 is_similar(gsl_vector_get($v1, 0) + gsl_vector_get($v1, 1) , 0);
155 sub GSL_EIGEN_HERM : Tests {
156 my $matrix = gsl_matrix_complex_alloc (2, 2);
157 my $complex = gsl_complex_rect(3,0);
158 gsl_matrix_complex_set($matrix, 0, 0, $complex);
160 $complex = gsl_complex_rect(2,1);
161 gsl_matrix_complex_set($matrix, 0, 1, $complex);
163 $complex = gsl_complex_rect(2,-1);
164 gsl_matrix_complex_set($matrix, 1, 0, $complex);
166 $complex = gsl_complex_rect(1,0);
167 gsl_matrix_complex_set($matrix, 1, 1, $complex);
169 my $eigen = gsl_eigen_herm_alloc(2);
170 my $vector = gsl_vector_alloc(2);
171 ok_status(gsl_eigen_herm($matrix, $vector, $eigen));
172 is_similar(gsl_vector_get($vector, 0), 2+sqrt(6));
173 is_similar(gsl_vector_get($vector, 1), 2-sqrt(6));
175 sub GSL_EIGEN_HERMV : Tests {
176 my $matrix = gsl_matrix_complex_alloc (2, 2);
177 my $complex = gsl_complex_rect(3,0);
178 gsl_matrix_complex_set($matrix, 0, 0, $complex);
180 $complex = gsl_complex_rect(2,1);
181 gsl_matrix_complex_set($matrix, 0, 1, $complex);
183 $complex = gsl_complex_rect(2,-1);
184 gsl_matrix_complex_set($matrix, 1, 0, $complex);
186 $complex = gsl_complex_rect(1,0);
187 gsl_matrix_complex_set($matrix, 1, 1, $complex);
189 my $eigen = gsl_eigen_hermv_alloc(2);
190 my $vector = gsl_vector_alloc(2);
191 my $evec = gsl_matrix_complex_alloc(2,2);
192 ok_status(gsl_eigen_hermv($matrix, $vector, $evec, $eigen));
193 is_similar(gsl_vector_get($vector, 0), 2+sqrt(6));
194 is_similar(gsl_vector_get($vector, 1), 2-sqrt(6));
196 # my $x = gsl_matrix_complex_get($evec, 1, 1);
197 # ok_similar( [ gsl_parts($x) ], [-0.750532688285823, 0 ], "last row");
198 # ok_similar( [ gsl_parts($x) ], [ 2/(-1+sqrt(6)), 1/(-1+sqrt(6)) ], "first value");
202 sub GSL_EIGEN_NONSYMM : Tests {
203 my $matrix = gsl_matrix_alloc (2, 2);
204 gsl_matrix_set($matrix, 0, 0, -12);
205 gsl_matrix_set($matrix, 1, 0, 7);
206 gsl_matrix_set($matrix, 0, 1, 65);
207 gsl_matrix_set($matrix, 1, 1, 59);
209 my $eigen = gsl_eigen_nonsymm_alloc(2);
210 my $vector = gsl_vector_complex_alloc(2);
211 ok_status(gsl_eigen_nonsymm($matrix, $vector, $eigen));
213 my $x = gsl_vector_complex_real($vector);
214 my $y = gsl_vector_complex_imag($vector);
216 # this interface seems hokey
217 is_similar( gsl_vector_get($x->{vector}, 1), (47/2)+(0.5*sqrt(6861)) );
218 is_similar( gsl_vector_get($y->{vector}, 1), 0 );
221 sub GSL_EIGEN_NONSYMM_Z : Tests {
222 my $matrix = gsl_matrix_alloc (2, 2);
223 gsl_matrix_set($matrix, 0, 0, -12);
224 gsl_matrix_set($matrix, 1, 0, 7);
225 gsl_matrix_set($matrix, 0, 1, 65);
226 gsl_matrix_set($matrix, 1, 1, 59);
228 my $eigen = gsl_eigen_nonsymm_alloc(2);
229 my $vector = gsl_vector_complex_alloc(2);
230 my $Z = gsl_matrix_alloc(2,2);
231 ok_status(gsl_eigen_nonsymm($matrix, $vector, $eigen));
232 ok_status(gsl_eigen_nonsymm_Z($matrix,$vector, $Z, $eigen));
233 ok_similar(gsl_matrix_get($Z, 0, 0), 0.9958842418254068860784291, "Z matrix", 0.005);
234 ok_similar(gsl_matrix_get($Z, 0, 1), 0.09063430301952179629793610, "Z matrix", 0.1);
235 ok_similar(gsl_matrix_get($Z, 1, 1), 0.9958842418254068860784291, "Z matrix", 0.005);
236 ok_similar(gsl_matrix_get($Z, 1, 0), 0.09063430301952179629793610, "Z matrix", 0.1);
238 my $x = gsl_vector_complex_real($vector);
239 my $y = gsl_vector_complex_imag($vector);
241 # this interface seems hokey
242 is_similar( gsl_vector_get($x->{vector}, 1), (47/2)+(0.5*sqrt(6861)) );
243 is_similar( gsl_vector_get($y->{vector}, 1), 0 );
246 sub GSL_EIGEN_NONSYMMV : Tests {
247 my $matrix = gsl_matrix_alloc (2, 2);
248 gsl_matrix_set($matrix, 0, 0, -12);
249 gsl_matrix_set($matrix, 1, 0, 7);
250 gsl_matrix_set($matrix, 0, 1, 65);
251 gsl_matrix_set($matrix, 1, 1, 59);
253 my $evec = gsl_matrix_complex_alloc(2,2);
254 my $eigen = gsl_eigen_nonsymmv_alloc(2);
255 my $vector = gsl_vector_complex_alloc(2);
256 ok_status(gsl_eigen_nonsymmv($matrix,$vector, $evec, $eigen));
259 my $x = gsl_vector_complex_real($vector);
260 my $y = gsl_vector_complex_imag($vector);
262 # this interface seems hokey
263 is_similar( gsl_vector_get($x->{vector}, 1), (47/2)+(0.5*sqrt(6861)) );
264 is_similar( gsl_vector_get($y->{vector}, 1), 0 );
266 $x = gsl_matrix_complex_get($evec, 1, 0);
267 ok_similar(gsl_imag($x), 0, "evec matrix");
268 ok_similar(gsl_real($x), 7/((71/2)+(.5*sqrt(6861))), "evec matrix", 0.01);
270 $x = gsl_matrix_complex_get($evec, 0, 0);
271 ok_similar(gsl_imag($x), 0, "evec matrix");
272 ok_similar(gsl_real($x), 7/((71/2)-(.5*sqrt(6861))), "evec matrix", 0.19);
274 $x = gsl_matrix_complex_get($evec, 0, 1);
275 $y = gsl_matrix_complex_get($evec, 1, 1);
277 ok_similar(gsl_imag($x), 0, "evec matrix");
278 ok_similar(gsl_imag($y), 0, "evec matrix");
280 local $TODO = "matlab differences";
281 ok_similar(gsl_real($x), 1); # this is the value I get with maple
282 ok_similar(gsl_real($y), 1); # this is the value I get with maple
286 Test::Class->runtests;