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,98 @@
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 _trinverse_h
40
+ #define _trinverse_h
41
+
42
+ #include "ap.h"
43
+ #include "ialglib.h"
44
+
45
+ /*************************************************************************
46
+ Triangular matrix inversion
47
+
48
+ The subroutine inverts the following types of matrices:
49
+ * upper triangular
50
+ * upper triangular with unit diagonal
51
+ * lower triangular
52
+ * lower triangular with unit diagonal
53
+
54
+ In case of an upper (lower) triangular matrix, the inverse matrix will
55
+ also be upper (lower) triangular, and after the end of the algorithm, the
56
+ inverse matrix replaces the source matrix. The elements below (above) the
57
+ main diagonal are not changed by the algorithm.
58
+
59
+ If the matrix has a unit diagonal, the inverse matrix also has a unit
60
+ diagonal, and the diagonal elements are not passed to the algorithm.
61
+
62
+ Input parameters:
63
+ A - matrix.
64
+ Array whose indexes range within [0..N-1, 0..N-1].
65
+ N - size of matrix A.
66
+ IsUpper - True, if the matrix is upper triangular.
67
+ IsUnitTriangular
68
+ - True, if the matrix has a unit diagonal.
69
+
70
+ Output parameters:
71
+ A - inverse matrix (if the problem is not degenerate).
72
+
73
+ Result:
74
+ True, if the matrix is not singular.
75
+ False, if the matrix is singular.
76
+
77
+ -- LAPACK routine (version 3.0) --
78
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
79
+ Courant Institute, Argonne National Lab, and Rice University
80
+ February 29, 1992
81
+ *************************************************************************/
82
+ bool rmatrixtrinverse(ap::real_2d_array& a,
83
+ int n,
84
+ bool isupper,
85
+ bool isunittriangular);
86
+
87
+
88
+ /*************************************************************************
89
+ Obsolete 1-based subroutine.
90
+ See RMatrixTRInverse for 0-based replacement.
91
+ *************************************************************************/
92
+ bool invtriangular(ap::real_2d_array& a,
93
+ int n,
94
+ bool isupper,
95
+ bool isunittriangular);
96
+
97
+
98
+ #endif
@@ -0,0 +1,926 @@
1
+
2
+ #include <stdafx.h>
3
+ #include "trlinsolve.h"
4
+
5
+ /*************************************************************************
6
+ Utility subroutine performing the "safe" solution of system of linear
7
+ equations with triangular coefficient matrices.
8
+
9
+ The subroutine uses scaling and solves the scaled system A*x=s*b (where s
10
+ is a scalar value) instead of A*x=b, choosing s so that x can be
11
+ represented by a floating-point number. The closer the system gets to a
12
+ singular, the less s is. If the system is singular, s=0 and x contains the
13
+ non-trivial solution of equation A*x=0.
14
+
15
+ The feature of an algorithm is that it could not cause an overflow or a
16
+ division by zero regardless of the matrix used as the input.
17
+
18
+ The algorithm can solve systems of equations with upper/lower triangular
19
+ matrices, with/without unit diagonal, and systems of type A*x=b or A'*x=b
20
+ (where A' is a transposed matrix A).
21
+
22
+ Input parameters:
23
+ A - system matrix. Array whose indexes range within [0..N-1, 0..N-1].
24
+ N - size of matrix A.
25
+ X - right-hand member of a system.
26
+ Array whose index ranges within [0..N-1].
27
+ IsUpper - matrix type. If it is True, the system matrix is the upper
28
+ triangular and is located in the corresponding part of
29
+ matrix A.
30
+ Trans - problem type. If it is True, the problem to be solved is
31
+ A'*x=b, otherwise it is A*x=b.
32
+ IsUnit - matrix type. If it is True, the system matrix has a unit
33
+ diagonal (the elements on the main diagonal are not used
34
+ in the calculation process), otherwise the matrix is considered
35
+ to be a general triangular matrix.
36
+
37
+ Output parameters:
38
+ X - solution. Array whose index ranges within [0..N-1].
39
+ S - scaling factor.
40
+
41
+ -- LAPACK auxiliary routine (version 3.0) --
42
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
43
+ Courant Institute, Argonne National Lab, and Rice University
44
+ June 30, 1992
45
+ *************************************************************************/
46
+ void rmatrixtrsafesolve(const ap::real_2d_array& a,
47
+ int n,
48
+ ap::real_1d_array& x,
49
+ double& s,
50
+ bool isupper,
51
+ bool istrans,
52
+ bool isunit)
53
+ {
54
+ bool normin;
55
+ ap::real_1d_array cnorm;
56
+ ap::real_2d_array a1;
57
+ ap::real_1d_array x1;
58
+ int i;
59
+
60
+
61
+ //
62
+ // From 0-based to 1-based
63
+ //
64
+ normin = false;
65
+ a1.setbounds(1, n, 1, n);
66
+ x1.setbounds(1, n);
67
+ for(i = 1; i <= n; i++)
68
+ {
69
+ ap::vmove(&a1(i, 1), &a(i-1, 0), ap::vlen(1,n));
70
+ }
71
+ ap::vmove(&x1(1), &x(0), ap::vlen(1,n));
72
+
73
+ //
74
+ // Solve 1-based
75
+ //
76
+ safesolvetriangular(a1, n, x1, s, isupper, istrans, isunit, normin, cnorm);
77
+
78
+ //
79
+ // From 1-based to 0-based
80
+ //
81
+ ap::vmove(&x(0), &x1(1), ap::vlen(0,n-1));
82
+ }
83
+
84
+
85
+ /*************************************************************************
86
+ Obsolete 1-based subroutine.
87
+ See RMatrixTRSafeSolve for 0-based replacement.
88
+ *************************************************************************/
89
+ void safesolvetriangular(const ap::real_2d_array& a,
90
+ int n,
91
+ ap::real_1d_array& x,
92
+ double& s,
93
+ bool isupper,
94
+ bool istrans,
95
+ bool isunit,
96
+ bool normin,
97
+ ap::real_1d_array& cnorm)
98
+ {
99
+ int i;
100
+ int imax;
101
+ int j;
102
+ int jfirst;
103
+ int jinc;
104
+ int jlast;
105
+ int jm1;
106
+ int jp1;
107
+ int ip1;
108
+ int im1;
109
+ int k;
110
+ int flg;
111
+ double v;
112
+ double vd;
113
+ double bignum;
114
+ double grow;
115
+ double rec;
116
+ double smlnum;
117
+ double sumj;
118
+ double tjj;
119
+ double tjjs;
120
+ double tmax;
121
+ double tscal;
122
+ double uscal;
123
+ double xbnd;
124
+ double xj;
125
+ double xmax;
126
+ bool notran;
127
+ bool upper;
128
+ bool nounit;
129
+
130
+ upper = isupper;
131
+ notran = !istrans;
132
+ nounit = !isunit;
133
+
134
+ //
135
+ // Quick return if possible
136
+ //
137
+ if( n==0 )
138
+ {
139
+ return;
140
+ }
141
+
142
+ //
143
+ // Determine machine dependent parameters to control overflow.
144
+ //
145
+ smlnum = ap::minrealnumber/(ap::machineepsilon*2);
146
+ bignum = 1/smlnum;
147
+ s = 1;
148
+ if( !normin )
149
+ {
150
+ cnorm.setbounds(1, n);
151
+
152
+ //
153
+ // Compute the 1-norm of each column, not including the diagonal.
154
+ //
155
+ if( upper )
156
+ {
157
+
158
+ //
159
+ // A is upper triangular.
160
+ //
161
+ for(j = 1; j <= n; j++)
162
+ {
163
+ v = 0;
164
+ for(k = 1; k <= j-1; k++)
165
+ {
166
+ v = v+fabs(a(k,j));
167
+ }
168
+ cnorm(j) = v;
169
+ }
170
+ }
171
+ else
172
+ {
173
+
174
+ //
175
+ // A is lower triangular.
176
+ //
177
+ for(j = 1; j <= n-1; j++)
178
+ {
179
+ v = 0;
180
+ for(k = j+1; k <= n; k++)
181
+ {
182
+ v = v+fabs(a(k,j));
183
+ }
184
+ cnorm(j) = v;
185
+ }
186
+ cnorm(n) = 0;
187
+ }
188
+ }
189
+
190
+ //
191
+ // Scale the column norms by TSCAL if the maximum element in CNORM is
192
+ // greater than BIGNUM.
193
+ //
194
+ imax = 1;
195
+ for(k = 2; k <= n; k++)
196
+ {
197
+ if( cnorm(k)>cnorm(imax) )
198
+ {
199
+ imax = k;
200
+ }
201
+ }
202
+ tmax = cnorm(imax);
203
+ if( tmax<=bignum )
204
+ {
205
+ tscal = 1;
206
+ }
207
+ else
208
+ {
209
+ tscal = 1/(smlnum*tmax);
210
+ ap::vmul(&cnorm(1), ap::vlen(1,n), tscal);
211
+ }
212
+
213
+ //
214
+ // Compute a bound on the computed solution vector to see if the
215
+ // Level 2 BLAS routine DTRSV can be used.
216
+ //
217
+ j = 1;
218
+ for(k = 2; k <= n; k++)
219
+ {
220
+ if( fabs(x(k))>fabs(x(j)) )
221
+ {
222
+ j = k;
223
+ }
224
+ }
225
+ xmax = fabs(x(j));
226
+ xbnd = xmax;
227
+ if( notran )
228
+ {
229
+
230
+ //
231
+ // Compute the growth in A * x = b.
232
+ //
233
+ if( upper )
234
+ {
235
+ jfirst = n;
236
+ jlast = 1;
237
+ jinc = -1;
238
+ }
239
+ else
240
+ {
241
+ jfirst = 1;
242
+ jlast = n;
243
+ jinc = 1;
244
+ }
245
+ if( tscal!=1 )
246
+ {
247
+ grow = 0;
248
+ }
249
+ else
250
+ {
251
+ if( nounit )
252
+ {
253
+
254
+ //
255
+ // A is non-unit triangular.
256
+ //
257
+ // Compute GROW = 1/G(j) and XBND = 1/M(j).
258
+ // Initially, G(0) = max{x(i), i=1,...,n}.
259
+ //
260
+ grow = 1/ap::maxreal(xbnd, smlnum);
261
+ xbnd = grow;
262
+ j = jfirst;
263
+ while(jinc>0&&j<=jlast||jinc<0&&j>=jlast)
264
+ {
265
+
266
+ //
267
+ // Exit the loop if the growth factor is too small.
268
+ //
269
+ if( grow<=smlnum )
270
+ {
271
+ break;
272
+ }
273
+
274
+ //
275
+ // M(j) = G(j-1) / abs(A(j,j))
276
+ //
277
+ tjj = fabs(a(j,j));
278
+ xbnd = ap::minreal(xbnd, ap::minreal(double(1), tjj)*grow);
279
+ if( tjj+cnorm(j)>=smlnum )
280
+ {
281
+
282
+ //
283
+ // G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
284
+ //
285
+ grow = grow*(tjj/(tjj+cnorm(j)));
286
+ }
287
+ else
288
+ {
289
+
290
+ //
291
+ // G(j) could overflow, set GROW to 0.
292
+ //
293
+ grow = 0;
294
+ }
295
+ if( j==jlast )
296
+ {
297
+ grow = xbnd;
298
+ }
299
+ j = j+jinc;
300
+ }
301
+ }
302
+ else
303
+ {
304
+
305
+ //
306
+ // A is unit triangular.
307
+ //
308
+ // Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
309
+ //
310
+ grow = ap::minreal(double(1), 1/ap::maxreal(xbnd, smlnum));
311
+ j = jfirst;
312
+ while(jinc>0&&j<=jlast||jinc<0&&j>=jlast)
313
+ {
314
+
315
+ //
316
+ // Exit the loop if the growth factor is too small.
317
+ //
318
+ if( grow<=smlnum )
319
+ {
320
+ break;
321
+ }
322
+
323
+ //
324
+ // G(j) = G(j-1)*( 1 + CNORM(j) )
325
+ //
326
+ grow = grow*(1/(1+cnorm(j)));
327
+ j = j+jinc;
328
+ }
329
+ }
330
+ }
331
+ }
332
+ else
333
+ {
334
+
335
+ //
336
+ // Compute the growth in A' * x = b.
337
+ //
338
+ if( upper )
339
+ {
340
+ jfirst = 1;
341
+ jlast = n;
342
+ jinc = 1;
343
+ }
344
+ else
345
+ {
346
+ jfirst = n;
347
+ jlast = 1;
348
+ jinc = -1;
349
+ }
350
+ if( tscal!=1 )
351
+ {
352
+ grow = 0;
353
+ }
354
+ else
355
+ {
356
+ if( nounit )
357
+ {
358
+
359
+ //
360
+ // A is non-unit triangular.
361
+ //
362
+ // Compute GROW = 1/G(j) and XBND = 1/M(j).
363
+ // Initially, M(0) = max{x(i), i=1,...,n}.
364
+ //
365
+ grow = 1/ap::maxreal(xbnd, smlnum);
366
+ xbnd = grow;
367
+ j = jfirst;
368
+ while(jinc>0&&j<=jlast||jinc<0&&j>=jlast)
369
+ {
370
+
371
+ //
372
+ // Exit the loop if the growth factor is too small.
373
+ //
374
+ if( grow<=smlnum )
375
+ {
376
+ break;
377
+ }
378
+
379
+ //
380
+ // G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
381
+ //
382
+ xj = 1+cnorm(j);
383
+ grow = ap::minreal(grow, xbnd/xj);
384
+
385
+ //
386
+ // M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
387
+ //
388
+ tjj = fabs(a(j,j));
389
+ if( xj>tjj )
390
+ {
391
+ xbnd = xbnd*(tjj/xj);
392
+ }
393
+ if( j==jlast )
394
+ {
395
+ grow = ap::minreal(grow, xbnd);
396
+ }
397
+ j = j+jinc;
398
+ }
399
+ }
400
+ else
401
+ {
402
+
403
+ //
404
+ // A is unit triangular.
405
+ //
406
+ // Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
407
+ //
408
+ grow = ap::minreal(double(1), 1/ap::maxreal(xbnd, smlnum));
409
+ j = jfirst;
410
+ while(jinc>0&&j<=jlast||jinc<0&&j>=jlast)
411
+ {
412
+
413
+ //
414
+ // Exit the loop if the growth factor is too small.
415
+ //
416
+ if( grow<=smlnum )
417
+ {
418
+ break;
419
+ }
420
+
421
+ //
422
+ // G(j) = ( 1 + CNORM(j) )*G(j-1)
423
+ //
424
+ xj = 1+cnorm(j);
425
+ grow = grow/xj;
426
+ j = j+jinc;
427
+ }
428
+ }
429
+ }
430
+ }
431
+ if( grow*tscal>smlnum )
432
+ {
433
+
434
+ //
435
+ // Use the Level 2 BLAS solve if the reciprocal of the bound on
436
+ // elements of X is not too small.
437
+ //
438
+ if( upper&&notran||!upper&&!notran )
439
+ {
440
+ if( nounit )
441
+ {
442
+ vd = a(n,n);
443
+ }
444
+ else
445
+ {
446
+ vd = 1;
447
+ }
448
+ x(n) = x(n)/vd;
449
+ for(i = n-1; i >= 1; i--)
450
+ {
451
+ ip1 = i+1;
452
+ if( upper )
453
+ {
454
+ v = ap::vdotproduct(&a(i, ip1), &x(ip1), ap::vlen(ip1,n));
455
+ }
456
+ else
457
+ {
458
+ v = ap::vdotproduct(a.getcolumn(i, ip1, n), x.getvector(ip1, n));
459
+ }
460
+ if( nounit )
461
+ {
462
+ vd = a(i,i);
463
+ }
464
+ else
465
+ {
466
+ vd = 1;
467
+ }
468
+ x(i) = (x(i)-v)/vd;
469
+ }
470
+ }
471
+ else
472
+ {
473
+ if( nounit )
474
+ {
475
+ vd = a(1,1);
476
+ }
477
+ else
478
+ {
479
+ vd = 1;
480
+ }
481
+ x(1) = x(1)/vd;
482
+ for(i = 2; i <= n; i++)
483
+ {
484
+ im1 = i-1;
485
+ if( upper )
486
+ {
487
+ v = ap::vdotproduct(a.getcolumn(i, 1, im1), x.getvector(1, im1));
488
+ }
489
+ else
490
+ {
491
+ v = ap::vdotproduct(&a(i, 1), &x(1), ap::vlen(1,im1));
492
+ }
493
+ if( nounit )
494
+ {
495
+ vd = a(i,i);
496
+ }
497
+ else
498
+ {
499
+ vd = 1;
500
+ }
501
+ x(i) = (x(i)-v)/vd;
502
+ }
503
+ }
504
+ }
505
+ else
506
+ {
507
+
508
+ //
509
+ // Use a Level 1 BLAS solve, scaling intermediate results.
510
+ //
511
+ if( xmax>bignum )
512
+ {
513
+
514
+ //
515
+ // Scale X so that its components are less than or equal to
516
+ // BIGNUM in absolute value.
517
+ //
518
+ s = bignum/xmax;
519
+ ap::vmul(&x(1), ap::vlen(1,n), s);
520
+ xmax = bignum;
521
+ }
522
+ if( notran )
523
+ {
524
+
525
+ //
526
+ // Solve A * x = b
527
+ //
528
+ j = jfirst;
529
+ while(jinc>0&&j<=jlast||jinc<0&&j>=jlast)
530
+ {
531
+
532
+ //
533
+ // Compute x(j) = b(j) / A(j,j), scaling x if necessary.
534
+ //
535
+ xj = fabs(x(j));
536
+ flg = 0;
537
+ if( nounit )
538
+ {
539
+ tjjs = a(j,j)*tscal;
540
+ }
541
+ else
542
+ {
543
+ tjjs = tscal;
544
+ if( tscal==1 )
545
+ {
546
+ flg = 100;
547
+ }
548
+ }
549
+ if( flg!=100 )
550
+ {
551
+ tjj = fabs(tjjs);
552
+ if( tjj>smlnum )
553
+ {
554
+
555
+ //
556
+ // abs(A(j,j)) > SMLNUM:
557
+ //
558
+ if( tjj<1 )
559
+ {
560
+ if( xj>tjj*bignum )
561
+ {
562
+
563
+ //
564
+ // Scale x by 1/b(j).
565
+ //
566
+ rec = 1/xj;
567
+ ap::vmul(&x(1), ap::vlen(1,n), rec);
568
+ s = s*rec;
569
+ xmax = xmax*rec;
570
+ }
571
+ }
572
+ x(j) = x(j)/tjjs;
573
+ xj = fabs(x(j));
574
+ }
575
+ else
576
+ {
577
+ if( tjj>0 )
578
+ {
579
+
580
+ //
581
+ // 0 < abs(A(j,j)) <= SMLNUM:
582
+ //
583
+ if( xj>tjj*bignum )
584
+ {
585
+
586
+ //
587
+ // Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
588
+ // to avoid overflow when dividing by A(j,j).
589
+ //
590
+ rec = tjj*bignum/xj;
591
+ if( cnorm(j)>1 )
592
+ {
593
+
594
+ //
595
+ // Scale by 1/CNORM(j) to avoid overflow when
596
+ // multiplying x(j) times column j.
597
+ //
598
+ rec = rec/cnorm(j);
599
+ }
600
+ ap::vmul(&x(1), ap::vlen(1,n), rec);
601
+ s = s*rec;
602
+ xmax = xmax*rec;
603
+ }
604
+ x(j) = x(j)/tjjs;
605
+ xj = fabs(x(j));
606
+ }
607
+ else
608
+ {
609
+
610
+ //
611
+ // A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and
612
+ // scale = 0, and compute a solution to A*x = 0.
613
+ //
614
+ for(i = 1; i <= n; i++)
615
+ {
616
+ x(i) = 0;
617
+ }
618
+ x(j) = 1;
619
+ xj = 1;
620
+ s = 0;
621
+ xmax = 0;
622
+ }
623
+ }
624
+ }
625
+
626
+ //
627
+ // Scale x if necessary to avoid overflow when adding a
628
+ // multiple of column j of A.
629
+ //
630
+ if( xj>1 )
631
+ {
632
+ rec = 1/xj;
633
+ if( cnorm(j)>(bignum-xmax)*rec )
634
+ {
635
+
636
+ //
637
+ // Scale x by 1/(2*abs(x(j))).
638
+ //
639
+ rec = rec*0.5;
640
+ ap::vmul(&x(1), ap::vlen(1,n), rec);
641
+ s = s*rec;
642
+ }
643
+ }
644
+ else
645
+ {
646
+ if( xj*cnorm(j)>bignum-xmax )
647
+ {
648
+
649
+ //
650
+ // Scale x by 1/2.
651
+ //
652
+ ap::vmul(&x(1), ap::vlen(1,n), 0.5);
653
+ s = s*0.5;
654
+ }
655
+ }
656
+ if( upper )
657
+ {
658
+ if( j>1 )
659
+ {
660
+
661
+ //
662
+ // Compute the update
663
+ // x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)
664
+ //
665
+ v = x(j)*tscal;
666
+ jm1 = j-1;
667
+ ap::vsub(x.getvector(1, jm1), a.getcolumn(j, 1, jm1), v);
668
+ i = 1;
669
+ for(k = 2; k <= j-1; k++)
670
+ {
671
+ if( fabs(x(k))>fabs(x(i)) )
672
+ {
673
+ i = k;
674
+ }
675
+ }
676
+ xmax = fabs(x(i));
677
+ }
678
+ }
679
+ else
680
+ {
681
+ if( j<n )
682
+ {
683
+
684
+ //
685
+ // Compute the update
686
+ // x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)
687
+ //
688
+ jp1 = j+1;
689
+ v = x(j)*tscal;
690
+ ap::vsub(x.getvector(jp1, n), a.getcolumn(j, jp1, n), v);
691
+ i = j+1;
692
+ for(k = j+2; k <= n; k++)
693
+ {
694
+ if( fabs(x(k))>fabs(x(i)) )
695
+ {
696
+ i = k;
697
+ }
698
+ }
699
+ xmax = fabs(x(i));
700
+ }
701
+ }
702
+ j = j+jinc;
703
+ }
704
+ }
705
+ else
706
+ {
707
+
708
+ //
709
+ // Solve A' * x = b
710
+ //
711
+ j = jfirst;
712
+ while(jinc>0&&j<=jlast||jinc<0&&j>=jlast)
713
+ {
714
+
715
+ //
716
+ // Compute x(j) = b(j) - sum A(k,j)*x(k).
717
+ // k<>j
718
+ //
719
+ xj = fabs(x(j));
720
+ uscal = tscal;
721
+ rec = 1/ap::maxreal(xmax, double(1));
722
+ if( cnorm(j)>(bignum-xj)*rec )
723
+ {
724
+
725
+ //
726
+ // If x(j) could overflow, scale x by 1/(2*XMAX).
727
+ //
728
+ rec = rec*0.5;
729
+ if( nounit )
730
+ {
731
+ tjjs = a(j,j)*tscal;
732
+ }
733
+ else
734
+ {
735
+ tjjs = tscal;
736
+ }
737
+ tjj = fabs(tjjs);
738
+ if( tjj>1 )
739
+ {
740
+
741
+ //
742
+ // Divide by A(j,j) when scaling x if A(j,j) > 1.
743
+ //
744
+ rec = ap::minreal(double(1), rec*tjj);
745
+ uscal = uscal/tjjs;
746
+ }
747
+ if( rec<1 )
748
+ {
749
+ ap::vmul(&x(1), ap::vlen(1,n), rec);
750
+ s = s*rec;
751
+ xmax = xmax*rec;
752
+ }
753
+ }
754
+ sumj = 0;
755
+ if( uscal==1 )
756
+ {
757
+
758
+ //
759
+ // If the scaling needed for A in the dot product is 1,
760
+ // call DDOT to perform the dot product.
761
+ //
762
+ if( upper )
763
+ {
764
+ if( j>1 )
765
+ {
766
+ jm1 = j-1;
767
+ sumj = ap::vdotproduct(a.getcolumn(j, 1, jm1), x.getvector(1, jm1));
768
+ }
769
+ else
770
+ {
771
+ sumj = 0;
772
+ }
773
+ }
774
+ else
775
+ {
776
+ if( j<n )
777
+ {
778
+ jp1 = j+1;
779
+ sumj = ap::vdotproduct(a.getcolumn(j, jp1, n), x.getvector(jp1, n));
780
+ }
781
+ }
782
+ }
783
+ else
784
+ {
785
+
786
+ //
787
+ // Otherwise, use in-line code for the dot product.
788
+ //
789
+ if( upper )
790
+ {
791
+ for(i = 1; i <= j-1; i++)
792
+ {
793
+ v = a(i,j)*uscal;
794
+ sumj = sumj+v*x(i);
795
+ }
796
+ }
797
+ else
798
+ {
799
+ if( j<n )
800
+ {
801
+ for(i = j+1; i <= n; i++)
802
+ {
803
+ v = a(i,j)*uscal;
804
+ sumj = sumj+v*x(i);
805
+ }
806
+ }
807
+ }
808
+ }
809
+ if( uscal==tscal )
810
+ {
811
+
812
+ //
813
+ // Compute x(j) := ( x(j) - sumj ) / A(j,j) if 1/A(j,j)
814
+ // was not used to scale the dotproduct.
815
+ //
816
+ x(j) = x(j)-sumj;
817
+ xj = fabs(x(j));
818
+ flg = 0;
819
+ if( nounit )
820
+ {
821
+ tjjs = a(j,j)*tscal;
822
+ }
823
+ else
824
+ {
825
+ tjjs = tscal;
826
+ if( tscal==1 )
827
+ {
828
+ flg = 150;
829
+ }
830
+ }
831
+
832
+ //
833
+ // Compute x(j) = x(j) / A(j,j), scaling if necessary.
834
+ //
835
+ if( flg!=150 )
836
+ {
837
+ tjj = fabs(tjjs);
838
+ if( tjj>smlnum )
839
+ {
840
+
841
+ //
842
+ // abs(A(j,j)) > SMLNUM:
843
+ //
844
+ if( tjj<1 )
845
+ {
846
+ if( xj>tjj*bignum )
847
+ {
848
+
849
+ //
850
+ // Scale X by 1/abs(x(j)).
851
+ //
852
+ rec = 1/xj;
853
+ ap::vmul(&x(1), ap::vlen(1,n), rec);
854
+ s = s*rec;
855
+ xmax = xmax*rec;
856
+ }
857
+ }
858
+ x(j) = x(j)/tjjs;
859
+ }
860
+ else
861
+ {
862
+ if( tjj>0 )
863
+ {
864
+
865
+ //
866
+ // 0 < abs(A(j,j)) <= SMLNUM:
867
+ //
868
+ if( xj>tjj*bignum )
869
+ {
870
+
871
+ //
872
+ // Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
873
+ //
874
+ rec = tjj*bignum/xj;
875
+ ap::vmul(&x(1), ap::vlen(1,n), rec);
876
+ s = s*rec;
877
+ xmax = xmax*rec;
878
+ }
879
+ x(j) = x(j)/tjjs;
880
+ }
881
+ else
882
+ {
883
+
884
+ //
885
+ // A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and
886
+ // scale = 0, and compute a solution to A'*x = 0.
887
+ //
888
+ for(i = 1; i <= n; i++)
889
+ {
890
+ x(i) = 0;
891
+ }
892
+ x(j) = 1;
893
+ s = 0;
894
+ xmax = 0;
895
+ }
896
+ }
897
+ }
898
+ }
899
+ else
900
+ {
901
+
902
+ //
903
+ // Compute x(j) := x(j) / A(j,j) - sumj if the dot
904
+ // product has already been divided by 1/A(j,j).
905
+ //
906
+ x(j) = x(j)/tjjs-sumj;
907
+ }
908
+ xmax = ap::maxreal(xmax, fabs(x(j)));
909
+ j = j+jinc;
910
+ }
911
+ }
912
+ s = s/tscal;
913
+ }
914
+
915
+ //
916
+ // Scale the column norms by 1/TSCAL for return.
917
+ //
918
+ if( tscal!=1 )
919
+ {
920
+ v = 1/tscal;
921
+ ap::vmul(&cnorm(1), ap::vlen(1,n), v);
922
+ }
923
+ }
924
+
925
+
926
+