alglib 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (255) hide show
  1. data/History.txt +7 -0
  2. data/Manifest.txt +253 -0
  3. data/README.txt +33 -0
  4. data/Rakefile +27 -0
  5. data/ext/Rakefile +24 -0
  6. data/ext/alglib.i +24 -0
  7. data/ext/alglib/Makefile +157 -0
  8. data/ext/alglib/airyf.cpp +372 -0
  9. data/ext/alglib/airyf.h +81 -0
  10. data/ext/alglib/alglib.cpp +8558 -0
  11. data/ext/alglib/alglib_util.cpp +19 -0
  12. data/ext/alglib/alglib_util.h +14 -0
  13. data/ext/alglib/ap.cpp +877 -0
  14. data/ext/alglib/ap.english.html +364 -0
  15. data/ext/alglib/ap.h +666 -0
  16. data/ext/alglib/ap.russian.html +442 -0
  17. data/ext/alglib/apvt.h +754 -0
  18. data/ext/alglib/bdss.cpp +1500 -0
  19. data/ext/alglib/bdss.h +251 -0
  20. data/ext/alglib/bdsvd.cpp +1339 -0
  21. data/ext/alglib/bdsvd.h +164 -0
  22. data/ext/alglib/bessel.cpp +1226 -0
  23. data/ext/alglib/bessel.h +331 -0
  24. data/ext/alglib/betaf.cpp +105 -0
  25. data/ext/alglib/betaf.h +74 -0
  26. data/ext/alglib/bidiagonal.cpp +1328 -0
  27. data/ext/alglib/bidiagonal.h +350 -0
  28. data/ext/alglib/binomialdistr.cpp +247 -0
  29. data/ext/alglib/binomialdistr.h +153 -0
  30. data/ext/alglib/blas.cpp +576 -0
  31. data/ext/alglib/blas.h +132 -0
  32. data/ext/alglib/cblas.cpp +226 -0
  33. data/ext/alglib/cblas.h +57 -0
  34. data/ext/alglib/cdet.cpp +138 -0
  35. data/ext/alglib/cdet.h +92 -0
  36. data/ext/alglib/chebyshev.cpp +216 -0
  37. data/ext/alglib/chebyshev.h +76 -0
  38. data/ext/alglib/chisquaredistr.cpp +157 -0
  39. data/ext/alglib/chisquaredistr.h +144 -0
  40. data/ext/alglib/cholesky.cpp +285 -0
  41. data/ext/alglib/cholesky.h +86 -0
  42. data/ext/alglib/cinverse.cpp +298 -0
  43. data/ext/alglib/cinverse.h +111 -0
  44. data/ext/alglib/clu.cpp +337 -0
  45. data/ext/alglib/clu.h +120 -0
  46. data/ext/alglib/correlation.cpp +280 -0
  47. data/ext/alglib/correlation.h +77 -0
  48. data/ext/alglib/correlationtests.cpp +726 -0
  49. data/ext/alglib/correlationtests.h +134 -0
  50. data/ext/alglib/crcond.cpp +826 -0
  51. data/ext/alglib/crcond.h +148 -0
  52. data/ext/alglib/creflections.cpp +310 -0
  53. data/ext/alglib/creflections.h +165 -0
  54. data/ext/alglib/csolve.cpp +312 -0
  55. data/ext/alglib/csolve.h +99 -0
  56. data/ext/alglib/ctrinverse.cpp +387 -0
  57. data/ext/alglib/ctrinverse.h +98 -0
  58. data/ext/alglib/ctrlinsolve.cpp +297 -0
  59. data/ext/alglib/ctrlinsolve.h +81 -0
  60. data/ext/alglib/dawson.cpp +234 -0
  61. data/ext/alglib/dawson.h +74 -0
  62. data/ext/alglib/descriptivestatistics.cpp +436 -0
  63. data/ext/alglib/descriptivestatistics.h +112 -0
  64. data/ext/alglib/det.cpp +140 -0
  65. data/ext/alglib/det.h +94 -0
  66. data/ext/alglib/dforest.cpp +1819 -0
  67. data/ext/alglib/dforest.h +316 -0
  68. data/ext/alglib/elliptic.cpp +497 -0
  69. data/ext/alglib/elliptic.h +217 -0
  70. data/ext/alglib/estnorm.cpp +429 -0
  71. data/ext/alglib/estnorm.h +107 -0
  72. data/ext/alglib/expintegrals.cpp +422 -0
  73. data/ext/alglib/expintegrals.h +108 -0
  74. data/ext/alglib/faq.english.html +258 -0
  75. data/ext/alglib/faq.russian.html +272 -0
  76. data/ext/alglib/fdistr.cpp +202 -0
  77. data/ext/alglib/fdistr.h +163 -0
  78. data/ext/alglib/fresnel.cpp +211 -0
  79. data/ext/alglib/fresnel.h +91 -0
  80. data/ext/alglib/gammaf.cpp +338 -0
  81. data/ext/alglib/gammaf.h +104 -0
  82. data/ext/alglib/gqgengauss.cpp +235 -0
  83. data/ext/alglib/gqgengauss.h +92 -0
  84. data/ext/alglib/gqgenhermite.cpp +268 -0
  85. data/ext/alglib/gqgenhermite.h +63 -0
  86. data/ext/alglib/gqgenjacobi.cpp +297 -0
  87. data/ext/alglib/gqgenjacobi.h +72 -0
  88. data/ext/alglib/gqgenlaguerre.cpp +265 -0
  89. data/ext/alglib/gqgenlaguerre.h +69 -0
  90. data/ext/alglib/gqgenlegendre.cpp +300 -0
  91. data/ext/alglib/gqgenlegendre.h +62 -0
  92. data/ext/alglib/gqgenlobatto.cpp +305 -0
  93. data/ext/alglib/gqgenlobatto.h +97 -0
  94. data/ext/alglib/gqgenradau.cpp +232 -0
  95. data/ext/alglib/gqgenradau.h +95 -0
  96. data/ext/alglib/hbisinv.cpp +480 -0
  97. data/ext/alglib/hbisinv.h +183 -0
  98. data/ext/alglib/hblas.cpp +228 -0
  99. data/ext/alglib/hblas.h +64 -0
  100. data/ext/alglib/hcholesky.cpp +339 -0
  101. data/ext/alglib/hcholesky.h +91 -0
  102. data/ext/alglib/hermite.cpp +114 -0
  103. data/ext/alglib/hermite.h +49 -0
  104. data/ext/alglib/hessenberg.cpp +370 -0
  105. data/ext/alglib/hessenberg.h +152 -0
  106. data/ext/alglib/hevd.cpp +247 -0
  107. data/ext/alglib/hevd.h +107 -0
  108. data/ext/alglib/hsschur.cpp +1316 -0
  109. data/ext/alglib/hsschur.h +108 -0
  110. data/ext/alglib/htridiagonal.cpp +734 -0
  111. data/ext/alglib/htridiagonal.h +180 -0
  112. data/ext/alglib/ialglib.cpp +6 -0
  113. data/ext/alglib/ialglib.h +9 -0
  114. data/ext/alglib/ibetaf.cpp +960 -0
  115. data/ext/alglib/ibetaf.h +125 -0
  116. data/ext/alglib/igammaf.cpp +430 -0
  117. data/ext/alglib/igammaf.h +157 -0
  118. data/ext/alglib/inv.cpp +274 -0
  119. data/ext/alglib/inv.h +115 -0
  120. data/ext/alglib/inverseupdate.cpp +480 -0
  121. data/ext/alglib/inverseupdate.h +185 -0
  122. data/ext/alglib/jacobianelliptic.cpp +164 -0
  123. data/ext/alglib/jacobianelliptic.h +94 -0
  124. data/ext/alglib/jarquebera.cpp +2271 -0
  125. data/ext/alglib/jarquebera.h +80 -0
  126. data/ext/alglib/kmeans.cpp +356 -0
  127. data/ext/alglib/kmeans.h +76 -0
  128. data/ext/alglib/laguerre.cpp +94 -0
  129. data/ext/alglib/laguerre.h +48 -0
  130. data/ext/alglib/lbfgs.cpp +1167 -0
  131. data/ext/alglib/lbfgs.h +218 -0
  132. data/ext/alglib/lda.cpp +434 -0
  133. data/ext/alglib/lda.h +133 -0
  134. data/ext/alglib/ldlt.cpp +1130 -0
  135. data/ext/alglib/ldlt.h +124 -0
  136. data/ext/alglib/leastsquares.cpp +1252 -0
  137. data/ext/alglib/leastsquares.h +290 -0
  138. data/ext/alglib/legendre.cpp +107 -0
  139. data/ext/alglib/legendre.h +49 -0
  140. data/ext/alglib/linreg.cpp +1185 -0
  141. data/ext/alglib/linreg.h +380 -0
  142. data/ext/alglib/logit.cpp +1523 -0
  143. data/ext/alglib/logit.h +333 -0
  144. data/ext/alglib/lq.cpp +399 -0
  145. data/ext/alglib/lq.h +160 -0
  146. data/ext/alglib/lu.cpp +462 -0
  147. data/ext/alglib/lu.h +119 -0
  148. data/ext/alglib/mannwhitneyu.cpp +4490 -0
  149. data/ext/alglib/mannwhitneyu.h +115 -0
  150. data/ext/alglib/minlm.cpp +918 -0
  151. data/ext/alglib/minlm.h +312 -0
  152. data/ext/alglib/mlpbase.cpp +3375 -0
  153. data/ext/alglib/mlpbase.h +589 -0
  154. data/ext/alglib/mlpe.cpp +1369 -0
  155. data/ext/alglib/mlpe.h +552 -0
  156. data/ext/alglib/mlptrain.cpp +1056 -0
  157. data/ext/alglib/mlptrain.h +283 -0
  158. data/ext/alglib/nearunityunit.cpp +91 -0
  159. data/ext/alglib/nearunityunit.h +17 -0
  160. data/ext/alglib/normaldistr.cpp +377 -0
  161. data/ext/alglib/normaldistr.h +175 -0
  162. data/ext/alglib/nsevd.cpp +1869 -0
  163. data/ext/alglib/nsevd.h +140 -0
  164. data/ext/alglib/pca.cpp +168 -0
  165. data/ext/alglib/pca.h +87 -0
  166. data/ext/alglib/poissondistr.cpp +143 -0
  167. data/ext/alglib/poissondistr.h +130 -0
  168. data/ext/alglib/polinterpolation.cpp +685 -0
  169. data/ext/alglib/polinterpolation.h +206 -0
  170. data/ext/alglib/psif.cpp +173 -0
  171. data/ext/alglib/psif.h +88 -0
  172. data/ext/alglib/qr.cpp +414 -0
  173. data/ext/alglib/qr.h +168 -0
  174. data/ext/alglib/ratinterpolation.cpp +134 -0
  175. data/ext/alglib/ratinterpolation.h +72 -0
  176. data/ext/alglib/rcond.cpp +705 -0
  177. data/ext/alglib/rcond.h +140 -0
  178. data/ext/alglib/reflections.cpp +504 -0
  179. data/ext/alglib/reflections.h +165 -0
  180. data/ext/alglib/rotations.cpp +473 -0
  181. data/ext/alglib/rotations.h +128 -0
  182. data/ext/alglib/rsolve.cpp +221 -0
  183. data/ext/alglib/rsolve.h +99 -0
  184. data/ext/alglib/sbisinv.cpp +217 -0
  185. data/ext/alglib/sbisinv.h +171 -0
  186. data/ext/alglib/sblas.cpp +185 -0
  187. data/ext/alglib/sblas.h +64 -0
  188. data/ext/alglib/schur.cpp +156 -0
  189. data/ext/alglib/schur.h +102 -0
  190. data/ext/alglib/sdet.cpp +193 -0
  191. data/ext/alglib/sdet.h +101 -0
  192. data/ext/alglib/sevd.cpp +116 -0
  193. data/ext/alglib/sevd.h +99 -0
  194. data/ext/alglib/sinverse.cpp +672 -0
  195. data/ext/alglib/sinverse.h +138 -0
  196. data/ext/alglib/spddet.cpp +138 -0
  197. data/ext/alglib/spddet.h +96 -0
  198. data/ext/alglib/spdgevd.cpp +842 -0
  199. data/ext/alglib/spdgevd.h +200 -0
  200. data/ext/alglib/spdinverse.cpp +509 -0
  201. data/ext/alglib/spdinverse.h +122 -0
  202. data/ext/alglib/spdrcond.cpp +421 -0
  203. data/ext/alglib/spdrcond.h +118 -0
  204. data/ext/alglib/spdsolve.cpp +275 -0
  205. data/ext/alglib/spdsolve.h +105 -0
  206. data/ext/alglib/spline2d.cpp +1192 -0
  207. data/ext/alglib/spline2d.h +301 -0
  208. data/ext/alglib/spline3.cpp +1264 -0
  209. data/ext/alglib/spline3.h +290 -0
  210. data/ext/alglib/srcond.cpp +595 -0
  211. data/ext/alglib/srcond.h +127 -0
  212. data/ext/alglib/ssolve.cpp +895 -0
  213. data/ext/alglib/ssolve.h +139 -0
  214. data/ext/alglib/stdafx.h +0 -0
  215. data/ext/alglib/stest.cpp +131 -0
  216. data/ext/alglib/stest.h +94 -0
  217. data/ext/alglib/studenttdistr.cpp +222 -0
  218. data/ext/alglib/studenttdistr.h +115 -0
  219. data/ext/alglib/studentttests.cpp +377 -0
  220. data/ext/alglib/studentttests.h +178 -0
  221. data/ext/alglib/svd.cpp +620 -0
  222. data/ext/alglib/svd.h +126 -0
  223. data/ext/alglib/tdbisinv.cpp +2608 -0
  224. data/ext/alglib/tdbisinv.h +228 -0
  225. data/ext/alglib/tdevd.cpp +1229 -0
  226. data/ext/alglib/tdevd.h +115 -0
  227. data/ext/alglib/tridiagonal.cpp +594 -0
  228. data/ext/alglib/tridiagonal.h +171 -0
  229. data/ext/alglib/trigintegrals.cpp +490 -0
  230. data/ext/alglib/trigintegrals.h +131 -0
  231. data/ext/alglib/trinverse.cpp +345 -0
  232. data/ext/alglib/trinverse.h +98 -0
  233. data/ext/alglib/trlinsolve.cpp +926 -0
  234. data/ext/alglib/trlinsolve.h +73 -0
  235. data/ext/alglib/tsort.cpp +405 -0
  236. data/ext/alglib/tsort.h +54 -0
  237. data/ext/alglib/variancetests.cpp +245 -0
  238. data/ext/alglib/variancetests.h +134 -0
  239. data/ext/alglib/wsr.cpp +6285 -0
  240. data/ext/alglib/wsr.h +96 -0
  241. data/ext/ap.i +97 -0
  242. data/ext/correlation.i +24 -0
  243. data/ext/extconf.rb +6 -0
  244. data/ext/logit.i +89 -0
  245. data/lib/alglib.rb +71 -0
  246. data/lib/alglib/correlation.rb +26 -0
  247. data/lib/alglib/linearregression.rb +63 -0
  248. data/lib/alglib/logit.rb +42 -0
  249. data/test/test_alglib.rb +52 -0
  250. data/test/test_correlation.rb +44 -0
  251. data/test/test_correlationtest.rb +45 -0
  252. data/test/test_linreg.rb +35 -0
  253. data/test/test_logit.rb +43 -0
  254. data/test/test_pca.rb +27 -0
  255. metadata +326 -0
@@ -0,0 +1,138 @@
1
+ /*************************************************************************
2
+ Copyright (c) 1992-2007 The University of Tennessee. All rights reserved.
3
+
4
+ Contributors:
5
+ * Sergey Bochkanov (ALGLIB project). Translation from FORTRAN to
6
+ pseudocode.
7
+
8
+ See subroutines comments for additional copyrights.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions are
12
+ met:
13
+
14
+ - Redistributions of source code must retain the above copyright
15
+ notice, this list of conditions and the following disclaimer.
16
+
17
+ - Redistributions in binary form must reproduce the above copyright
18
+ notice, this list of conditions and the following disclaimer listed
19
+ in this license in the documentation and/or other materials
20
+ provided with the distribution.
21
+
22
+ - Neither the name of the copyright holders nor the names of its
23
+ contributors may be used to endorse or promote products derived from
24
+ this software without specific prior written permission.
25
+
26
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
+ *************************************************************************/
38
+
39
+ #ifndef _sinverse_h
40
+ #define _sinverse_h
41
+
42
+ #include "ap.h"
43
+ #include "ialglib.h"
44
+
45
+ #include "sblas.h"
46
+ #include "ldlt.h"
47
+
48
+
49
+ /*************************************************************************
50
+ Inversion of a symmetric indefinite matrix
51
+
52
+ The algorithm gets an LDLT-decomposition as an input, generates matrix A^-1
53
+ and saves the lower or upper triangle of an inverse matrix depending on the
54
+ input (U*D*U' or L*D*L').
55
+
56
+ Input parameters:
57
+ A - LDLT-decomposition of the matrix,
58
+ Output of subroutine SMatrixLDLT.
59
+ N - size of matrix A.
60
+ IsUpper - storage format. If IsUpper = True, then the symmetric matrix
61
+ is given as decomposition A = U*D*U' and this decomposition
62
+ is stored in the upper triangle of matrix A and on the main
63
+ diagonal, and the lower triangle of matrix A is not used.
64
+ Pivots - a table of permutations, output of subroutine SMatrixLDLT.
65
+
66
+ Output parameters:
67
+ A - inverse of the matrix, whose LDLT-decomposition was stored
68
+ in matrix A as a subroutine input.
69
+ Array with elements [0..N-1, 0..N-1].
70
+ If IsUpper = True, then A contains the upper triangle of
71
+ matrix A^-1, and the elements below the main diagonal are
72
+ not used nor changed. The same applies if IsUpper = False.
73
+
74
+ Result:
75
+ True, if the matrix is not singular.
76
+ False, if the matrix is singular and could not be inverted.
77
+
78
+ -- LAPACK routine (version 3.0) --
79
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
80
+ Courant Institute, Argonne National Lab, and Rice University
81
+ March 31, 1993
82
+ *************************************************************************/
83
+ bool smatrixldltinverse(ap::real_2d_array& a,
84
+ const ap::integer_1d_array& pivots,
85
+ int n,
86
+ bool isupper);
87
+
88
+
89
+ /*************************************************************************
90
+ Inversion of a symmetric indefinite matrix
91
+
92
+ Given a lower or upper triangle of matrix A, the algorithm generates
93
+ matrix A^-1 and saves the lower or upper triangle depending on the input.
94
+
95
+ Input parameters:
96
+ A - matrix to be inverted (upper or lower triangle).
97
+ Array with elements [0..N-1, 0..N-1].
98
+ N - size of matrix A.
99
+ IsUpper - storage format. If IsUpper = True, then the upper
100
+ triangle of matrix A is given, otherwise the lower
101
+ triangle is given.
102
+
103
+ Output parameters:
104
+ A - inverse of matrix A.
105
+ Array with elements [0..N-1, 0..N-1].
106
+ If IsUpper = True, then A contains the upper triangle of
107
+ matrix A^-1, and the elements below the main diagonal are
108
+ not used nor changed.
109
+ The same applies if IsUpper = False.
110
+
111
+ Result:
112
+ True, if the matrix is not singular.
113
+ False, if the matrix is singular and could not be inverted.
114
+
115
+ -- LAPACK routine (version 3.0) --
116
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
117
+ Courant Institute, Argonne National Lab, and Rice University
118
+ March 31, 1993
119
+ *************************************************************************/
120
+ bool smatrixinverse(ap::real_2d_array& a, int n, bool isupper);
121
+
122
+
123
+ /*************************************************************************
124
+ Obsolete 1-based subroutine
125
+ *************************************************************************/
126
+ bool inverseldlt(ap::real_2d_array& a,
127
+ const ap::integer_1d_array& pivots,
128
+ int n,
129
+ bool isupper);
130
+
131
+
132
+ /*************************************************************************
133
+ Obsolete 1-based subroutine
134
+ *************************************************************************/
135
+ bool inversesymmetricindefinite(ap::real_2d_array& a, int n, bool isupper);
136
+
137
+
138
+ #endif
@@ -0,0 +1,138 @@
1
+ /*************************************************************************
2
+ Copyright (c) 2005-2007, Sergey Bochkanov (ALGLIB project).
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ - Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ - Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer listed
13
+ in this license in the documentation and/or other materials
14
+ provided with the distribution.
15
+
16
+ - Neither the name of the copyright holders nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *************************************************************************/
32
+
33
+ #include <stdafx.h>
34
+ #include "spddet.h"
35
+
36
+ /*************************************************************************
37
+ Determinant calculation of the matrix given by the Cholesky decomposition.
38
+
39
+ Input parameters:
40
+ A - Cholesky decomposition,
41
+ output of SMatrixCholesky subroutine.
42
+ N - size of matrix A.
43
+
44
+ As the determinant is equal to the product of squares of diagonal elements,
45
+ it�s not necessary to specify which triangle - lower or upper - the matrix
46
+ is stored in.
47
+
48
+ Result:
49
+ matrix determinant.
50
+
51
+ -- ALGLIB --
52
+ Copyright 2005-2008 by Bochkanov Sergey
53
+ *************************************************************************/
54
+ double spdmatrixcholeskydet(const ap::real_2d_array& a, int n)
55
+ {
56
+ double result;
57
+ int i;
58
+
59
+ result = 1;
60
+ for(i = 0; i <= n-1; i++)
61
+ {
62
+ result = result*ap::sqr(a(i,i));
63
+ }
64
+ return result;
65
+ }
66
+
67
+
68
+ /*************************************************************************
69
+ Determinant calculation of the symmetric positive definite matrix.
70
+
71
+ Input parameters:
72
+ A - matrix. Array with elements [0..N-1, 0..N-1].
73
+ N - size of matrix A.
74
+ IsUpper - if IsUpper = True, then the symmetric matrix A is given by
75
+ its upper triangle, and the lower triangle isn�t used by
76
+ subroutine. Similarly, if IsUpper = False, then A is given
77
+ by its lower triangle.
78
+
79
+ Result:
80
+ determinant of matrix A.
81
+ If matrix A is not positive definite, then subroutine returns -1.
82
+
83
+ -- ALGLIB --
84
+ Copyright 2005-2008 by Bochkanov Sergey
85
+ *************************************************************************/
86
+ double spdmatrixdet(ap::real_2d_array a, int n, bool isupper)
87
+ {
88
+ double result;
89
+
90
+ if( !spdmatrixcholesky(a, n, isupper) )
91
+ {
92
+ result = -1;
93
+ }
94
+ else
95
+ {
96
+ result = spdmatrixcholeskydet(a, n);
97
+ }
98
+ return result;
99
+ }
100
+
101
+
102
+ /*************************************************************************
103
+ Obsolete subroutine
104
+ *************************************************************************/
105
+ double determinantcholesky(const ap::real_2d_array& a, int n)
106
+ {
107
+ double result;
108
+ int i;
109
+
110
+ result = 1;
111
+ for(i = 1; i <= n; i++)
112
+ {
113
+ result = result*ap::sqr(a(i,i));
114
+ }
115
+ return result;
116
+ }
117
+
118
+
119
+ /*************************************************************************
120
+ Obsolete subroutine
121
+ *************************************************************************/
122
+ double determinantspd(ap::real_2d_array a, int n, bool isupper)
123
+ {
124
+ double result;
125
+
126
+ if( !choleskydecomposition(a, n, isupper) )
127
+ {
128
+ result = -1;
129
+ }
130
+ else
131
+ {
132
+ result = determinantcholesky(a, n);
133
+ }
134
+ return result;
135
+ }
136
+
137
+
138
+
@@ -0,0 +1,96 @@
1
+ /*************************************************************************
2
+ Copyright (c) 2005-2007, Sergey Bochkanov (ALGLIB project).
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ - Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ - Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer listed
13
+ in this license in the documentation and/or other materials
14
+ provided with the distribution.
15
+
16
+ - Neither the name of the copyright holders nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *************************************************************************/
32
+
33
+ #ifndef _spddet_h
34
+ #define _spddet_h
35
+
36
+ #include "ap.h"
37
+ #include "ialglib.h"
38
+
39
+ #include "cholesky.h"
40
+
41
+
42
+ /*************************************************************************
43
+ Determinant calculation of the matrix given by the Cholesky decomposition.
44
+
45
+ Input parameters:
46
+ A - Cholesky decomposition,
47
+ output of SMatrixCholesky subroutine.
48
+ N - size of matrix A.
49
+
50
+ As the determinant is equal to the product of squares of diagonal elements,
51
+ it�s not necessary to specify which triangle - lower or upper - the matrix
52
+ is stored in.
53
+
54
+ Result:
55
+ matrix determinant.
56
+
57
+ -- ALGLIB --
58
+ Copyright 2005-2008 by Bochkanov Sergey
59
+ *************************************************************************/
60
+ double spdmatrixcholeskydet(const ap::real_2d_array& a, int n);
61
+
62
+
63
+ /*************************************************************************
64
+ Determinant calculation of the symmetric positive definite matrix.
65
+
66
+ Input parameters:
67
+ A - matrix. Array with elements [0..N-1, 0..N-1].
68
+ N - size of matrix A.
69
+ IsUpper - if IsUpper = True, then the symmetric matrix A is given by
70
+ its upper triangle, and the lower triangle isn�t used by
71
+ subroutine. Similarly, if IsUpper = False, then A is given
72
+ by its lower triangle.
73
+
74
+ Result:
75
+ determinant of matrix A.
76
+ If matrix A is not positive definite, then subroutine returns -1.
77
+
78
+ -- ALGLIB --
79
+ Copyright 2005-2008 by Bochkanov Sergey
80
+ *************************************************************************/
81
+ double spdmatrixdet(ap::real_2d_array a, int n, bool isupper);
82
+
83
+
84
+ /*************************************************************************
85
+ Obsolete subroutine
86
+ *************************************************************************/
87
+ double determinantcholesky(const ap::real_2d_array& a, int n);
88
+
89
+
90
+ /*************************************************************************
91
+ Obsolete subroutine
92
+ *************************************************************************/
93
+ double determinantspd(ap::real_2d_array a, int n, bool isupper);
94
+
95
+
96
+ #endif
@@ -0,0 +1,842 @@
1
+ /*************************************************************************
2
+ Copyright (c) 2005-2007, Sergey Bochkanov (ALGLIB project).
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ - Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ - Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer listed
13
+ in this license in the documentation and/or other materials
14
+ provided with the distribution.
15
+
16
+ - Neither the name of the copyright holders nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *************************************************************************/
32
+
33
+ #include <stdafx.h>
34
+ #include "spdgevd.h"
35
+
36
+ /*************************************************************************
37
+ Algorithm for solving the following generalized symmetric positive-definite
38
+ eigenproblem:
39
+ A*x = lambda*B*x (1) or
40
+ A*B*x = lambda*x (2) or
41
+ B*A*x = lambda*x (3).
42
+ where A is a symmetric matrix, B - symmetric positive-definite matrix.
43
+ The problem is solved by reducing it to an ordinary symmetric eigenvalue
44
+ problem.
45
+
46
+ Input parameters:
47
+ A - symmetric matrix which is given by its upper or lower
48
+ triangular part.
49
+ Array whose indexes range within [0..N-1, 0..N-1].
50
+ N - size of matrices A and B.
51
+ IsUpperA - storage format of matrix A.
52
+ B - symmetric positive-definite matrix which is given by
53
+ its upper or lower triangular part.
54
+ Array whose indexes range within [0..N-1, 0..N-1].
55
+ IsUpperB - storage format of matrix B.
56
+ ZNeeded - if ZNeeded is equal to:
57
+ * 0, the eigenvectors are not returned;
58
+ * 1, the eigenvectors are returned.
59
+ ProblemType - if ProblemType is equal to:
60
+ * 1, the following problem is solved: A*x = lambda*B*x;
61
+ * 2, the following problem is solved: A*B*x = lambda*x;
62
+ * 3, the following problem is solved: B*A*x = lambda*x.
63
+
64
+ Output parameters:
65
+ D - eigenvalues in ascending order.
66
+ Array whose index ranges within [0..N-1].
67
+ Z - if ZNeeded is equal to:
68
+ * 0, Z hasn�t changed;
69
+ * 1, Z contains eigenvectors.
70
+ Array whose indexes range within [0..N-1, 0..N-1].
71
+ The eigenvectors are stored in matrix columns. It should
72
+ be noted that the eigenvectors in such problems do not
73
+ form an orthogonal system.
74
+
75
+ Result:
76
+ True, if the problem was solved successfully.
77
+ False, if the error occurred during the Cholesky decomposition of matrix
78
+ B (the matrix isn�t positive-definite) or during the work of the iterative
79
+ algorithm for solving the symmetric eigenproblem.
80
+
81
+ See also the GeneralizedSymmetricDefiniteEVDReduce subroutine.
82
+
83
+ -- ALGLIB --
84
+ Copyright 1.28.2006 by Bochkanov Sergey
85
+ *************************************************************************/
86
+ bool smatrixgevd(ap::real_2d_array a,
87
+ int n,
88
+ bool isuppera,
89
+ const ap::real_2d_array& b,
90
+ bool isupperb,
91
+ int zneeded,
92
+ int problemtype,
93
+ ap::real_1d_array& d,
94
+ ap::real_2d_array& z)
95
+ {
96
+ bool result;
97
+ ap::real_2d_array r;
98
+ ap::real_2d_array t;
99
+ bool isupperr;
100
+ int j1;
101
+ int j2;
102
+ int j1inc;
103
+ int j2inc;
104
+ int i;
105
+ int j;
106
+ double v;
107
+
108
+
109
+ //
110
+ // Reduce and solve
111
+ //
112
+ result = smatrixgevdreduce(a, n, isuppera, b, isupperb, problemtype, r, isupperr);
113
+ if( !result )
114
+ {
115
+ return result;
116
+ }
117
+ result = smatrixevd(a, n, zneeded, isuppera, d, t);
118
+ if( !result )
119
+ {
120
+ return result;
121
+ }
122
+
123
+ //
124
+ // Transform eigenvectors if needed
125
+ //
126
+ if( zneeded!=0 )
127
+ {
128
+
129
+ //
130
+ // fill Z with zeros
131
+ //
132
+ z.setbounds(0, n-1, 0, n-1);
133
+ for(j = 0; j <= n-1; j++)
134
+ {
135
+ z(0,j) = 0.0;
136
+ }
137
+ for(i = 1; i <= n-1; i++)
138
+ {
139
+ ap::vmove(&z(i, 0), &z(0, 0), ap::vlen(0,n-1));
140
+ }
141
+
142
+ //
143
+ // Setup R properties
144
+ //
145
+ if( isupperr )
146
+ {
147
+ j1 = 0;
148
+ j2 = n-1;
149
+ j1inc = +1;
150
+ j2inc = 0;
151
+ }
152
+ else
153
+ {
154
+ j1 = 0;
155
+ j2 = 0;
156
+ j1inc = 0;
157
+ j2inc = +1;
158
+ }
159
+
160
+ //
161
+ // Calculate R*Z
162
+ //
163
+ for(i = 0; i <= n-1; i++)
164
+ {
165
+ for(j = j1; j <= j2; j++)
166
+ {
167
+ v = r(i,j);
168
+ ap::vadd(&z(i, 0), &t(j, 0), ap::vlen(0,n-1), v);
169
+ }
170
+ j1 = j1+j1inc;
171
+ j2 = j2+j2inc;
172
+ }
173
+ }
174
+ return result;
175
+ }
176
+
177
+
178
+ /*************************************************************************
179
+ Algorithm for reduction of the following generalized symmetric positive-
180
+ definite eigenvalue problem:
181
+ A*x = lambda*B*x (1) or
182
+ A*B*x = lambda*x (2) or
183
+ B*A*x = lambda*x (3)
184
+ to the symmetric eigenvalues problem C*y = lambda*y (eigenvalues of this and
185
+ the given problems are the same, and the eigenvectors of the given problem
186
+ could be obtained by multiplying the obtained eigenvectors by the
187
+ transformation matrix x = R*y).
188
+
189
+ Here A is a symmetric matrix, B - symmetric positive-definite matrix.
190
+
191
+ Input parameters:
192
+ A - symmetric matrix which is given by its upper or lower
193
+ triangular part.
194
+ Array whose indexes range within [0..N-1, 0..N-1].
195
+ N - size of matrices A and B.
196
+ IsUpperA - storage format of matrix A.
197
+ B - symmetric positive-definite matrix which is given by
198
+ its upper or lower triangular part.
199
+ Array whose indexes range within [0..N-1, 0..N-1].
200
+ IsUpperB - storage format of matrix B.
201
+ ProblemType - if ProblemType is equal to:
202
+ * 1, the following problem is solved: A*x = lambda*B*x;
203
+ * 2, the following problem is solved: A*B*x = lambda*x;
204
+ * 3, the following problem is solved: B*A*x = lambda*x.
205
+
206
+ Output parameters:
207
+ A - symmetric matrix which is given by its upper or lower
208
+ triangle depending on IsUpperA. Contains matrix C.
209
+ Array whose indexes range within [0..N-1, 0..N-1].
210
+ R - upper triangular or low triangular transformation matrix
211
+ which is used to obtain the eigenvectors of a given problem
212
+ as the product of eigenvectors of C (from the right) and
213
+ matrix R (from the left). If the matrix is upper
214
+ triangular, the elements below the main diagonal
215
+ are equal to 0 (and vice versa). Thus, we can perform
216
+ the multiplication without taking into account the
217
+ internal structure (which is an easier though less
218
+ effective way).
219
+ Array whose indexes range within [0..N-1, 0..N-1].
220
+ IsUpperR - type of matrix R (upper or lower triangular).
221
+
222
+ Result:
223
+ True, if the problem was reduced successfully.
224
+ False, if the error occurred during the Cholesky decomposition of
225
+ matrix B (the matrix is not positive-definite).
226
+
227
+ -- ALGLIB --
228
+ Copyright 1.28.2006 by Bochkanov Sergey
229
+ *************************************************************************/
230
+ bool smatrixgevdreduce(ap::real_2d_array& a,
231
+ int n,
232
+ bool isuppera,
233
+ const ap::real_2d_array& b,
234
+ bool isupperb,
235
+ int problemtype,
236
+ ap::real_2d_array& r,
237
+ bool& isupperr)
238
+ {
239
+ bool result;
240
+ ap::real_2d_array t;
241
+ ap::real_1d_array w1;
242
+ ap::real_1d_array w2;
243
+ ap::real_1d_array w3;
244
+ int i;
245
+ int j;
246
+ double v;
247
+
248
+ ap::ap_error::make_assertion(n>0, "SMatrixGEVDReduce: N<=0!");
249
+ ap::ap_error::make_assertion(problemtype==1||problemtype==2||problemtype==3, "SMatrixGEVDReduce: incorrect ProblemType!");
250
+ result = true;
251
+
252
+ //
253
+ // Problem 1: A*x = lambda*B*x
254
+ //
255
+ // Reducing to:
256
+ // C*y = lambda*y
257
+ // C = L^(-1) * A * L^(-T)
258
+ // x = L^(-T) * y
259
+ //
260
+ if( problemtype==1 )
261
+ {
262
+
263
+ //
264
+ // Factorize B in T: B = LL'
265
+ //
266
+ t.setbounds(0, n-1, 0, n-1);
267
+ if( isupperb )
268
+ {
269
+ for(i = 0; i <= n-1; i++)
270
+ {
271
+ ap::vmove(t.getcolumn(i, i, n-1), b.getrow(i, i, n-1));
272
+ }
273
+ }
274
+ else
275
+ {
276
+ for(i = 0; i <= n-1; i++)
277
+ {
278
+ ap::vmove(&t(i, 0), &b(i, 0), ap::vlen(0,i));
279
+ }
280
+ }
281
+ if( !spdmatrixcholesky(t, n, false) )
282
+ {
283
+ result = false;
284
+ return result;
285
+ }
286
+
287
+ //
288
+ // Invert L in T
289
+ //
290
+ if( !rmatrixtrinverse(t, n, false, false) )
291
+ {
292
+ result = false;
293
+ return result;
294
+ }
295
+
296
+ //
297
+ // Build L^(-1) * A * L^(-T) in R
298
+ //
299
+ w1.setbounds(1, n);
300
+ w2.setbounds(1, n);
301
+ r.setbounds(0, n-1, 0, n-1);
302
+ for(j = 1; j <= n; j++)
303
+ {
304
+
305
+ //
306
+ // Form w2 = A * l'(j) (here l'(j) is j-th column of L^(-T))
307
+ //
308
+ ap::vmove(&w1(1), &t(j-1, 0), ap::vlen(1,j));
309
+ symmetricmatrixvectormultiply(a, isuppera, 0, j-1, w1, 1.0, w2);
310
+ if( isuppera )
311
+ {
312
+ matrixvectormultiply(a, 0, j-1, j, n-1, true, w1, 1, j, 1.0, w2, j+1, n, 0.0);
313
+ }
314
+ else
315
+ {
316
+ matrixvectormultiply(a, j, n-1, 0, j-1, false, w1, 1, j, 1.0, w2, j+1, n, 0.0);
317
+ }
318
+
319
+ //
320
+ // Form l(i)*w2 (here l(i) is i-th row of L^(-1))
321
+ //
322
+ for(i = 1; i <= n; i++)
323
+ {
324
+ v = ap::vdotproduct(&t(i-1, 0), &w2(1), ap::vlen(0,i-1));
325
+ r(i-1,j-1) = v;
326
+ }
327
+ }
328
+
329
+ //
330
+ // Copy R to A
331
+ //
332
+ for(i = 0; i <= n-1; i++)
333
+ {
334
+ ap::vmove(&a(i, 0), &r(i, 0), ap::vlen(0,n-1));
335
+ }
336
+
337
+ //
338
+ // Copy L^(-1) from T to R and transpose
339
+ //
340
+ isupperr = true;
341
+ for(i = 0; i <= n-1; i++)
342
+ {
343
+ for(j = 0; j <= i-1; j++)
344
+ {
345
+ r(i,j) = 0;
346
+ }
347
+ }
348
+ for(i = 0; i <= n-1; i++)
349
+ {
350
+ ap::vmove(r.getrow(i, i, n-1), t.getcolumn(i, i, n-1));
351
+ }
352
+ return result;
353
+ }
354
+
355
+ //
356
+ // Problem 2: A*B*x = lambda*x
357
+ // or
358
+ // problem 3: B*A*x = lambda*x
359
+ //
360
+ // Reducing to:
361
+ // C*y = lambda*y
362
+ // C = U * A * U'
363
+ // B = U'* U
364
+ //
365
+ if( problemtype==2||problemtype==3 )
366
+ {
367
+
368
+ //
369
+ // Factorize B in T: B = U'*U
370
+ //
371
+ t.setbounds(0, n-1, 0, n-1);
372
+ if( isupperb )
373
+ {
374
+ for(i = 0; i <= n-1; i++)
375
+ {
376
+ ap::vmove(&t(i, i), &b(i, i), ap::vlen(i,n-1));
377
+ }
378
+ }
379
+ else
380
+ {
381
+ for(i = 0; i <= n-1; i++)
382
+ {
383
+ ap::vmove(t.getrow(i, i, n-1), b.getcolumn(i, i, n-1));
384
+ }
385
+ }
386
+ if( !spdmatrixcholesky(t, n, true) )
387
+ {
388
+ result = false;
389
+ return result;
390
+ }
391
+
392
+ //
393
+ // Build U * A * U' in R
394
+ //
395
+ w1.setbounds(1, n);
396
+ w2.setbounds(1, n);
397
+ w3.setbounds(1, n);
398
+ r.setbounds(0, n-1, 0, n-1);
399
+ for(j = 1; j <= n; j++)
400
+ {
401
+
402
+ //
403
+ // Form w2 = A * u'(j) (here u'(j) is j-th column of U')
404
+ //
405
+ ap::vmove(&w1(1), &t(j-1, j-1), ap::vlen(1,n-j+1));
406
+ symmetricmatrixvectormultiply(a, isuppera, j-1, n-1, w1, 1.0, w3);
407
+ ap::vmove(&w2(j), &w3(1), ap::vlen(j,n));
408
+ ap::vmove(&w1(j), &t(j-1, j-1), ap::vlen(j,n));
409
+ if( isuppera )
410
+ {
411
+ matrixvectormultiply(a, 0, j-2, j-1, n-1, false, w1, j, n, 1.0, w2, 1, j-1, 0.0);
412
+ }
413
+ else
414
+ {
415
+ matrixvectormultiply(a, j-1, n-1, 0, j-2, true, w1, j, n, 1.0, w2, 1, j-1, 0.0);
416
+ }
417
+
418
+ //
419
+ // Form u(i)*w2 (here u(i) is i-th row of U)
420
+ //
421
+ for(i = 1; i <= n; i++)
422
+ {
423
+ v = ap::vdotproduct(&t(i-1, i-1), &w2(i), ap::vlen(i-1,n-1));
424
+ r(i-1,j-1) = v;
425
+ }
426
+ }
427
+
428
+ //
429
+ // Copy R to A
430
+ //
431
+ for(i = 0; i <= n-1; i++)
432
+ {
433
+ ap::vmove(&a(i, 0), &r(i, 0), ap::vlen(0,n-1));
434
+ }
435
+ if( problemtype==2 )
436
+ {
437
+
438
+ //
439
+ // Invert U in T
440
+ //
441
+ if( !rmatrixtrinverse(t, n, true, false) )
442
+ {
443
+ result = false;
444
+ return result;
445
+ }
446
+
447
+ //
448
+ // Copy U^-1 from T to R
449
+ //
450
+ isupperr = true;
451
+ for(i = 0; i <= n-1; i++)
452
+ {
453
+ for(j = 0; j <= i-1; j++)
454
+ {
455
+ r(i,j) = 0;
456
+ }
457
+ }
458
+ for(i = 0; i <= n-1; i++)
459
+ {
460
+ ap::vmove(&r(i, i), &t(i, i), ap::vlen(i,n-1));
461
+ }
462
+ }
463
+ else
464
+ {
465
+
466
+ //
467
+ // Copy U from T to R and transpose
468
+ //
469
+ isupperr = false;
470
+ for(i = 0; i <= n-1; i++)
471
+ {
472
+ for(j = i+1; j <= n-1; j++)
473
+ {
474
+ r(i,j) = 0;
475
+ }
476
+ }
477
+ for(i = 0; i <= n-1; i++)
478
+ {
479
+ ap::vmove(r.getcolumn(i, i, n-1), t.getrow(i, i, n-1));
480
+ }
481
+ }
482
+ }
483
+ return result;
484
+ }
485
+
486
+
487
+ /*************************************************************************
488
+ Obsolete 1-based subroutine
489
+ *************************************************************************/
490
+ bool generalizedsymmetricdefiniteevd(ap::real_2d_array a,
491
+ int n,
492
+ bool isuppera,
493
+ const ap::real_2d_array& b,
494
+ bool isupperb,
495
+ int zneeded,
496
+ int problemtype,
497
+ ap::real_1d_array& d,
498
+ ap::real_2d_array& z)
499
+ {
500
+ bool result;
501
+ ap::real_2d_array r;
502
+ ap::real_2d_array t;
503
+ bool isupperr;
504
+ int j1;
505
+ int j2;
506
+ int j1inc;
507
+ int j2inc;
508
+ int i;
509
+ int j;
510
+ double v;
511
+
512
+
513
+ //
514
+ // Reduce and solve
515
+ //
516
+ result = generalizedsymmetricdefiniteevdreduce(a, n, isuppera, b, isupperb, problemtype, r, isupperr);
517
+ if( !result )
518
+ {
519
+ return result;
520
+ }
521
+ result = symmetricevd(a, n, zneeded, isuppera, d, t);
522
+ if( !result )
523
+ {
524
+ return result;
525
+ }
526
+
527
+ //
528
+ // Transform eigenvectors if needed
529
+ //
530
+ if( zneeded!=0 )
531
+ {
532
+
533
+ //
534
+ // fill Z with zeros
535
+ //
536
+ z.setbounds(1, n, 1, n);
537
+ for(j = 1; j <= n; j++)
538
+ {
539
+ z(1,j) = 0.0;
540
+ }
541
+ for(i = 2; i <= n; i++)
542
+ {
543
+ ap::vmove(&z(i, 1), &z(1, 1), ap::vlen(1,n));
544
+ }
545
+
546
+ //
547
+ // Setup R properties
548
+ //
549
+ if( isupperr )
550
+ {
551
+ j1 = 1;
552
+ j2 = n;
553
+ j1inc = +1;
554
+ j2inc = 0;
555
+ }
556
+ else
557
+ {
558
+ j1 = 1;
559
+ j2 = 1;
560
+ j1inc = 0;
561
+ j2inc = +1;
562
+ }
563
+
564
+ //
565
+ // Calculate R*Z
566
+ //
567
+ for(i = 1; i <= n; i++)
568
+ {
569
+ for(j = j1; j <= j2; j++)
570
+ {
571
+ v = r(i,j);
572
+ ap::vadd(&z(i, 1), &t(j, 1), ap::vlen(1,n), v);
573
+ }
574
+ j1 = j1+j1inc;
575
+ j2 = j2+j2inc;
576
+ }
577
+ }
578
+ return result;
579
+ }
580
+
581
+
582
+ /*************************************************************************
583
+ Obsolete 1-based subroutine
584
+ *************************************************************************/
585
+ bool generalizedsymmetricdefiniteevdreduce(ap::real_2d_array& a,
586
+ int n,
587
+ bool isuppera,
588
+ const ap::real_2d_array& b,
589
+ bool isupperb,
590
+ int problemtype,
591
+ ap::real_2d_array& r,
592
+ bool& isupperr)
593
+ {
594
+ bool result;
595
+ ap::real_2d_array t;
596
+ ap::real_1d_array w1;
597
+ ap::real_1d_array w2;
598
+ ap::real_1d_array w3;
599
+ int i;
600
+ int j;
601
+ double v;
602
+
603
+ ap::ap_error::make_assertion(n>0, "GeneralizedSymmetricDefiniteEVDReduce: N<=0!");
604
+ ap::ap_error::make_assertion(problemtype==1||problemtype==2||problemtype==3, "GeneralizedSymmetricDefiniteEVDReduce: incorrect ProblemType!");
605
+ result = true;
606
+
607
+ //
608
+ // Problem 1: A*x = lambda*B*x
609
+ //
610
+ // Reducing to:
611
+ // C*y = lambda*y
612
+ // C = L^(-1) * A * L^(-T)
613
+ // x = L^(-T) * y
614
+ //
615
+ if( problemtype==1 )
616
+ {
617
+
618
+ //
619
+ // Factorize B in T: B = LL'
620
+ //
621
+ t.setbounds(1, n, 1, n);
622
+ if( isupperb )
623
+ {
624
+ for(i = 1; i <= n; i++)
625
+ {
626
+ ap::vmove(t.getcolumn(i, i, n), b.getrow(i, i, n));
627
+ }
628
+ }
629
+ else
630
+ {
631
+ for(i = 1; i <= n; i++)
632
+ {
633
+ ap::vmove(&t(i, 1), &b(i, 1), ap::vlen(1,i));
634
+ }
635
+ }
636
+ if( !choleskydecomposition(t, n, false) )
637
+ {
638
+ result = false;
639
+ return result;
640
+ }
641
+
642
+ //
643
+ // Invert L in T
644
+ //
645
+ if( !invtriangular(t, n, false, false) )
646
+ {
647
+ result = false;
648
+ return result;
649
+ }
650
+
651
+ //
652
+ // Build L^(-1) * A * L^(-T) in R
653
+ //
654
+ w1.setbounds(1, n);
655
+ w2.setbounds(1, n);
656
+ r.setbounds(1, n, 1, n);
657
+ for(j = 1; j <= n; j++)
658
+ {
659
+
660
+ //
661
+ // Form w2 = A * l'(j) (here l'(j) is j-th column of L^(-T))
662
+ //
663
+ ap::vmove(&w1(1), &t(j, 1), ap::vlen(1,j));
664
+ symmetricmatrixvectormultiply(a, isuppera, 1, j, w1, 1.0, w2);
665
+ if( isuppera )
666
+ {
667
+ matrixvectormultiply(a, 1, j, j+1, n, true, w1, 1, j, 1.0, w2, j+1, n, 0.0);
668
+ }
669
+ else
670
+ {
671
+ matrixvectormultiply(a, j+1, n, 1, j, false, w1, 1, j, 1.0, w2, j+1, n, 0.0);
672
+ }
673
+
674
+ //
675
+ // Form l(i)*w2 (here l(i) is i-th row of L^(-1))
676
+ //
677
+ for(i = 1; i <= n; i++)
678
+ {
679
+ v = ap::vdotproduct(&t(i, 1), &w2(1), ap::vlen(1,i));
680
+ r(i,j) = v;
681
+ }
682
+ }
683
+
684
+ //
685
+ // Copy R to A
686
+ //
687
+ for(i = 1; i <= n; i++)
688
+ {
689
+ ap::vmove(&a(i, 1), &r(i, 1), ap::vlen(1,n));
690
+ }
691
+
692
+ //
693
+ // Copy L^(-1) from T to R and transpose
694
+ //
695
+ isupperr = true;
696
+ for(i = 1; i <= n; i++)
697
+ {
698
+ for(j = 1; j <= i-1; j++)
699
+ {
700
+ r(i,j) = 0;
701
+ }
702
+ }
703
+ for(i = 1; i <= n; i++)
704
+ {
705
+ ap::vmove(r.getrow(i, i, n), t.getcolumn(i, i, n));
706
+ }
707
+ return result;
708
+ }
709
+
710
+ //
711
+ // Problem 2: A*B*x = lambda*x
712
+ // or
713
+ // problem 3: B*A*x = lambda*x
714
+ //
715
+ // Reducing to:
716
+ // C*y = lambda*y
717
+ // C = U * A * U'
718
+ // B = U'* U
719
+ //
720
+ if( problemtype==2||problemtype==3 )
721
+ {
722
+
723
+ //
724
+ // Factorize B in T: B = U'*U
725
+ //
726
+ t.setbounds(1, n, 1, n);
727
+ if( isupperb )
728
+ {
729
+ for(i = 1; i <= n; i++)
730
+ {
731
+ ap::vmove(&t(i, i), &b(i, i), ap::vlen(i,n));
732
+ }
733
+ }
734
+ else
735
+ {
736
+ for(i = 1; i <= n; i++)
737
+ {
738
+ ap::vmove(t.getrow(i, i, n), b.getcolumn(i, i, n));
739
+ }
740
+ }
741
+ if( !choleskydecomposition(t, n, true) )
742
+ {
743
+ result = false;
744
+ return result;
745
+ }
746
+
747
+ //
748
+ // Build U * A * U' in R
749
+ //
750
+ w1.setbounds(1, n);
751
+ w2.setbounds(1, n);
752
+ w3.setbounds(1, n);
753
+ r.setbounds(1, n, 1, n);
754
+ for(j = 1; j <= n; j++)
755
+ {
756
+
757
+ //
758
+ // Form w2 = A * u'(j) (here u'(j) is j-th column of U')
759
+ //
760
+ ap::vmove(&w1(1), &t(j, j), ap::vlen(1,n-j+1));
761
+ symmetricmatrixvectormultiply(a, isuppera, j, n, w1, 1.0, w3);
762
+ ap::vmove(&w2(j), &w3(1), ap::vlen(j,n));
763
+ ap::vmove(&w1(j), &t(j, j), ap::vlen(j,n));
764
+ if( isuppera )
765
+ {
766
+ matrixvectormultiply(a, 1, j-1, j, n, false, w1, j, n, 1.0, w2, 1, j-1, 0.0);
767
+ }
768
+ else
769
+ {
770
+ matrixvectormultiply(a, j, n, 1, j-1, true, w1, j, n, 1.0, w2, 1, j-1, 0.0);
771
+ }
772
+
773
+ //
774
+ // Form u(i)*w2 (here u(i) is i-th row of U)
775
+ //
776
+ for(i = 1; i <= n; i++)
777
+ {
778
+ v = ap::vdotproduct(&t(i, i), &w2(i), ap::vlen(i,n));
779
+ r(i,j) = v;
780
+ }
781
+ }
782
+
783
+ //
784
+ // Copy R to A
785
+ //
786
+ for(i = 1; i <= n; i++)
787
+ {
788
+ ap::vmove(&a(i, 1), &r(i, 1), ap::vlen(1,n));
789
+ }
790
+ if( problemtype==2 )
791
+ {
792
+
793
+ //
794
+ // Invert U in T
795
+ //
796
+ if( !invtriangular(t, n, true, false) )
797
+ {
798
+ result = false;
799
+ return result;
800
+ }
801
+
802
+ //
803
+ // Copy U^-1 from T to R
804
+ //
805
+ isupperr = true;
806
+ for(i = 1; i <= n; i++)
807
+ {
808
+ for(j = 1; j <= i-1; j++)
809
+ {
810
+ r(i,j) = 0;
811
+ }
812
+ }
813
+ for(i = 1; i <= n; i++)
814
+ {
815
+ ap::vmove(&r(i, i), &t(i, i), ap::vlen(i,n));
816
+ }
817
+ }
818
+ else
819
+ {
820
+
821
+ //
822
+ // Copy U from T to R and transpose
823
+ //
824
+ isupperr = false;
825
+ for(i = 1; i <= n; i++)
826
+ {
827
+ for(j = i+1; j <= n; j++)
828
+ {
829
+ r(i,j) = 0;
830
+ }
831
+ }
832
+ for(i = 1; i <= n; i++)
833
+ {
834
+ ap::vmove(r.getcolumn(i, i, n), t.getrow(i, i, n));
835
+ }
836
+ }
837
+ }
838
+ return result;
839
+ }
840
+
841
+
842
+