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,133 @@
1
+ /*************************************************************************
2
+ Copyright (c) 2008, 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 _lda_h
34
+ #define _lda_h
35
+
36
+ #include "ap.h"
37
+ #include "ialglib.h"
38
+
39
+ #include "blas.h"
40
+ #include "rotations.h"
41
+ #include "tdevd.h"
42
+ #include "sblas.h"
43
+ #include "reflections.h"
44
+ #include "tridiagonal.h"
45
+ #include "sevd.h"
46
+ #include "cholesky.h"
47
+ #include "spdinverse.h"
48
+
49
+
50
+ /*************************************************************************
51
+ Multiclass Fisher LDA
52
+
53
+ Subroutine finds coefficients of linear combination which optimally separates
54
+ training set on classes.
55
+
56
+ INPUT PARAMETERS:
57
+ XY - training set, array[0..NPoints-1,0..NVars].
58
+ First NVars columns store values of independent
59
+ variables, next column stores number of class (from 0
60
+ to NClasses-1) which dataset element belongs to. Fractional
61
+ values are rounded to nearest integer.
62
+ NPoints - training set size, NPoints>=0
63
+ NVars - number of independent variables, NVars>=1
64
+ NClasses - number of classes, NClasses>=2
65
+
66
+
67
+ OUTPUT PARAMETERS:
68
+ Info - return code:
69
+ * -4, if internal EVD subroutine hasn't converged
70
+ * -2, if there is a point with class number
71
+ outside of [0..NClasses-1].
72
+ * -1, if incorrect parameters was passed (NPoints<0,
73
+ NVars<1, NClasses<2)
74
+ * 1, if task has been solved
75
+ * 2, if there was a multicollinearity in training set,
76
+ but task has been solved.
77
+ W - linear combination coefficients, array[0..NVars-1]
78
+
79
+ -- ALGLIB --
80
+ Copyright 31.05.2008 by Bochkanov Sergey
81
+ *************************************************************************/
82
+ void fisherlda(const ap::real_2d_array& xy,
83
+ int npoints,
84
+ int nvars,
85
+ int nclasses,
86
+ int& info,
87
+ ap::real_1d_array& w);
88
+
89
+
90
+ /*************************************************************************
91
+ N-dimensional multiclass Fisher LDA
92
+
93
+ Subroutine finds coefficients of linear combinations which optimally separates
94
+ training set on classes. It returns N-dimensional basis whose vector are sorted
95
+ by quality of training set separation (in descending order).
96
+
97
+ INPUT PARAMETERS:
98
+ XY - training set, array[0..NPoints-1,0..NVars].
99
+ First NVars columns store values of independent
100
+ variables, next column stores number of class (from 0
101
+ to NClasses-1) which dataset element belongs to. Fractional
102
+ values are rounded to nearest integer.
103
+ NPoints - training set size, NPoints>=0
104
+ NVars - number of independent variables, NVars>=1
105
+ NClasses - number of classes, NClasses>=2
106
+
107
+
108
+ OUTPUT PARAMETERS:
109
+ Info - return code:
110
+ * -4, if internal EVD subroutine hasn't converged
111
+ * -2, if there is a point with class number
112
+ outside of [0..NClasses-1].
113
+ * -1, if incorrect parameters was passed (NPoints<0,
114
+ NVars<1, NClasses<2)
115
+ * 1, if task has been solved
116
+ * 2, if there was a multicollinearity in training set,
117
+ but task has been solved.
118
+ W - basis, array[0..NVars-1,0..NVars-1]
119
+ columns of matrix stores basis vectors, sorted by
120
+ quality of training set separation (in descending order)
121
+
122
+ -- ALGLIB --
123
+ Copyright 31.05.2008 by Bochkanov Sergey
124
+ *************************************************************************/
125
+ void fisherldan(const ap::real_2d_array& xy,
126
+ int npoints,
127
+ int nvars,
128
+ int nclasses,
129
+ int& info,
130
+ ap::real_2d_array& w);
131
+
132
+
133
+ #endif
@@ -0,0 +1,1130 @@
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 "ldlt.h"
41
+
42
+ /*************************************************************************
43
+ LDLTDecomposition of a symmetric matrix
44
+
45
+ The algorithm represents a symmetric matrix (which is not necessarily
46
+ positive definite) as A=L*D*L' or A = U*D*U', where D is a block-diagonal
47
+ matrix with blocks 1x1 or 2x2, matrix L (matrix U) is a product of lower
48
+ (upper) triangular matrices with unit diagonal and permutation matrices.
49
+
50
+ Input parameters:
51
+ A - factorized matrix, array with elements [0..N-1, 0..N-1].
52
+ If IsUpper � True, then the upper triangle contains
53
+ elements of symmetric matrix A, and the lower triangle is
54
+ not used.
55
+ The same applies if IsUpper = False.
56
+ N - size of factorized matrix.
57
+ IsUpper - parameter which shows a method of matrix definition (lower
58
+ or upper triangle).
59
+
60
+ Output parameters:
61
+ A - matrices D and U, if IsUpper = True, or L, if IsUpper = False,
62
+ in compact form, replacing the upper (lower) triangle of
63
+ matrix A. In that case, the elements under (over) the main
64
+ diagonal are not used nor modified.
65
+ Pivots - tables of performed permutations (see below).
66
+
67
+ If IsUpper = True, then A = U*D*U', U = P(n)*U(n)*...*P(k)*U(k), where
68
+ P(k) is the permutation matrix, U(k) - upper triangular matrix with its
69
+ unit main diagonal and k decreases from n with step s which is equal to
70
+ 1 or 2 (according to the size of the blocks of matrix D).
71
+
72
+ ( I v 0 ) k-s+1
73
+ U(k) = ( 0 I 0 ) s
74
+ ( 0 0 I ) n-k-1
75
+ k-s+1 s n-k-1
76
+
77
+ If Pivots[k]>=0, then s=1, P(k) - permutation of rows k and Pivots[k], the
78
+ vectorv forming matrix U(k) is stored in elements A(0:k-1,k), D(k) replaces
79
+ A(k,k). If Pivots[k]=Pivots[k-1]<0 then s=2, P(k) - permutation of rows k-1
80
+ and N+Pivots[k-1], the vector v forming matrix U(k) is stored in elements
81
+ A(0:k-1,k:k+1), the upper triangle of block D(k) is stored in A(k,k),
82
+ A(k,k+1) and A(k+1,k+1).
83
+
84
+ If IsUpper = False, then A = L*D*L', L=P(0)*L(0)*...*P(k)*L(k), where P(k)
85
+ is the permutation matrix, L(k) � lower triangular matrix with unit main
86
+ diagonal and k decreases from 1 with step s which is equal to 1 or 2
87
+ (according to the size of the blocks of matrix D).
88
+
89
+ ( I 0 0 ) k-1
90
+ L(k) = ( 0 I 0 ) s
91
+ ( 0 v I ) n-k-s+1
92
+ k-1 s n-k-s+1
93
+
94
+ If Pivots[k]>=0 then s=1, P(k) � permutation of rows k and Pivots[k], the
95
+ vector v forming matrix L(k) is stored in elements A(k+1:n-1,k), D(k)
96
+ replaces A(k,k). If Pivots[k]=Pivots[k+1]<0 then s=2, P(k) - permutation
97
+ of rows k+1 and N+Pivots[k+1], the vector v forming matrix L(k) is stored
98
+ in elements A(k+2:n-1,k:k+1), the lower triangle of block D(k) is stored in
99
+ A(k,k), A(k+1,k) and A(k+1,k+1).
100
+
101
+ -- LAPACK routine (version 3.0) --
102
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
103
+ Courant Institute, Argonne National Lab, and Rice University
104
+ June 30, 1999
105
+ *************************************************************************/
106
+ void smatrixldlt(ap::real_2d_array& a,
107
+ int n,
108
+ bool isupper,
109
+ ap::integer_1d_array& pivots)
110
+ {
111
+ int i;
112
+ int imax;
113
+ int j;
114
+ int jmax;
115
+ int k;
116
+ int kk;
117
+ int kp;
118
+ int kstep;
119
+ double absakk;
120
+ double alpha;
121
+ double colmax;
122
+ double d11;
123
+ double d12;
124
+ double d21;
125
+ double d22;
126
+ double r1;
127
+ double rowmax;
128
+ double t;
129
+ double wk;
130
+ double wkm1;
131
+ double wkp1;
132
+ int ii;
133
+ int i1;
134
+ int i2;
135
+ double vv;
136
+ ap::real_1d_array temp;
137
+
138
+ pivots.setbounds(0, n-1);
139
+ temp.setbounds(0, n-1);
140
+
141
+ //
142
+ // Initialize ALPHA for use in choosing pivot block size.
143
+ //
144
+ alpha = (1+sqrt(double(17)))/8;
145
+ if( isupper )
146
+ {
147
+
148
+ //
149
+ // Factorize A as U*D*U' using the upper triangle of A
150
+ //
151
+ //
152
+ // K is the main loop index, decreasing from N to 1 in steps of
153
+ // 1 or 2
154
+ //
155
+ k = n-1;
156
+ while(k>=0)
157
+ {
158
+ kstep = 1;
159
+
160
+ //
161
+ // Determine rows and columns to be interchanged and whether
162
+ // a 1-by-1 or 2-by-2 pivot block will be used
163
+ //
164
+ absakk = fabs(a(k,k));
165
+
166
+ //
167
+ // IMAX is the row-index of the largest off-diagonal element in
168
+ // column K+1, and COLMAX is its absolute value
169
+ //
170
+ if( k>0 )
171
+ {
172
+ imax = 1;
173
+ for(ii = 2; ii <= k; ii++)
174
+ {
175
+ if( fabs(a(ii-1,k))>fabs(a(imax-1,k)) )
176
+ {
177
+ imax = ii;
178
+ }
179
+ }
180
+ colmax = fabs(a(imax-1,k));
181
+ }
182
+ else
183
+ {
184
+ colmax = 0;
185
+ }
186
+ if( ap::maxreal(absakk, colmax)==0 )
187
+ {
188
+
189
+ //
190
+ // Column K is zero
191
+ //
192
+ kp = k;
193
+ }
194
+ else
195
+ {
196
+ if( absakk>=alpha*colmax )
197
+ {
198
+
199
+ //
200
+ // no interchange, use 1-by-1 pivot block
201
+ //
202
+ kp = k;
203
+ }
204
+ else
205
+ {
206
+
207
+ //
208
+ // JMAX is the column-index of the largest off-diagonal
209
+ // element in row IMAX, and ROWMAX is its absolute value
210
+ //
211
+ jmax = imax+1;
212
+ for(ii = imax+2; ii <= k+1; ii++)
213
+ {
214
+ if( fabs(a(imax-1,ii-1))>fabs(a(imax-1,jmax-1)) )
215
+ {
216
+ jmax = ii;
217
+ }
218
+ }
219
+ rowmax = fabs(a(imax-1,jmax-1));
220
+ if( imax>1 )
221
+ {
222
+ jmax = 1;
223
+ for(ii = 2; ii <= imax-1; ii++)
224
+ {
225
+ if( fabs(a(ii-1,imax-1))>fabs(a(jmax-1,imax-1)) )
226
+ {
227
+ jmax = ii;
228
+ }
229
+ }
230
+ rowmax = ap::maxreal(rowmax, fabs(a(jmax-1,imax-1)));
231
+ }
232
+ vv = colmax/rowmax;
233
+ if( absakk>=alpha*colmax*vv )
234
+ {
235
+
236
+ //
237
+ // no interchange, use 1-by-1 pivot block
238
+ //
239
+ kp = k;
240
+ }
241
+ else
242
+ {
243
+ if( fabs(a(imax-1,imax-1))>=alpha*rowmax )
244
+ {
245
+
246
+ //
247
+ // interchange rows and columns K and IMAX, use 1-by-1
248
+ // pivot block
249
+ //
250
+ kp = imax-1;
251
+ }
252
+ else
253
+ {
254
+
255
+ //
256
+ // interchange rows and columns K-1 and IMAX, use 2-by-2
257
+ // pivot block
258
+ //
259
+ kp = imax-1;
260
+ kstep = 2;
261
+ }
262
+ }
263
+ }
264
+ kk = k+1-kstep;
265
+ if( kp+1!=kk+1 )
266
+ {
267
+
268
+ //
269
+ // Interchange rows and columns KK and KP+1 in the leading
270
+ // submatrix A(0:K,0:K)
271
+ //
272
+ ap::vmove(temp.getvector(0, kp-1), a.getcolumn(kk, 0, kp-1));
273
+ ap::vmove(a.getcolumn(kk, 0, kp-1), a.getcolumn(kp, 0, kp-1));
274
+ ap::vmove(a.getcolumn(kp, 0, kp-1), temp.getvector(0, kp-1));
275
+ ap::vmove(temp.getvector(kp+1, kk-1), a.getcolumn(kk, kp+1, kk-1));
276
+ ap::vmove(a.getcolumn(kk, kp+1, kk-1), a.getrow(kp, kp+1, kk-1));
277
+ ap::vmove(&a(kp, kp+1), &temp(kp+1), ap::vlen(kp+1,kk-1));
278
+ t = a(kk,kk);
279
+ a(kk,kk) = a(kp,kp);
280
+ a(kp,kp) = t;
281
+ if( kstep==2 )
282
+ {
283
+ t = a(k-1,k);
284
+ a(k-1,k) = a(kp,k);
285
+ a(kp,k) = t;
286
+ }
287
+ }
288
+
289
+ //
290
+ // Update the leading submatrix
291
+ //
292
+ if( kstep==1 )
293
+ {
294
+
295
+ //
296
+ // 1-by-1 pivot block D(k): column k now holds
297
+ //
298
+ // W(k) = U(k)*D(k)
299
+ //
300
+ // where U(k) is the k-th column of U
301
+ //
302
+ // Perform a rank-1 update of A(1:k-1,1:k-1) as
303
+ //
304
+ // A := A - U(k)*D(k)*U(k)' = A - W(k)*1/D(k)*W(k)'
305
+ //
306
+ r1 = 1/a(k,k);
307
+ for(i = 0; i <= k-1; i++)
308
+ {
309
+ vv = -r1*a(i,k);
310
+ ap::vadd(a.getrow(i, i, k-1), a.getcolumn(k, i, k-1), vv);
311
+ }
312
+
313
+ //
314
+ // Store U(K+1) in column K+1
315
+ //
316
+ ap::vmul(a.getcolumn(k, 0, k-1), r1);
317
+ }
318
+ else
319
+ {
320
+
321
+ //
322
+ // 2-by-2 pivot block D(k): columns k and k-1 now hold
323
+ //
324
+ // ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k)
325
+ //
326
+ // where U(k) and U(k-1) are the k-th and (k-1)-th columns
327
+ // of U
328
+ //
329
+ // Perform a rank-2 update of A(1:k-2,1:k-2) as
330
+ //
331
+ // A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )'
332
+ // = A - ( W(k-1) W(k) )*inv(D(k))*( W(k-1) W(k) )'
333
+ //
334
+ if( k>1 )
335
+ {
336
+ d12 = a(k-1,k);
337
+ d22 = a(k-1,k-1)/d12;
338
+ d11 = a(k,k)/d12;
339
+ t = 1/(d11*d22-1);
340
+ d12 = t/d12;
341
+ for(j = k-2; j >= 0; j--)
342
+ {
343
+ wkm1 = d12*(d11*a(j,k-1)-a(j,k));
344
+ wk = d12*(d22*a(j,k)-a(j,k-1));
345
+ ap::vsub(a.getcolumn(j, 0, j), a.getcolumn(k, 0, j), wk);
346
+ ap::vsub(a.getcolumn(j, 0, j), a.getcolumn(k-1, 0, j), wkm1);
347
+ a(j,k) = wk;
348
+ a(j,k-1) = wkm1;
349
+ }
350
+ }
351
+ }
352
+ }
353
+
354
+ //
355
+ // Store details of the interchanges in IPIV
356
+ //
357
+ if( kstep==1 )
358
+ {
359
+ pivots(k) = kp;
360
+ }
361
+ else
362
+ {
363
+ pivots(k) = kp-n;
364
+ pivots(k-1) = kp-n;
365
+ }
366
+
367
+ //
368
+ // Decrease K+1 and return to the start of the main loop
369
+ //
370
+ k = k-kstep;
371
+ }
372
+ }
373
+ else
374
+ {
375
+
376
+ //
377
+ // Factorize A as L*D*L' using the lower triangle of A
378
+ //
379
+ // K+1 is the main loop index, increasing from 1 to N in steps of
380
+ // 1 or 2
381
+ //
382
+ k = 0;
383
+ while(k<=n-1)
384
+ {
385
+ kstep = 1;
386
+
387
+ //
388
+ // Determine rows and columns to be interchanged and whether
389
+ // a 1-by-1 or 2-by-2 pivot block will be used
390
+ //
391
+ absakk = fabs(a(k,k));
392
+
393
+ //
394
+ // IMAX is the row-index of the largest off-diagonal element in
395
+ // column K+1, and COLMAX is its absolute value
396
+ //
397
+ if( k<n-1 )
398
+ {
399
+ imax = k+1+1;
400
+ for(ii = k+1+2; ii <= n; ii++)
401
+ {
402
+ if( fabs(a(ii-1,k))>fabs(a(imax-1,k)) )
403
+ {
404
+ imax = ii;
405
+ }
406
+ }
407
+ colmax = fabs(a(imax-1,k));
408
+ }
409
+ else
410
+ {
411
+ colmax = 0;
412
+ }
413
+ if( ap::maxreal(absakk, colmax)==0 )
414
+ {
415
+
416
+ //
417
+ // Column K+1 is zero
418
+ //
419
+ kp = k;
420
+ }
421
+ else
422
+ {
423
+ if( absakk>=alpha*colmax )
424
+ {
425
+
426
+ //
427
+ // no interchange, use 1-by-1 pivot block
428
+ //
429
+ kp = k;
430
+ }
431
+ else
432
+ {
433
+
434
+ //
435
+ // JMAX is the column-index of the largest off-diagonal
436
+ // element in row IMAX, and ROWMAX is its absolute value
437
+ //
438
+ jmax = k+1;
439
+ for(ii = k+1+1; ii <= imax-1; ii++)
440
+ {
441
+ if( fabs(a(imax-1,ii-1))>fabs(a(imax-1,jmax-1)) )
442
+ {
443
+ jmax = ii;
444
+ }
445
+ }
446
+ rowmax = fabs(a(imax-1,jmax-1));
447
+ if( imax<n )
448
+ {
449
+ jmax = imax+1;
450
+ for(ii = imax+2; ii <= n; ii++)
451
+ {
452
+ if( fabs(a(ii-1,imax-1))>fabs(a(jmax-1,imax-1)) )
453
+ {
454
+ jmax = ii;
455
+ }
456
+ }
457
+ rowmax = ap::maxreal(rowmax, fabs(a(jmax-1,imax-1)));
458
+ }
459
+ vv = colmax/rowmax;
460
+ if( absakk>=alpha*colmax*vv )
461
+ {
462
+
463
+ //
464
+ // no interchange, use 1-by-1 pivot block
465
+ //
466
+ kp = k;
467
+ }
468
+ else
469
+ {
470
+ if( fabs(a(imax-1,imax-1))>=alpha*rowmax )
471
+ {
472
+
473
+ //
474
+ // interchange rows and columns K+1 and IMAX, use 1-by-1
475
+ // pivot block
476
+ //
477
+ kp = imax-1;
478
+ }
479
+ else
480
+ {
481
+
482
+ //
483
+ // interchange rows and columns K+1+1 and IMAX, use 2-by-2
484
+ // pivot block
485
+ //
486
+ kp = imax-1;
487
+ kstep = 2;
488
+ }
489
+ }
490
+ }
491
+ kk = k+kstep-1;
492
+ if( kp!=kk )
493
+ {
494
+
495
+ //
496
+ // Interchange rows and columns KK+1 and KP+1 in the trailing
497
+ // submatrix A(K+1:n,K+1:n)
498
+ //
499
+ if( kp+1<n )
500
+ {
501
+ ap::vmove(temp.getvector(kp+1, n-1), a.getcolumn(kk, kp+1, n-1));
502
+ ap::vmove(a.getcolumn(kk, kp+1, n-1), a.getcolumn(kp, kp+1, n-1));
503
+ ap::vmove(a.getcolumn(kp, kp+1, n-1), temp.getvector(kp+1, n-1));
504
+ }
505
+ ap::vmove(temp.getvector(kk+1, kp-1), a.getcolumn(kk, kk+1, kp-1));
506
+ ap::vmove(a.getcolumn(kk, kk+1, kp-1), a.getrow(kp, kk+1, kp-1));
507
+ ap::vmove(&a(kp, kk+1), &temp(kk+1), ap::vlen(kk+1,kp-1));
508
+ t = a(kk,kk);
509
+ a(kk,kk) = a(kp,kp);
510
+ a(kp,kp) = t;
511
+ if( kstep==2 )
512
+ {
513
+ t = a(k+1,k);
514
+ a(k+1,k) = a(kp,k);
515
+ a(kp,k) = t;
516
+ }
517
+ }
518
+
519
+ //
520
+ // Update the trailing submatrix
521
+ //
522
+ if( kstep==1 )
523
+ {
524
+
525
+ //
526
+ // 1-by-1 pivot block D(K+1): column K+1 now holds
527
+ //
528
+ // W(K+1) = L(K+1)*D(K+1)
529
+ //
530
+ // where L(K+1) is the K+1-th column of L
531
+ //
532
+ if( k+1<n )
533
+ {
534
+
535
+ //
536
+ // Perform a rank-1 update of A(K+1+1:n,K+1+1:n) as
537
+ //
538
+ // A := A - L(K+1)*D(K+1)*L(K+1)' = A - W(K+1)*(1/D(K+1))*W(K+1)'
539
+ //
540
+ d11 = 1/a(k+1-1,k+1-1);
541
+ for(ii = k+1; ii <= n-1; ii++)
542
+ {
543
+ vv = -d11*a(ii,k);
544
+ ap::vadd(a.getrow(ii, k+1, ii), a.getcolumn(k, k+1, ii), vv);
545
+ }
546
+
547
+ //
548
+ // Store L(K+1) in column K+1
549
+ //
550
+ ap::vmul(a.getcolumn(k, k+1, n-1), d11);
551
+ }
552
+ }
553
+ else
554
+ {
555
+
556
+ //
557
+ // 2-by-2 pivot block D(K+1)
558
+ //
559
+ if( k<n-2 )
560
+ {
561
+
562
+ //
563
+ // Perform a rank-2 update of A(K+1+2:n,K+1+2:n) as
564
+ //
565
+ // A := A - ( (A(K+1) A(K+1+1))*D(K+1)**(-1) ) * (A(K+1) A(K+1+1))'
566
+ //
567
+ // where L(K+1) and L(K+1+1) are the K+1-th and (K+1+1)-th
568
+ // columns of L
569
+ //
570
+ d21 = a(k+1,k);
571
+ d11 = a(k+1,k+1)/d21;
572
+ d22 = a(k,k)/d21;
573
+ t = 1/(d11*d22-1);
574
+ d21 = t/d21;
575
+ for(j = k+2; j <= n-1; j++)
576
+ {
577
+ wk = d21*(d11*a(j,k)-a(j,k+1));
578
+ wkp1 = d21*(d22*a(j,k+1)-a(j,k));
579
+ ap::vsub(a.getcolumn(j, j, n-1), a.getcolumn(k, j, n-1), wk);
580
+ ap::vsub(a.getcolumn(j, j, n-1), a.getcolumn(k+1, j, n-1), wkp1);
581
+ a(j,k) = wk;
582
+ a(j,k+1) = wkp1;
583
+ }
584
+ }
585
+ }
586
+ }
587
+
588
+ //
589
+ // Store details of the interchanges in IPIV
590
+ //
591
+ if( kstep==1 )
592
+ {
593
+ pivots(k+1-1) = kp+1-1;
594
+ }
595
+ else
596
+ {
597
+ pivots(k+1-1) = kp+1-1-n;
598
+ pivots(k+1+1-1) = kp+1-1-n;
599
+ }
600
+
601
+ //
602
+ // Increase K+1 and return to the start of the main loop
603
+ //
604
+ k = k+kstep;
605
+ }
606
+ }
607
+ }
608
+
609
+
610
+ /*************************************************************************
611
+ Obsolete subroutine.
612
+ *************************************************************************/
613
+ void ldltdecomposition(ap::real_2d_array& a,
614
+ int n,
615
+ bool isupper,
616
+ ap::integer_1d_array& pivots)
617
+ {
618
+ int i;
619
+ int imax;
620
+ int j;
621
+ int jmax;
622
+ int k;
623
+ int kk;
624
+ int kp;
625
+ int kstep;
626
+ double absakk;
627
+ double alpha;
628
+ double colmax;
629
+ double d11;
630
+ double d12;
631
+ double d21;
632
+ double d22;
633
+ double r1;
634
+ double rowmax;
635
+ double t;
636
+ double wk;
637
+ double wkm1;
638
+ double wkp1;
639
+ int ii;
640
+ int i1;
641
+ int i2;
642
+ double vv;
643
+ ap::real_1d_array temp;
644
+
645
+ pivots.setbounds(1, n);
646
+ temp.setbounds(1, n);
647
+
648
+ //
649
+ // Initialize ALPHA for use in choosing pivot block size.
650
+ //
651
+ alpha = (1+sqrt(double(17)))/8;
652
+ if( isupper )
653
+ {
654
+
655
+ //
656
+ // Factorize A as U*D*U' using the upper triangle of A
657
+ //
658
+ //
659
+ // K is the main loop index, decreasing from N to 1 in steps of
660
+ // 1 or 2
661
+ //
662
+ k = n;
663
+ while(k>=1)
664
+ {
665
+ kstep = 1;
666
+
667
+ //
668
+ // Determine rows and columns to be interchanged and whether
669
+ // a 1-by-1 or 2-by-2 pivot block will be used
670
+ //
671
+ absakk = fabs(a(k,k));
672
+
673
+ //
674
+ // IMAX is the row-index of the largest off-diagonal element in
675
+ // column K, and COLMAX is its absolute value
676
+ //
677
+ if( k>1 )
678
+ {
679
+ imax = 1;
680
+ for(ii = 2; ii <= k-1; ii++)
681
+ {
682
+ if( fabs(a(ii,k))>fabs(a(imax,k)) )
683
+ {
684
+ imax = ii;
685
+ }
686
+ }
687
+ colmax = fabs(a(imax,k));
688
+ }
689
+ else
690
+ {
691
+ colmax = 0;
692
+ }
693
+ if( ap::maxreal(absakk, colmax)==0 )
694
+ {
695
+
696
+ //
697
+ // Column K is zero
698
+ //
699
+ kp = k;
700
+ }
701
+ else
702
+ {
703
+ if( absakk>=alpha*colmax )
704
+ {
705
+
706
+ //
707
+ // no interchange, use 1-by-1 pivot block
708
+ //
709
+ kp = k;
710
+ }
711
+ else
712
+ {
713
+
714
+ //
715
+ // JMAX is the column-index of the largest off-diagonal
716
+ // element in row IMAX, and ROWMAX is its absolute value
717
+ //
718
+ jmax = imax+1;
719
+ for(ii = imax+2; ii <= k; ii++)
720
+ {
721
+ if( fabs(a(imax,ii))>fabs(a(imax,jmax)) )
722
+ {
723
+ jmax = ii;
724
+ }
725
+ }
726
+ rowmax = fabs(a(imax,jmax));
727
+ if( imax>1 )
728
+ {
729
+ jmax = 1;
730
+ for(ii = 2; ii <= imax-1; ii++)
731
+ {
732
+ if( fabs(a(ii,imax))>fabs(a(jmax,imax)) )
733
+ {
734
+ jmax = ii;
735
+ }
736
+ }
737
+ rowmax = ap::maxreal(rowmax, fabs(a(jmax,imax)));
738
+ }
739
+ vv = colmax/rowmax;
740
+ if( absakk>=alpha*colmax*vv )
741
+ {
742
+
743
+ //
744
+ // no interchange, use 1-by-1 pivot block
745
+ //
746
+ kp = k;
747
+ }
748
+ else
749
+ {
750
+ if( fabs(a(imax,imax))>=alpha*rowmax )
751
+ {
752
+
753
+ //
754
+ // interchange rows and columns K and IMAX, use 1-by-1
755
+ // pivot block
756
+ //
757
+ kp = imax;
758
+ }
759
+ else
760
+ {
761
+
762
+ //
763
+ // interchange rows and columns K-1 and IMAX, use 2-by-2
764
+ // pivot block
765
+ //
766
+ kp = imax;
767
+ kstep = 2;
768
+ }
769
+ }
770
+ }
771
+ kk = k-kstep+1;
772
+ if( kp!=kk )
773
+ {
774
+
775
+ //
776
+ // Interchange rows and columns KK and KP in the leading
777
+ // submatrix A(1:k,1:k)
778
+ //
779
+ i1 = kp-1;
780
+ ap::vmove(temp.getvector(1, i1), a.getcolumn(kk, 1, i1));
781
+ ap::vmove(a.getcolumn(kk, 1, i1), a.getcolumn(kp, 1, i1));
782
+ ap::vmove(a.getcolumn(kp, 1, i1), temp.getvector(1, i1));
783
+ i1 = kp+1;
784
+ i2 = kk-1;
785
+ ap::vmove(temp.getvector(i1, i2), a.getcolumn(kk, i1, i2));
786
+ ap::vmove(a.getcolumn(kk, i1, i2), a.getrow(kp, i1, i2));
787
+ ap::vmove(&a(kp, i1), &temp(i1), ap::vlen(i1,i2));
788
+ t = a(kk,kk);
789
+ a(kk,kk) = a(kp,kp);
790
+ a(kp,kp) = t;
791
+ if( kstep==2 )
792
+ {
793
+ t = a(k-1,k);
794
+ a(k-1,k) = a(kp,k);
795
+ a(kp,k) = t;
796
+ }
797
+ }
798
+
799
+ //
800
+ // Update the leading submatrix
801
+ //
802
+ if( kstep==1 )
803
+ {
804
+
805
+ //
806
+ // 1-by-1 pivot block D(k): column k now holds
807
+ //
808
+ // W(k) = U(k)*D(k)
809
+ //
810
+ // where U(k) is the k-th column of U
811
+ //
812
+ // Perform a rank-1 update of A(1:k-1,1:k-1) as
813
+ //
814
+ // A := A - U(k)*D(k)*U(k)' = A - W(k)*1/D(k)*W(k)'
815
+ //
816
+ r1 = 1/a(k,k);
817
+ for(i = 1; i <= k-1; i++)
818
+ {
819
+ i2 = k-1;
820
+ vv = -r1*a(i,k);
821
+ ap::vadd(a.getrow(i, i, i2), a.getcolumn(k, i, i2), vv);
822
+ }
823
+
824
+ //
825
+ // Store U(k) in column k
826
+ //
827
+ i2 = k-1;
828
+ ap::vmul(a.getcolumn(k, 1, i2), r1);
829
+ }
830
+ else
831
+ {
832
+
833
+ //
834
+ // 2-by-2 pivot block D(k): columns k and k-1 now hold
835
+ //
836
+ // ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k)
837
+ //
838
+ // where U(k) and U(k-1) are the k-th and (k-1)-th columns
839
+ // of U
840
+ //
841
+ // Perform a rank-2 update of A(1:k-2,1:k-2) as
842
+ //
843
+ // A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )'
844
+ // = A - ( W(k-1) W(k) )*inv(D(k))*( W(k-1) W(k) )'
845
+ //
846
+ if( k>2 )
847
+ {
848
+ d12 = a(k-1,k);
849
+ d22 = a(k-1,k-1)/d12;
850
+ d11 = a(k,k)/d12;
851
+ t = 1/(d11*d22-1);
852
+ d12 = t/d12;
853
+ for(j = k-2; j >= 1; j--)
854
+ {
855
+ wkm1 = d12*(d11*a(j,k-1)-a(j,k));
856
+ wk = d12*(d22*a(j,k)-a(j,k-1));
857
+ ap::vsub(a.getcolumn(j, 1, j), a.getcolumn(k, 1, j), wk);
858
+ i1 = k-1;
859
+ ap::vsub(a.getcolumn(j, 1, j), a.getcolumn(i1, 1, j), wkm1);
860
+ a(j,k) = wk;
861
+ a(j,k-1) = wkm1;
862
+ }
863
+ }
864
+ }
865
+ }
866
+
867
+ //
868
+ // Store details of the interchanges in IPIV
869
+ //
870
+ if( kstep==1 )
871
+ {
872
+ pivots(k) = kp;
873
+ }
874
+ else
875
+ {
876
+ pivots(k) = -kp;
877
+ pivots(k-1) = -kp;
878
+ }
879
+
880
+ //
881
+ // Decrease K and return to the start of the main loop
882
+ //
883
+ k = k-kstep;
884
+ }
885
+ }
886
+ else
887
+ {
888
+
889
+ //
890
+ // Factorize A as L*D*L' using the lower triangle of A
891
+ //
892
+ // K is the main loop index, increasing from 1 to N in steps of
893
+ // 1 or 2
894
+ //
895
+ k = 1;
896
+ while(k<=n)
897
+ {
898
+ kstep = 1;
899
+
900
+ //
901
+ // Determine rows and columns to be interchanged and whether
902
+ // a 1-by-1 or 2-by-2 pivot block will be used
903
+ //
904
+ absakk = fabs(a(k,k));
905
+
906
+ //
907
+ // IMAX is the row-index of the largest off-diagonal element in
908
+ // column K, and COLMAX is its absolute value
909
+ //
910
+ if( k<n )
911
+ {
912
+ imax = k+1;
913
+ for(ii = k+2; ii <= n; ii++)
914
+ {
915
+ if( fabs(a(ii,k))>fabs(a(imax,k)) )
916
+ {
917
+ imax = ii;
918
+ }
919
+ }
920
+ colmax = fabs(a(imax,k));
921
+ }
922
+ else
923
+ {
924
+ colmax = 0;
925
+ }
926
+ if( ap::maxreal(absakk, colmax)==0 )
927
+ {
928
+
929
+ //
930
+ // Column K is zero
931
+ //
932
+ kp = k;
933
+ }
934
+ else
935
+ {
936
+ if( absakk>=alpha*colmax )
937
+ {
938
+
939
+ //
940
+ // no interchange, use 1-by-1 pivot block
941
+ //
942
+ kp = k;
943
+ }
944
+ else
945
+ {
946
+
947
+ //
948
+ // JMAX is the column-index of the largest off-diagonal
949
+ // element in row IMAX, and ROWMAX is its absolute value
950
+ //
951
+ jmax = k;
952
+ for(ii = k+1; ii <= imax-1; ii++)
953
+ {
954
+ if( fabs(a(imax,ii))>fabs(a(imax,jmax)) )
955
+ {
956
+ jmax = ii;
957
+ }
958
+ }
959
+ rowmax = fabs(a(imax,jmax));
960
+ if( imax<n )
961
+ {
962
+ jmax = imax+1;
963
+ for(ii = imax+2; ii <= n; ii++)
964
+ {
965
+ if( fabs(a(ii,imax))>fabs(a(jmax,imax)) )
966
+ {
967
+ jmax = ii;
968
+ }
969
+ }
970
+ rowmax = ap::maxreal(rowmax, fabs(a(jmax,imax)));
971
+ }
972
+ vv = colmax/rowmax;
973
+ if( absakk>=alpha*colmax*vv )
974
+ {
975
+
976
+ //
977
+ // no interchange, use 1-by-1 pivot block
978
+ //
979
+ kp = k;
980
+ }
981
+ else
982
+ {
983
+ if( fabs(a(imax,imax))>=alpha*rowmax )
984
+ {
985
+
986
+ //
987
+ // interchange rows and columns K and IMAX, use 1-by-1
988
+ // pivot block
989
+ //
990
+ kp = imax;
991
+ }
992
+ else
993
+ {
994
+
995
+ //
996
+ // interchange rows and columns K+1 and IMAX, use 2-by-2
997
+ // pivot block
998
+ //
999
+ kp = imax;
1000
+ kstep = 2;
1001
+ }
1002
+ }
1003
+ }
1004
+ kk = k+kstep-1;
1005
+ if( kp!=kk )
1006
+ {
1007
+
1008
+ //
1009
+ // Interchange rows and columns KK and KP in the trailing
1010
+ // submatrix A(k:n,k:n)
1011
+ //
1012
+ if( kp<n )
1013
+ {
1014
+ i1 = kp+1;
1015
+ ap::vmove(temp.getvector(i1, n), a.getcolumn(kk, i1, n));
1016
+ ap::vmove(a.getcolumn(kk, i1, n), a.getcolumn(kp, i1, n));
1017
+ ap::vmove(a.getcolumn(kp, i1, n), temp.getvector(i1, n));
1018
+ }
1019
+ i1 = kk+1;
1020
+ i2 = kp-1;
1021
+ ap::vmove(temp.getvector(i1, i2), a.getcolumn(kk, i1, i2));
1022
+ ap::vmove(a.getcolumn(kk, i1, i2), a.getrow(kp, i1, i2));
1023
+ ap::vmove(&a(kp, i1), &temp(i1), ap::vlen(i1,i2));
1024
+ t = a(kk,kk);
1025
+ a(kk,kk) = a(kp,kp);
1026
+ a(kp,kp) = t;
1027
+ if( kstep==2 )
1028
+ {
1029
+ t = a(k+1,k);
1030
+ a(k+1,k) = a(kp,k);
1031
+ a(kp,k) = t;
1032
+ }
1033
+ }
1034
+
1035
+ //
1036
+ // Update the trailing submatrix
1037
+ //
1038
+ if( kstep==1 )
1039
+ {
1040
+
1041
+ //
1042
+ // 1-by-1 pivot block D(k): column k now holds
1043
+ //
1044
+ // W(k) = L(k)*D(k)
1045
+ //
1046
+ // where L(k) is the k-th column of L
1047
+ //
1048
+ if( k<n )
1049
+ {
1050
+
1051
+ //
1052
+ // Perform a rank-1 update of A(k+1:n,k+1:n) as
1053
+ //
1054
+ // A := A - L(k)*D(k)*L(k)' = A - W(k)*(1/D(k))*W(k)'
1055
+ //
1056
+ d11 = 1/a(k,k);
1057
+ for(ii = k+1; ii <= n; ii++)
1058
+ {
1059
+ i1 = k+1;
1060
+ i2 = ii;
1061
+ vv = -d11*a(ii,k);
1062
+ ap::vadd(a.getrow(ii, i1, i2), a.getcolumn(k, i1, i2), vv);
1063
+ }
1064
+
1065
+ //
1066
+ // Store L(k) in column K
1067
+ //
1068
+ i1 = k+1;
1069
+ ap::vmul(a.getcolumn(k, i1, n), d11);
1070
+ }
1071
+ }
1072
+ else
1073
+ {
1074
+
1075
+ //
1076
+ // 2-by-2 pivot block D(k)
1077
+ //
1078
+ if( k<n-1 )
1079
+ {
1080
+
1081
+ //
1082
+ // Perform a rank-2 update of A(k+2:n,k+2:n) as
1083
+ //
1084
+ // A := A - ( (A(k) A(k+1))*D(k)**(-1) ) * (A(k) A(k+1))'
1085
+ //
1086
+ // where L(k) and L(k+1) are the k-th and (k+1)-th
1087
+ // columns of L
1088
+ //
1089
+ d21 = a(k+1,k);
1090
+ d11 = a(k+1,k+1)/d21;
1091
+ d22 = a(k,k)/d21;
1092
+ t = 1/(d11*d22-1);
1093
+ d21 = t/d21;
1094
+ for(j = k+2; j <= n; j++)
1095
+ {
1096
+ wk = d21*(d11*a(j,k)-a(j,k+1));
1097
+ wkp1 = d21*(d22*a(j,k+1)-a(j,k));
1098
+ ii = k+1;
1099
+ ap::vsub(a.getcolumn(j, j, n), a.getcolumn(k, j, n), wk);
1100
+ ap::vsub(a.getcolumn(j, j, n), a.getcolumn(ii, j, n), wkp1);
1101
+ a(j,k) = wk;
1102
+ a(j,k+1) = wkp1;
1103
+ }
1104
+ }
1105
+ }
1106
+ }
1107
+
1108
+ //
1109
+ // Store details of the interchanges in IPIV
1110
+ //
1111
+ if( kstep==1 )
1112
+ {
1113
+ pivots(k) = kp;
1114
+ }
1115
+ else
1116
+ {
1117
+ pivots(k) = -kp;
1118
+ pivots(k+1) = -kp;
1119
+ }
1120
+
1121
+ //
1122
+ // Increase K and return to the start of the main loop
1123
+ //
1124
+ k = k+kstep;
1125
+ }
1126
+ }
1127
+ }
1128
+
1129
+
1130
+