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,200 @@
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 _spdgevd_h
34
+ #define _spdgevd_h
35
+
36
+ #include "ap.h"
37
+ #include "ialglib.h"
38
+
39
+ #include "cholesky.h"
40
+ #include "sblas.h"
41
+ #include "blas.h"
42
+ #include "trinverse.h"
43
+ #include "rotations.h"
44
+ #include "tdevd.h"
45
+ #include "reflections.h"
46
+ #include "tridiagonal.h"
47
+ #include "sevd.h"
48
+
49
+
50
+ /*************************************************************************
51
+ Algorithm for solving the following generalized symmetric positive-definite
52
+ eigenproblem:
53
+ A*x = lambda*B*x (1) or
54
+ A*B*x = lambda*x (2) or
55
+ B*A*x = lambda*x (3).
56
+ where A is a symmetric matrix, B - symmetric positive-definite matrix.
57
+ The problem is solved by reducing it to an ordinary symmetric eigenvalue
58
+ problem.
59
+
60
+ Input parameters:
61
+ A - symmetric matrix which is given by its upper or lower
62
+ triangular part.
63
+ Array whose indexes range within [0..N-1, 0..N-1].
64
+ N - size of matrices A and B.
65
+ IsUpperA - storage format of matrix A.
66
+ B - symmetric positive-definite matrix which is given by
67
+ its upper or lower triangular part.
68
+ Array whose indexes range within [0..N-1, 0..N-1].
69
+ IsUpperB - storage format of matrix B.
70
+ ZNeeded - if ZNeeded is equal to:
71
+ * 0, the eigenvectors are not returned;
72
+ * 1, the eigenvectors are returned.
73
+ ProblemType - if ProblemType is equal to:
74
+ * 1, the following problem is solved: A*x = lambda*B*x;
75
+ * 2, the following problem is solved: A*B*x = lambda*x;
76
+ * 3, the following problem is solved: B*A*x = lambda*x.
77
+
78
+ Output parameters:
79
+ D - eigenvalues in ascending order.
80
+ Array whose index ranges within [0..N-1].
81
+ Z - if ZNeeded is equal to:
82
+ * 0, Z hasn�t changed;
83
+ * 1, Z contains eigenvectors.
84
+ Array whose indexes range within [0..N-1, 0..N-1].
85
+ The eigenvectors are stored in matrix columns. It should
86
+ be noted that the eigenvectors in such problems do not
87
+ form an orthogonal system.
88
+
89
+ Result:
90
+ True, if the problem was solved successfully.
91
+ False, if the error occurred during the Cholesky decomposition of matrix
92
+ B (the matrix isn�t positive-definite) or during the work of the iterative
93
+ algorithm for solving the symmetric eigenproblem.
94
+
95
+ See also the GeneralizedSymmetricDefiniteEVDReduce subroutine.
96
+
97
+ -- ALGLIB --
98
+ Copyright 1.28.2006 by Bochkanov Sergey
99
+ *************************************************************************/
100
+ bool smatrixgevd(ap::real_2d_array a,
101
+ int n,
102
+ bool isuppera,
103
+ const ap::real_2d_array& b,
104
+ bool isupperb,
105
+ int zneeded,
106
+ int problemtype,
107
+ ap::real_1d_array& d,
108
+ ap::real_2d_array& z);
109
+
110
+
111
+ /*************************************************************************
112
+ Algorithm for reduction of the following generalized symmetric positive-
113
+ definite eigenvalue problem:
114
+ A*x = lambda*B*x (1) or
115
+ A*B*x = lambda*x (2) or
116
+ B*A*x = lambda*x (3)
117
+ to the symmetric eigenvalues problem C*y = lambda*y (eigenvalues of this and
118
+ the given problems are the same, and the eigenvectors of the given problem
119
+ could be obtained by multiplying the obtained eigenvectors by the
120
+ transformation matrix x = R*y).
121
+
122
+ Here A is a symmetric matrix, B - symmetric positive-definite matrix.
123
+
124
+ Input parameters:
125
+ A - symmetric matrix which is given by its upper or lower
126
+ triangular part.
127
+ Array whose indexes range within [0..N-1, 0..N-1].
128
+ N - size of matrices A and B.
129
+ IsUpperA - storage format of matrix A.
130
+ B - symmetric positive-definite matrix which is given by
131
+ its upper or lower triangular part.
132
+ Array whose indexes range within [0..N-1, 0..N-1].
133
+ IsUpperB - storage format of matrix B.
134
+ ProblemType - if ProblemType is equal to:
135
+ * 1, the following problem is solved: A*x = lambda*B*x;
136
+ * 2, the following problem is solved: A*B*x = lambda*x;
137
+ * 3, the following problem is solved: B*A*x = lambda*x.
138
+
139
+ Output parameters:
140
+ A - symmetric matrix which is given by its upper or lower
141
+ triangle depending on IsUpperA. Contains matrix C.
142
+ Array whose indexes range within [0..N-1, 0..N-1].
143
+ R - upper triangular or low triangular transformation matrix
144
+ which is used to obtain the eigenvectors of a given problem
145
+ as the product of eigenvectors of C (from the right) and
146
+ matrix R (from the left). If the matrix is upper
147
+ triangular, the elements below the main diagonal
148
+ are equal to 0 (and vice versa). Thus, we can perform
149
+ the multiplication without taking into account the
150
+ internal structure (which is an easier though less
151
+ effective way).
152
+ Array whose indexes range within [0..N-1, 0..N-1].
153
+ IsUpperR - type of matrix R (upper or lower triangular).
154
+
155
+ Result:
156
+ True, if the problem was reduced successfully.
157
+ False, if the error occurred during the Cholesky decomposition of
158
+ matrix B (the matrix is not positive-definite).
159
+
160
+ -- ALGLIB --
161
+ Copyright 1.28.2006 by Bochkanov Sergey
162
+ *************************************************************************/
163
+ bool smatrixgevdreduce(ap::real_2d_array& a,
164
+ int n,
165
+ bool isuppera,
166
+ const ap::real_2d_array& b,
167
+ bool isupperb,
168
+ int problemtype,
169
+ ap::real_2d_array& r,
170
+ bool& isupperr);
171
+
172
+
173
+ /*************************************************************************
174
+ Obsolete 1-based subroutine
175
+ *************************************************************************/
176
+ bool generalizedsymmetricdefiniteevd(ap::real_2d_array a,
177
+ int n,
178
+ bool isuppera,
179
+ const ap::real_2d_array& b,
180
+ bool isupperb,
181
+ int zneeded,
182
+ int problemtype,
183
+ ap::real_1d_array& d,
184
+ ap::real_2d_array& z);
185
+
186
+
187
+ /*************************************************************************
188
+ Obsolete 1-based subroutine
189
+ *************************************************************************/
190
+ bool generalizedsymmetricdefiniteevdreduce(ap::real_2d_array& a,
191
+ int n,
192
+ bool isuppera,
193
+ const ap::real_2d_array& b,
194
+ bool isupperb,
195
+ int problemtype,
196
+ ap::real_2d_array& r,
197
+ bool& isupperr);
198
+
199
+
200
+ #endif
@@ -0,0 +1,509 @@
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
+ #include <stdafx.h>
40
+ #include <stdio.h>
41
+ #include "spdinverse.h"
42
+
43
+ static void testinversecholesky();
44
+
45
+ /*************************************************************************
46
+ Inversion of a symmetric positive definite matrix which is given
47
+ by Cholesky decomposition.
48
+
49
+ Input parameters:
50
+ A - Cholesky decomposition of the matrix to be inverted:
51
+ A=U�*U or A = L*L'.
52
+ Output of CholeskyDecomposition subroutine.
53
+ Array with elements [0..N-1, 0..N-1].
54
+ N - size of matrix A.
55
+ IsUpper � storage format.
56
+ If IsUpper = True, then matrix A is given as A = U'*U
57
+ (matrix contains upper triangle).
58
+ Similarly, if IsUpper = False, then A = L*L'.
59
+
60
+ Output parameters:
61
+ A - upper or lower triangle of symmetric matrix A^-1, depending
62
+ on the value of IsUpper.
63
+
64
+ Result:
65
+ True, if the inversion succeeded.
66
+ False, if matrix A contains zero elements on its main diagonal.
67
+ Matrix A could not be inverted.
68
+
69
+ The algorithm is the modification of DPOTRI and DLAUU2 subroutines from
70
+ LAPACK library.
71
+ *************************************************************************/
72
+ bool spdmatrixcholeskyinverse(ap::real_2d_array& a, int n, bool isupper)
73
+ {
74
+ bool result;
75
+ int i;
76
+ int j;
77
+ int k;
78
+ double v;
79
+ double ajj;
80
+ double aii;
81
+ ap::real_1d_array t;
82
+ ap::real_2d_array a1;
83
+
84
+ result = true;
85
+
86
+ //
87
+ // Test the input parameters.
88
+ //
89
+ t.setbounds(0, n-1);
90
+ if( isupper )
91
+ {
92
+
93
+ //
94
+ // Compute inverse of upper triangular matrix.
95
+ //
96
+ for(j = 0; j <= n-1; j++)
97
+ {
98
+ if( a(j,j)==0 )
99
+ {
100
+ result = false;
101
+ return result;
102
+ }
103
+ a(j,j) = 1/a(j,j);
104
+ ajj = -a(j,j);
105
+
106
+ //
107
+ // Compute elements 1:j-1 of j-th column.
108
+ //
109
+ ap::vmove(t.getvector(0, j-1), a.getcolumn(j, 0, j-1));
110
+ for(i = 0; i <= j-1; i++)
111
+ {
112
+ v = ap::vdotproduct(&a(i, i), &t(i), ap::vlen(i,j-1));
113
+ a(i,j) = v;
114
+ }
115
+ ap::vmul(a.getcolumn(j, 0, j-1), ajj);
116
+ }
117
+
118
+ //
119
+ // InvA = InvU * InvU'
120
+ //
121
+ for(i = 0; i <= n-1; i++)
122
+ {
123
+ aii = a(i,i);
124
+ if( i<n-1 )
125
+ {
126
+ v = ap::vdotproduct(&a(i, i), &a(i, i), ap::vlen(i,n-1));
127
+ a(i,i) = v;
128
+ for(k = 0; k <= i-1; k++)
129
+ {
130
+ v = ap::vdotproduct(&a(k, i+1), &a(i, i+1), ap::vlen(i+1,n-1));
131
+ a(k,i) = a(k,i)*aii+v;
132
+ }
133
+ }
134
+ else
135
+ {
136
+ ap::vmul(a.getcolumn(i, 0, i), aii);
137
+ }
138
+ }
139
+ }
140
+ else
141
+ {
142
+
143
+ //
144
+ // Compute inverse of lower triangular matrix.
145
+ //
146
+ for(j = n-1; j >= 0; j--)
147
+ {
148
+ if( a(j,j)==0 )
149
+ {
150
+ result = false;
151
+ return result;
152
+ }
153
+ a(j,j) = 1/a(j,j);
154
+ ajj = -a(j,j);
155
+ if( j<n-1 )
156
+ {
157
+
158
+ //
159
+ // Compute elements j+1:n of j-th column.
160
+ //
161
+ ap::vmove(t.getvector(j+1, n-1), a.getcolumn(j, j+1, n-1));
162
+ for(i = j+1+1; i <= n; i++)
163
+ {
164
+ v = ap::vdotproduct(&a(i-1, j+1), &t(j+1), ap::vlen(j+1,i-1));
165
+ a(i-1,j) = v;
166
+ }
167
+ ap::vmul(a.getcolumn(j, j+1, n-1), ajj);
168
+ }
169
+ }
170
+
171
+ //
172
+ // InvA = InvL' * InvL
173
+ //
174
+ for(i = 0; i <= n-1; i++)
175
+ {
176
+ aii = a(i,i);
177
+ if( i<n-1 )
178
+ {
179
+ v = ap::vdotproduct(a.getcolumn(i, i, n-1), a.getcolumn(i, i, n-1));
180
+ a(i,i) = v;
181
+ for(k = 0; k <= i-1; k++)
182
+ {
183
+ v = ap::vdotproduct(a.getcolumn(k, i+1, n-1), a.getcolumn(i, i+1, n-1));
184
+ a(i,k) = aii*a(i,k)+v;
185
+ }
186
+ }
187
+ else
188
+ {
189
+ ap::vmul(&a(i, 0), ap::vlen(0,i), aii);
190
+ }
191
+ }
192
+ }
193
+ return result;
194
+ }
195
+
196
+
197
+ /*************************************************************************
198
+ Inversion of a symmetric positive definite matrix.
199
+
200
+ Given an upper or lower triangle of a symmetric positive definite matrix,
201
+ the algorithm generates matrix A^-1 and saves the upper or lower triangle
202
+ depending on the input.
203
+
204
+ Input parameters:
205
+ A - matrix to be inverted (upper or lower triangle).
206
+ Array with elements [0..N-1,0..N-1].
207
+ N - size of matrix A.
208
+ IsUpper - storage format.
209
+ If IsUpper = True, then the upper triangle of matrix A is
210
+ given, otherwise the lower triangle is given.
211
+
212
+ Output parameters:
213
+ A - inverse of matrix A.
214
+ Array with elements [0..N-1,0..N-1].
215
+ If IsUpper = True, then the upper triangle of matrix A^-1
216
+ is used, and the elements below the main diagonal are not
217
+ used nor changed. The same applies if IsUpper = False.
218
+
219
+ Result:
220
+ True, if the matrix is positive definite.
221
+ False, if the matrix is not positive definite (and it could not be
222
+ inverted by this algorithm).
223
+ *************************************************************************/
224
+ bool spdmatrixinverse(ap::real_2d_array& a, int n, bool isupper)
225
+ {
226
+ bool result;
227
+
228
+ result = false;
229
+ if( spdmatrixcholesky(a, n, isupper) )
230
+ {
231
+ if( spdmatrixcholeskyinverse(a, n, isupper) )
232
+ {
233
+ result = true;
234
+ }
235
+ }
236
+ return result;
237
+ }
238
+
239
+
240
+ /*************************************************************************
241
+ Obsolete subroutine.
242
+ *************************************************************************/
243
+ bool inversecholesky(ap::real_2d_array& a, int n, bool isupper)
244
+ {
245
+ bool result;
246
+ int i;
247
+ int j;
248
+ int k;
249
+ int nmj;
250
+ int jm1;
251
+ int jp1;
252
+ int ip1;
253
+ double v;
254
+ double ajj;
255
+ double aii;
256
+ ap::real_1d_array t;
257
+ ap::real_1d_array d;
258
+
259
+ result = true;
260
+
261
+ //
262
+ // Test the input parameters.
263
+ //
264
+ t.setbounds(1, n);
265
+ d.setbounds(1, n);
266
+ if( isupper )
267
+ {
268
+
269
+ //
270
+ // Compute inverse of upper triangular matrix.
271
+ //
272
+ for(j = 1; j <= n; j++)
273
+ {
274
+ if( a(j,j)==0 )
275
+ {
276
+ result = false;
277
+ return result;
278
+ }
279
+ jm1 = j-1;
280
+ a(j,j) = 1/a(j,j);
281
+ ajj = -a(j,j);
282
+
283
+ //
284
+ // Compute elements 1:j-1 of j-th column.
285
+ //
286
+ ap::vmove(t.getvector(1, jm1), a.getcolumn(j, 1, jm1));
287
+ for(i = 1; i <= j-1; i++)
288
+ {
289
+ v = ap::vdotproduct(a.getrow(i, i, jm1), a.getcolumn(j, i, jm1));
290
+ a(i,j) = v;
291
+ }
292
+ ap::vmul(a.getcolumn(j, 1, jm1), ajj);
293
+ }
294
+
295
+ //
296
+ // InvA = InvU * InvU'
297
+ //
298
+ for(i = 1; i <= n; i++)
299
+ {
300
+ aii = a(i,i);
301
+ if( i<n )
302
+ {
303
+ v = ap::vdotproduct(&a(i, i), &a(i, i), ap::vlen(i,n));
304
+ a(i,i) = v;
305
+ ip1 = i+1;
306
+ for(k = 1; k <= i-1; k++)
307
+ {
308
+ v = ap::vdotproduct(&a(k, ip1), &a(i, ip1), ap::vlen(ip1,n));
309
+ a(k,i) = a(k,i)*aii+v;
310
+ }
311
+ }
312
+ else
313
+ {
314
+ ap::vmul(a.getcolumn(i, 1, i), aii);
315
+ }
316
+ }
317
+ }
318
+ else
319
+ {
320
+
321
+ //
322
+ // Compute inverse of lower triangular matrix.
323
+ //
324
+ for(j = n; j >= 1; j--)
325
+ {
326
+ if( a(j,j)==0 )
327
+ {
328
+ result = false;
329
+ return result;
330
+ }
331
+ a(j,j) = 1/a(j,j);
332
+ ajj = -a(j,j);
333
+ if( j<n )
334
+ {
335
+
336
+ //
337
+ // Compute elements j+1:n of j-th column.
338
+ //
339
+ nmj = n-j;
340
+ jp1 = j+1;
341
+ ap::vmove(t.getvector(jp1, n), a.getcolumn(j, jp1, n));
342
+ for(i = j+1; i <= n; i++)
343
+ {
344
+ v = ap::vdotproduct(&a(i, jp1), &t(jp1), ap::vlen(jp1,i));
345
+ a(i,j) = v;
346
+ }
347
+ ap::vmul(a.getcolumn(j, jp1, n), ajj);
348
+ }
349
+ }
350
+
351
+ //
352
+ // InvA = InvL' * InvL
353
+ //
354
+ for(i = 1; i <= n; i++)
355
+ {
356
+ aii = a(i,i);
357
+ if( i<n )
358
+ {
359
+ v = ap::vdotproduct(a.getcolumn(i, i, n), a.getcolumn(i, i, n));
360
+ a(i,i) = v;
361
+ ip1 = i+1;
362
+ for(k = 1; k <= i-1; k++)
363
+ {
364
+ v = ap::vdotproduct(a.getcolumn(k, ip1, n), a.getcolumn(i, ip1, n));
365
+ a(i,k) = aii*a(i,k)+v;
366
+ }
367
+ }
368
+ else
369
+ {
370
+ ap::vmul(&a(i, 1), ap::vlen(1,i), aii);
371
+ }
372
+ }
373
+ }
374
+ return result;
375
+ }
376
+
377
+
378
+ /*************************************************************************
379
+ Obsolete subroutine.
380
+ *************************************************************************/
381
+ bool inversesymmetricpositivedefinite(ap::real_2d_array& a,
382
+ int n,
383
+ bool isupper)
384
+ {
385
+ bool result;
386
+
387
+ result = false;
388
+ if( choleskydecomposition(a, n, isupper) )
389
+ {
390
+ if( inversecholesky(a, n, isupper) )
391
+ {
392
+ result = true;
393
+ }
394
+ }
395
+ return result;
396
+ }
397
+
398
+
399
+ static void testinversecholesky()
400
+ {
401
+ ap::real_2d_array l;
402
+ ap::real_2d_array a;
403
+ ap::real_2d_array inva;
404
+ int n;
405
+ int pass;
406
+ int passcount;
407
+ int i;
408
+ int j;
409
+ int minij;
410
+ bool upperin;
411
+ bool cr;
412
+ double err;
413
+ double v;
414
+
415
+ err = 0;
416
+ passcount = 100;
417
+ for(pass = 1; pass <= passcount; pass++)
418
+ {
419
+ n = 1+ap::randominteger(50);
420
+ upperin = ap::randomreal()>0.5;
421
+ l.setbounds(1, n, 1, n);
422
+ a.setbounds(1, n, 1, n);
423
+ inva.setbounds(1, n, 1, n);
424
+ for(i = 1; i <= n; i++)
425
+ {
426
+ for(j = i+1; j <= n; j++)
427
+ {
428
+ l(i,j) = ap::randomreal();
429
+ l(j,i) = l(i,j);
430
+ }
431
+ l(i,i) = 1.1+ap::randomreal();
432
+ }
433
+ for(i = 1; i <= n; i++)
434
+ {
435
+ for(j = 1; j <= n; j++)
436
+ {
437
+ minij = ap::minint(i, j);
438
+ v = ap::vdotproduct(l.getrow(i, 1, minij), l.getcolumn(j, 1, minij));
439
+ a(i,j) = v;
440
+ a(j,i) = v;
441
+ inva(i,j) = v;
442
+ inva(j,i) = v;
443
+ }
444
+ }
445
+ for(i = 1; i <= n; i++)
446
+ {
447
+ for(j = 1; j <= n; j++)
448
+ {
449
+ if( upperin )
450
+ {
451
+ if( j<i )
452
+ {
453
+ inva(i,j) = 0;
454
+ }
455
+ }
456
+ else
457
+ {
458
+ if( i<j )
459
+ {
460
+ inva(i,j) = 0;
461
+ }
462
+ }
463
+ }
464
+ }
465
+ cr = inversesymmetricpositivedefinite(inva, n, upperin);
466
+ ap::ap_error::make_assertion(cr, "Something strange");
467
+ for(i = 1; i <= n; i++)
468
+ {
469
+ for(j = 1; j <= n; j++)
470
+ {
471
+ if( upperin )
472
+ {
473
+ if( j<i )
474
+ {
475
+ inva(i,j) = inva(j,i);
476
+ }
477
+ }
478
+ else
479
+ {
480
+ if( i<j )
481
+ {
482
+ inva(i,j) = inva(j,i);
483
+ }
484
+ }
485
+ }
486
+ }
487
+ for(i = 1; i <= n; i++)
488
+ {
489
+ for(j = 1; j <= n; j++)
490
+ {
491
+ v = ap::vdotproduct(a.getrow(i, 1, n), inva.getcolumn(j, 1, n));
492
+ if( j==i )
493
+ {
494
+ err = ap::maxreal(err, fabs(v-1));
495
+ }
496
+ else
497
+ {
498
+ err = ap::maxreal(err, fabs(v));
499
+ }
500
+ }
501
+ }
502
+ }
503
+ printf("Pass count %0ld\nInverseSymmetricPositiveDefinite error is %5.3le\n",
504
+ long(passcount),
505
+ double(err));
506
+ }
507
+
508
+
509
+