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,124 @@
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 _ldlt_h
40
+ #define _ldlt_h
41
+
42
+ #include "ap.h"
43
+ #include "ialglib.h"
44
+
45
+ /*************************************************************************
46
+ LDLTDecomposition of a symmetric matrix
47
+
48
+ The algorithm represents a symmetric matrix (which is not necessarily
49
+ positive definite) as A=L*D*L' or A = U*D*U', where D is a block-diagonal
50
+ matrix with blocks 1x1 or 2x2, matrix L (matrix U) is a product of lower
51
+ (upper) triangular matrices with unit diagonal and permutation matrices.
52
+
53
+ Input parameters:
54
+ A - factorized matrix, array with elements [0..N-1, 0..N-1].
55
+ If IsUpper � True, then the upper triangle contains
56
+ elements of symmetric matrix A, and the lower triangle is
57
+ not used.
58
+ The same applies if IsUpper = False.
59
+ N - size of factorized matrix.
60
+ IsUpper - parameter which shows a method of matrix definition (lower
61
+ or upper triangle).
62
+
63
+ Output parameters:
64
+ A - matrices D and U, if IsUpper = True, or L, if IsUpper = False,
65
+ in compact form, replacing the upper (lower) triangle of
66
+ matrix A. In that case, the elements under (over) the main
67
+ diagonal are not used nor modified.
68
+ Pivots - tables of performed permutations (see below).
69
+
70
+ If IsUpper = True, then A = U*D*U', U = P(n)*U(n)*...*P(k)*U(k), where
71
+ P(k) is the permutation matrix, U(k) - upper triangular matrix with its
72
+ unit main diagonal and k decreases from n with step s which is equal to
73
+ 1 or 2 (according to the size of the blocks of matrix D).
74
+
75
+ ( I v 0 ) k-s+1
76
+ U(k) = ( 0 I 0 ) s
77
+ ( 0 0 I ) n-k-1
78
+ k-s+1 s n-k-1
79
+
80
+ If Pivots[k]>=0, then s=1, P(k) - permutation of rows k and Pivots[k], the
81
+ vectorv forming matrix U(k) is stored in elements A(0:k-1,k), D(k) replaces
82
+ A(k,k). If Pivots[k]=Pivots[k-1]<0 then s=2, P(k) - permutation of rows k-1
83
+ and N+Pivots[k-1], the vector v forming matrix U(k) is stored in elements
84
+ A(0:k-1,k:k+1), the upper triangle of block D(k) is stored in A(k,k),
85
+ A(k,k+1) and A(k+1,k+1).
86
+
87
+ If IsUpper = False, then A = L*D*L', L=P(0)*L(0)*...*P(k)*L(k), where P(k)
88
+ is the permutation matrix, L(k) � lower triangular matrix with unit main
89
+ diagonal and k decreases from 1 with step s which is equal to 1 or 2
90
+ (according to the size of the blocks of matrix D).
91
+
92
+ ( I 0 0 ) k-1
93
+ L(k) = ( 0 I 0 ) s
94
+ ( 0 v I ) n-k-s+1
95
+ k-1 s n-k-s+1
96
+
97
+ If Pivots[k]>=0 then s=1, P(k) � permutation of rows k and Pivots[k], the
98
+ vector v forming matrix L(k) is stored in elements A(k+1:n-1,k), D(k)
99
+ replaces A(k,k). If Pivots[k]=Pivots[k+1]<0 then s=2, P(k) - permutation
100
+ of rows k+1 and N+Pivots[k+1], the vector v forming matrix L(k) is stored
101
+ in elements A(k+2:n-1,k:k+1), the lower triangle of block D(k) is stored in
102
+ A(k,k), A(k+1,k) and A(k+1,k+1).
103
+
104
+ -- LAPACK routine (version 3.0) --
105
+ Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
106
+ Courant Institute, Argonne National Lab, and Rice University
107
+ June 30, 1999
108
+ *************************************************************************/
109
+ void smatrixldlt(ap::real_2d_array& a,
110
+ int n,
111
+ bool isupper,
112
+ ap::integer_1d_array& pivots);
113
+
114
+
115
+ /*************************************************************************
116
+ Obsolete subroutine.
117
+ *************************************************************************/
118
+ void ldltdecomposition(ap::real_2d_array& a,
119
+ int n,
120
+ bool isupper,
121
+ ap::integer_1d_array& pivots);
122
+
123
+
124
+ #endif
@@ -0,0 +1,1252 @@
1
+ /*************************************************************************
2
+ Copyright (c) 2006-2007, Sergey Bochkanov (ALGLIB project).
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ - Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ - Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer listed
13
+ in this license in the documentation and/or other materials
14
+ provided with the distribution.
15
+
16
+ - Neither the name of the copyright holders nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *************************************************************************/
32
+
33
+ #include <stdafx.h>
34
+ #include "leastsquares.h"
35
+
36
+ /*************************************************************************
37
+ Weighted approximation by arbitrary function basis in a space of arbitrary
38
+ dimension using linear least squares method.
39
+
40
+ Input parameters:
41
+ Y - array[0..N-1]
42
+ It contains a set of function values in N points. Space
43
+ dimension and points don't matter. Procedure works with
44
+ function values in these points and values of basis functions
45
+ only.
46
+
47
+ W - array[0..N-1]
48
+ It contains weights corresponding to function values. Each
49
+ summand in square sum of approximation deviations from given
50
+ values is multiplied by the square of corresponding weight.
51
+
52
+ FMatrix-a table of basis functions values, array[0..N-1, 0..M-1].
53
+ FMatrix[I, J] - value of J-th basis function in I-th point.
54
+
55
+ N - number of points used. N>=1.
56
+ M - number of basis functions, M>=1.
57
+
58
+ Output parameters:
59
+ C - decomposition coefficients.
60
+ Array of real numbers whose index goes from 0 to M-1.
61
+ C[j] - j-th basis function coefficient.
62
+
63
+ -- ALGLIB --
64
+ Copyright by Bochkanov Sergey
65
+ *************************************************************************/
66
+ void buildgeneralleastsquares(const ap::real_1d_array& y,
67
+ const ap::real_1d_array& w,
68
+ const ap::real_2d_array& fmatrix,
69
+ int n,
70
+ int m,
71
+ ap::real_1d_array& c)
72
+ {
73
+ int i;
74
+ int j;
75
+ ap::real_2d_array a;
76
+ ap::real_2d_array q;
77
+ ap::real_2d_array vt;
78
+ ap::real_1d_array b;
79
+ ap::real_1d_array tau;
80
+ ap::real_2d_array b2;
81
+ ap::real_1d_array tauq;
82
+ ap::real_1d_array taup;
83
+ ap::real_1d_array d;
84
+ ap::real_1d_array e;
85
+ bool isuppera;
86
+ int mi;
87
+ int ni;
88
+ double v;
89
+
90
+ mi = n;
91
+ ni = m;
92
+ c.setbounds(0, ni-1);
93
+
94
+ //
95
+ // Initialize design matrix.
96
+ // Here we are making MI>=NI.
97
+ //
98
+ a.setbounds(1, ni, 1, ap::maxint(mi, ni));
99
+ b.setbounds(1, ap::maxint(mi, ni));
100
+ for(i = 1; i <= mi; i++)
101
+ {
102
+ b(i) = w(i-1)*y(i-1);
103
+ }
104
+ for(i = mi+1; i <= ni; i++)
105
+ {
106
+ b(i) = 0;
107
+ }
108
+ for(j = 1; j <= ni; j++)
109
+ {
110
+ ap::vmove(a.getrow(j, 1, mi), fmatrix.getcolumn(j-1, 0, mi-1));
111
+ }
112
+ for(j = 1; j <= ni; j++)
113
+ {
114
+ for(i = mi+1; i <= ni; i++)
115
+ {
116
+ a(j,i) = 0;
117
+ }
118
+ }
119
+ for(j = 1; j <= ni; j++)
120
+ {
121
+ for(i = 1; i <= mi; i++)
122
+ {
123
+ a(j,i) = a(j,i)*w(i-1);
124
+ }
125
+ }
126
+ mi = ap::maxint(mi, ni);
127
+
128
+ //
129
+ // LQ-decomposition of A'
130
+ // B2 := Q*B
131
+ //
132
+ lqdecomposition(a, ni, mi, tau);
133
+ unpackqfromlq(a, ni, mi, tau, ni, q);
134
+ b2.setbounds(1, 1, 1, ni);
135
+ for(j = 1; j <= ni; j++)
136
+ {
137
+ b2(1,j) = 0;
138
+ }
139
+ for(i = 1; i <= ni; i++)
140
+ {
141
+ v = ap::vdotproduct(&b(1), &q(i, 1), ap::vlen(1,mi));
142
+ b2(1,i) = v;
143
+ }
144
+
145
+ //
146
+ // Back from A' to A
147
+ // Making cols(A)=rows(A)
148
+ //
149
+ for(i = 1; i <= ni-1; i++)
150
+ {
151
+ ap::vmove(a.getrow(i, i+1, ni), a.getcolumn(i, i+1, ni));
152
+ }
153
+ for(i = 2; i <= ni; i++)
154
+ {
155
+ for(j = 1; j <= i-1; j++)
156
+ {
157
+ a(i,j) = 0;
158
+ }
159
+ }
160
+
161
+ //
162
+ // Bidiagonal decomposition of A
163
+ // A = Q * d2 * P'
164
+ // B2 := (Q'*B2')'
165
+ //
166
+ tobidiagonal(a, ni, ni, tauq, taup);
167
+ multiplybyqfrombidiagonal(a, ni, ni, tauq, b2, 1, ni, true, false);
168
+ unpackptfrombidiagonal(a, ni, ni, taup, ni, vt);
169
+ unpackdiagonalsfrombidiagonal(a, ni, ni, isuppera, d, e);
170
+
171
+ //
172
+ // Singular value decomposition of A
173
+ // A = U * d * V'
174
+ // B2 := (U'*B2')'
175
+ //
176
+ if( !bidiagonalsvddecomposition(d, e, ni, isuppera, false, b2, 1, q, 0, vt, ni) )
177
+ {
178
+ for(i = 0; i <= ni-1; i++)
179
+ {
180
+ c(i) = 0;
181
+ }
182
+ return;
183
+ }
184
+
185
+ //
186
+ // B2 := (d^(-1) * B2')'
187
+ //
188
+ if( d(1)!=0 )
189
+ {
190
+ for(i = 1; i <= ni; i++)
191
+ {
192
+ if( d(i)>ap::machineepsilon*10*sqrt(double(ni))*d(1) )
193
+ {
194
+ b2(1,i) = b2(1,i)/d(i);
195
+ }
196
+ else
197
+ {
198
+ b2(1,i) = 0;
199
+ }
200
+ }
201
+ }
202
+
203
+ //
204
+ // B := (V * B2')'
205
+ //
206
+ for(i = 1; i <= ni; i++)
207
+ {
208
+ b(i) = 0;
209
+ }
210
+ for(i = 1; i <= ni; i++)
211
+ {
212
+ v = b2(1,i);
213
+ ap::vadd(&b(1), &vt(i, 1), ap::vlen(1,ni), v);
214
+ }
215
+
216
+ //
217
+ // Out
218
+ //
219
+ for(i = 1; i <= ni; i++)
220
+ {
221
+ c(i-1) = b(i);
222
+ }
223
+ }
224
+
225
+
226
+ /*************************************************************************
227
+ Linear approximation using least squares method
228
+
229
+ The subroutine calculates coefficients of the line approximating given
230
+ function.
231
+
232
+ Input parameters:
233
+ X - array[0..N-1], it contains a set of abscissas.
234
+ Y - array[0..N-1], function values.
235
+ N - number of points, N>=1
236
+
237
+ Output parameters:
238
+ a, b- coefficients of linear approximation a+b*t
239
+
240
+ -- ALGLIB --
241
+ Copyright by Bochkanov Sergey
242
+ *************************************************************************/
243
+ void buildlinearleastsquares(const ap::real_1d_array& x,
244
+ const ap::real_1d_array& y,
245
+ int n,
246
+ double& a,
247
+ double& b)
248
+ {
249
+ double pp;
250
+ double qq;
251
+ double pq;
252
+ double b1;
253
+ double b2;
254
+ double d1;
255
+ double d2;
256
+ double t1;
257
+ double t2;
258
+ double phi;
259
+ double c;
260
+ double s;
261
+ double m;
262
+ int i;
263
+
264
+ pp = n;
265
+ qq = 0;
266
+ pq = 0;
267
+ b1 = 0;
268
+ b2 = 0;
269
+ for(i = 0; i <= n-1; i++)
270
+ {
271
+ pq = pq+x(i);
272
+ qq = qq+ap::sqr(x(i));
273
+ b1 = b1+y(i);
274
+ b2 = b2+x(i)*y(i);
275
+ }
276
+ phi = atan2(2*pq, qq-pp)/2;
277
+ c = cos(phi);
278
+ s = sin(phi);
279
+ d1 = ap::sqr(c)*pp+ap::sqr(s)*qq-2*s*c*pq;
280
+ d2 = ap::sqr(s)*pp+ap::sqr(c)*qq+2*s*c*pq;
281
+ if( fabs(d1)>fabs(d2) )
282
+ {
283
+ m = fabs(d1);
284
+ }
285
+ else
286
+ {
287
+ m = fabs(d2);
288
+ }
289
+ t1 = c*b1-s*b2;
290
+ t2 = s*b1+c*b2;
291
+ if( fabs(d1)>m*ap::machineepsilon*1000 )
292
+ {
293
+ t1 = t1/d1;
294
+ }
295
+ else
296
+ {
297
+ t1 = 0;
298
+ }
299
+ if( fabs(d2)>m*ap::machineepsilon*1000 )
300
+ {
301
+ t2 = t2/d2;
302
+ }
303
+ else
304
+ {
305
+ t2 = 0;
306
+ }
307
+ a = c*t1+s*t2;
308
+ b = -s*t1+c*t2;
309
+ }
310
+
311
+
312
+ /*************************************************************************
313
+ Weighted cubic spline approximation using linear least squares
314
+
315
+ Input parameters:
316
+ X - array[0..N-1], abscissas
317
+ Y - array[0..N-1], function values
318
+ W - array[0..N-1], weights.
319
+ A, B- interval to build splines in.
320
+ N - number of points used. N>=1.
321
+ M - number of basic splines, M>=2.
322
+
323
+ Output parameters:
324
+ CTbl- coefficients table to be used by SplineInterpolation function.
325
+ -- ALGLIB --
326
+ Copyright by Bochkanov Sergey
327
+ *************************************************************************/
328
+ void buildsplineleastsquares(const ap::real_1d_array& x,
329
+ const ap::real_1d_array& y,
330
+ const ap::real_1d_array& w,
331
+ double a,
332
+ double b,
333
+ int n,
334
+ int m,
335
+ ap::real_1d_array& ctbl)
336
+ {
337
+ int i;
338
+ int j;
339
+ ap::real_2d_array ma;
340
+ ap::real_2d_array q;
341
+ ap::real_2d_array vt;
342
+ ap::real_1d_array mb;
343
+ ap::real_1d_array tau;
344
+ ap::real_2d_array b2;
345
+ ap::real_1d_array tauq;
346
+ ap::real_1d_array taup;
347
+ ap::real_1d_array d;
348
+ ap::real_1d_array e;
349
+ bool isuppera;
350
+ int mi;
351
+ int ni;
352
+ double v;
353
+ ap::real_1d_array sx;
354
+ ap::real_1d_array sy;
355
+
356
+ ap::ap_error::make_assertion(m>=2, "BuildSplineLeastSquares: M is too small!");
357
+ mi = n;
358
+ ni = m;
359
+ sx.setbounds(0, ni-1);
360
+ sy.setbounds(0, ni-1);
361
+
362
+ //
363
+ // Initializing design matrix
364
+ // Here we are making MI>=NI
365
+ //
366
+ ma.setbounds(1, ni, 1, ap::maxint(mi, ni));
367
+ mb.setbounds(1, ap::maxint(mi, ni));
368
+ for(j = 0; j <= ni-1; j++)
369
+ {
370
+ sx(j) = a+(b-a)*j/(ni-1);
371
+ }
372
+ for(j = 0; j <= ni-1; j++)
373
+ {
374
+ for(i = 0; i <= ni-1; i++)
375
+ {
376
+ sy(i) = 0;
377
+ }
378
+ sy(j) = 1;
379
+ buildcubicspline(sx, sy, ni, 0, 0.0, 0, 0.0, ctbl);
380
+ for(i = 0; i <= mi-1; i++)
381
+ {
382
+ ma(j+1,i+1) = w(i)*splineinterpolation(ctbl, x(i));
383
+ }
384
+ }
385
+ for(j = 1; j <= ni; j++)
386
+ {
387
+ for(i = mi+1; i <= ni; i++)
388
+ {
389
+ ma(j,i) = 0;
390
+ }
391
+ }
392
+
393
+ //
394
+ // Initializing right part
395
+ //
396
+ for(i = 0; i <= mi-1; i++)
397
+ {
398
+ mb(i+1) = w(i)*y(i);
399
+ }
400
+ for(i = mi+1; i <= ni; i++)
401
+ {
402
+ mb(i) = 0;
403
+ }
404
+ mi = ap::maxint(mi, ni);
405
+
406
+ //
407
+ // LQ-decomposition of A'
408
+ // B2 := Q*B
409
+ //
410
+ lqdecomposition(ma, ni, mi, tau);
411
+ unpackqfromlq(ma, ni, mi, tau, ni, q);
412
+ b2.setbounds(1, 1, 1, ni);
413
+ for(j = 1; j <= ni; j++)
414
+ {
415
+ b2(1,j) = 0;
416
+ }
417
+ for(i = 1; i <= ni; i++)
418
+ {
419
+ v = ap::vdotproduct(&mb(1), &q(i, 1), ap::vlen(1,mi));
420
+ b2(1,i) = v;
421
+ }
422
+
423
+ //
424
+ // Back from A' to A
425
+ // Making cols(A)=rows(A)
426
+ //
427
+ for(i = 1; i <= ni-1; i++)
428
+ {
429
+ ap::vmove(ma.getrow(i, i+1, ni), ma.getcolumn(i, i+1, ni));
430
+ }
431
+ for(i = 2; i <= ni; i++)
432
+ {
433
+ for(j = 1; j <= i-1; j++)
434
+ {
435
+ ma(i,j) = 0;
436
+ }
437
+ }
438
+
439
+ //
440
+ // Bidiagonal decomposition of A
441
+ // A = Q * d2 * P'
442
+ // B2 := (Q'*B2')'
443
+ //
444
+ tobidiagonal(ma, ni, ni, tauq, taup);
445
+ multiplybyqfrombidiagonal(ma, ni, ni, tauq, b2, 1, ni, true, false);
446
+ unpackptfrombidiagonal(ma, ni, ni, taup, ni, vt);
447
+ unpackdiagonalsfrombidiagonal(ma, ni, ni, isuppera, d, e);
448
+
449
+ //
450
+ // Singular value decomposition of A
451
+ // A = U * d * V'
452
+ // B2 := (U'*B2')'
453
+ //
454
+ if( !bidiagonalsvddecomposition(d, e, ni, isuppera, false, b2, 1, q, 0, vt, ni) )
455
+ {
456
+ for(i = 1; i <= ni; i++)
457
+ {
458
+ d(i) = 0;
459
+ b2(1,i) = 0;
460
+ for(j = 1; j <= ni; j++)
461
+ {
462
+ if( i==j )
463
+ {
464
+ vt(i,j) = 1;
465
+ }
466
+ else
467
+ {
468
+ vt(i,j) = 0;
469
+ }
470
+ }
471
+ }
472
+ b2(1,1) = 1;
473
+ }
474
+
475
+ //
476
+ // B2 := (d^(-1) * B2')'
477
+ //
478
+ for(i = 1; i <= ni; i++)
479
+ {
480
+ if( d(i)>ap::machineepsilon*10*sqrt(double(ni))*d(1) )
481
+ {
482
+ b2(1,i) = b2(1,i)/d(i);
483
+ }
484
+ else
485
+ {
486
+ b2(1,i) = 0;
487
+ }
488
+ }
489
+
490
+ //
491
+ // B := (V * B2')'
492
+ //
493
+ for(i = 1; i <= ni; i++)
494
+ {
495
+ mb(i) = 0;
496
+ }
497
+ for(i = 1; i <= ni; i++)
498
+ {
499
+ v = b2(1,i);
500
+ ap::vadd(&mb(1), &vt(i, 1), ap::vlen(1,ni), v);
501
+ }
502
+
503
+ //
504
+ // Forming result spline
505
+ //
506
+ for(i = 0; i <= ni-1; i++)
507
+ {
508
+ sy(i) = mb(i+1);
509
+ }
510
+ buildcubicspline(sx, sy, ni, 0, 0.0, 0, 0.0, ctbl);
511
+ }
512
+
513
+
514
+ /*************************************************************************
515
+ Polynomial approximation using least squares method
516
+
517
+ The subroutine calculates coefficients of the polynomial approximating
518
+ given function. It is recommended to use this function only if you need to
519
+ obtain coefficients of approximation polynomial. If you have to build and
520
+ calculate polynomial approximation (NOT coefficients), it's better to use
521
+ BuildChebyshevLeastSquares subroutine in combination with
522
+ CalculateChebyshevLeastSquares subroutine. The result of Chebyshev
523
+ polynomial approximation is equivalent to the result obtained using powers
524
+ of X, but has higher accuracy due to better numerical properties of
525
+ Chebyshev polynomials.
526
+
527
+ Input parameters:
528
+ X - array[0..N-1], abscissas
529
+ Y - array[0..N-1], function values
530
+ N - number of points, N>=1
531
+ M - order of polynomial required, M>=0
532
+
533
+ Output parameters:
534
+ C - approximating polynomial coefficients, array[0..M],
535
+ C[i] - coefficient at X^i.
536
+
537
+ -- ALGLIB --
538
+ Copyright by Bochkanov Sergey
539
+ *************************************************************************/
540
+ void buildpolynomialleastsquares(const ap::real_1d_array& x,
541
+ const ap::real_1d_array& y,
542
+ int n,
543
+ int m,
544
+ ap::real_1d_array& c)
545
+ {
546
+ ap::real_1d_array ctbl;
547
+ ap::real_1d_array w;
548
+ ap::real_1d_array c1;
549
+ double maxx;
550
+ double minx;
551
+ int i;
552
+ int j;
553
+ int k;
554
+ double e;
555
+ double d;
556
+ double l1;
557
+ double l2;
558
+ ap::real_1d_array z2;
559
+ ap::real_1d_array z1;
560
+
561
+
562
+ //
563
+ // Initialize
564
+ //
565
+ maxx = x(0);
566
+ minx = x(0);
567
+ for(i = 1; i <= n-1; i++)
568
+ {
569
+ if( x(i)>maxx )
570
+ {
571
+ maxx = x(i);
572
+ }
573
+ if( x(i)<minx )
574
+ {
575
+ minx = x(i);
576
+ }
577
+ }
578
+ if( minx==maxx )
579
+ {
580
+ minx = minx-0.5;
581
+ maxx = maxx+0.5;
582
+ }
583
+ w.setbounds(0, n-1);
584
+ for(i = 0; i <= n-1; i++)
585
+ {
586
+ w(i) = 1;
587
+ }
588
+
589
+ //
590
+ // Build Chebyshev approximation
591
+ //
592
+ buildchebyshevleastsquares(x, y, w, minx, maxx, n, m, ctbl);
593
+
594
+ //
595
+ // From Chebyshev to powers of X
596
+ //
597
+ c1.setbounds(0, m);
598
+ for(i = 0; i <= m; i++)
599
+ {
600
+ c1(i) = 0;
601
+ }
602
+ d = 0;
603
+ for(i = 0; i <= m; i++)
604
+ {
605
+ for(k = i; k <= m; k++)
606
+ {
607
+ e = c1(k);
608
+ c1(k) = 0;
609
+ if( i<=1&&k==i )
610
+ {
611
+ c1(k) = 1;
612
+ }
613
+ else
614
+ {
615
+ if( i!=0 )
616
+ {
617
+ c1(k) = 2*d;
618
+ }
619
+ if( k>i+1 )
620
+ {
621
+ c1(k) = c1(k)-c1(k-2);
622
+ }
623
+ }
624
+ d = e;
625
+ }
626
+ d = c1(i);
627
+ e = 0;
628
+ k = i;
629
+ while(k<=m)
630
+ {
631
+ e = e+c1(k)*ctbl(k);
632
+ k = k+2;
633
+ }
634
+ c1(i) = e;
635
+ }
636
+
637
+ //
638
+ // Linear translation
639
+ //
640
+ l1 = 2/(ctbl(m+2)-ctbl(m+1));
641
+ l2 = -2*ctbl(m+1)/(ctbl(m+2)-ctbl(m+1))-1;
642
+ c.setbounds(0, m);
643
+ z2.setbounds(0, m);
644
+ z1.setbounds(0, m);
645
+ c(0) = c1(0);
646
+ z1(0) = 1;
647
+ z2(0) = 1;
648
+ for(i = 1; i <= m; i++)
649
+ {
650
+ z2(i) = 1;
651
+ z1(i) = l2*z1(i-1);
652
+ c(0) = c(0)+c1(i)*z1(i);
653
+ }
654
+ for(j = 1; j <= m; j++)
655
+ {
656
+ z2(0) = l1*z2(0);
657
+ c(j) = c1(j)*z2(0);
658
+ for(i = j+1; i <= m; i++)
659
+ {
660
+ k = i-j;
661
+ z2(k) = l1*z2(k)+z2(k-1);
662
+ c(j) = c(j)+c1(i)*z2(k)*z1(k);
663
+ }
664
+ }
665
+ }
666
+
667
+
668
+ /*************************************************************************
669
+ Chebyshev polynomial approximation using least squares method.
670
+
671
+ The algorithm reduces interval [A, B] to the interval [-1,1], then builds
672
+ least squares approximation using Chebyshev polynomials.
673
+
674
+ Input parameters:
675
+ X - array[0..N-1], abscissas
676
+ Y - array[0..N-1], function values
677
+ W - array[0..N-1], weights
678
+ A, B- interval to build approximating polynomials in.
679
+ N - number of points used. N>=1.
680
+ M - order of polynomial, M>=0. This parameter is passed into
681
+ CalculateChebyshevLeastSquares function.
682
+
683
+ Output parameters:
684
+ CTbl - coefficient table. This parameter is passed into
685
+ CalculateChebyshevLeastSquares function.
686
+ -- ALGLIB --
687
+ Copyright by Bochkanov Sergey
688
+ *************************************************************************/
689
+ void buildchebyshevleastsquares(const ap::real_1d_array& x,
690
+ const ap::real_1d_array& y,
691
+ const ap::real_1d_array& w,
692
+ double a,
693
+ double b,
694
+ int n,
695
+ int m,
696
+ ap::real_1d_array& ctbl)
697
+ {
698
+ int i;
699
+ int j;
700
+ ap::real_2d_array ma;
701
+ ap::real_2d_array q;
702
+ ap::real_2d_array vt;
703
+ ap::real_1d_array mb;
704
+ ap::real_1d_array tau;
705
+ ap::real_2d_array b2;
706
+ ap::real_1d_array tauq;
707
+ ap::real_1d_array taup;
708
+ ap::real_1d_array d;
709
+ ap::real_1d_array e;
710
+ bool isuppera;
711
+ int mi;
712
+ int ni;
713
+ double v;
714
+
715
+ mi = n;
716
+ ni = m+1;
717
+
718
+ //
719
+ // Initializing design matrix
720
+ // Here we are making MI>=NI
721
+ //
722
+ ma.setbounds(1, ni, 1, ap::maxint(mi, ni));
723
+ mb.setbounds(1, ap::maxint(mi, ni));
724
+ for(j = 1; j <= ni; j++)
725
+ {
726
+ for(i = 1; i <= mi; i++)
727
+ {
728
+ v = 2*(x(i-1)-a)/(b-a)-1;
729
+ if( j==1 )
730
+ {
731
+ ma(j,i) = 1.0;
732
+ }
733
+ if( j==2 )
734
+ {
735
+ ma(j,i) = v;
736
+ }
737
+ if( j>2 )
738
+ {
739
+ ma(j,i) = 2.0*v*ma(j-1,i)-ma(j-2,i);
740
+ }
741
+ }
742
+ }
743
+ for(j = 1; j <= ni; j++)
744
+ {
745
+ for(i = 1; i <= mi; i++)
746
+ {
747
+ ma(j,i) = w(i-1)*ma(j,i);
748
+ }
749
+ }
750
+ for(j = 1; j <= ni; j++)
751
+ {
752
+ for(i = mi+1; i <= ni; i++)
753
+ {
754
+ ma(j,i) = 0;
755
+ }
756
+ }
757
+
758
+ //
759
+ // Initializing right part
760
+ //
761
+ for(i = 0; i <= mi-1; i++)
762
+ {
763
+ mb(i+1) = w(i)*y(i);
764
+ }
765
+ for(i = mi+1; i <= ni; i++)
766
+ {
767
+ mb(i) = 0;
768
+ }
769
+ mi = ap::maxint(mi, ni);
770
+
771
+ //
772
+ // LQ-decomposition of A'
773
+ // B2 := Q*B
774
+ //
775
+ lqdecomposition(ma, ni, mi, tau);
776
+ unpackqfromlq(ma, ni, mi, tau, ni, q);
777
+ b2.setbounds(1, 1, 1, ni);
778
+ for(j = 1; j <= ni; j++)
779
+ {
780
+ b2(1,j) = 0;
781
+ }
782
+ for(i = 1; i <= ni; i++)
783
+ {
784
+ v = ap::vdotproduct(&mb(1), &q(i, 1), ap::vlen(1,mi));
785
+ b2(1,i) = v;
786
+ }
787
+
788
+ //
789
+ // Back from A' to A
790
+ // Making cols(A)=rows(A)
791
+ //
792
+ for(i = 1; i <= ni-1; i++)
793
+ {
794
+ ap::vmove(ma.getrow(i, i+1, ni), ma.getcolumn(i, i+1, ni));
795
+ }
796
+ for(i = 2; i <= ni; i++)
797
+ {
798
+ for(j = 1; j <= i-1; j++)
799
+ {
800
+ ma(i,j) = 0;
801
+ }
802
+ }
803
+
804
+ //
805
+ // Bidiagonal decomposition of A
806
+ // A = Q * d2 * P'
807
+ // B2 := (Q'*B2')'
808
+ //
809
+ tobidiagonal(ma, ni, ni, tauq, taup);
810
+ multiplybyqfrombidiagonal(ma, ni, ni, tauq, b2, 1, ni, true, false);
811
+ unpackptfrombidiagonal(ma, ni, ni, taup, ni, vt);
812
+ unpackdiagonalsfrombidiagonal(ma, ni, ni, isuppera, d, e);
813
+
814
+ //
815
+ // Singular value decomposition of A
816
+ // A = U * d * V'
817
+ // B2 := (U'*B2')'
818
+ //
819
+ if( !bidiagonalsvddecomposition(d, e, ni, isuppera, false, b2, 1, q, 0, vt, ni) )
820
+ {
821
+ for(i = 1; i <= ni; i++)
822
+ {
823
+ d(i) = 0;
824
+ b2(1,i) = 0;
825
+ for(j = 1; j <= ni; j++)
826
+ {
827
+ if( i==j )
828
+ {
829
+ vt(i,j) = 1;
830
+ }
831
+ else
832
+ {
833
+ vt(i,j) = 0;
834
+ }
835
+ }
836
+ }
837
+ b2(1,1) = 1;
838
+ }
839
+
840
+ //
841
+ // B2 := (d^(-1) * B2')'
842
+ //
843
+ for(i = 1; i <= ni; i++)
844
+ {
845
+ if( d(i)>ap::machineepsilon*10*sqrt(double(ni))*d(1) )
846
+ {
847
+ b2(1,i) = b2(1,i)/d(i);
848
+ }
849
+ else
850
+ {
851
+ b2(1,i) = 0;
852
+ }
853
+ }
854
+
855
+ //
856
+ // B := (V * B2')'
857
+ //
858
+ for(i = 1; i <= ni; i++)
859
+ {
860
+ mb(i) = 0;
861
+ }
862
+ for(i = 1; i <= ni; i++)
863
+ {
864
+ v = b2(1,i);
865
+ ap::vadd(&mb(1), &vt(i, 1), ap::vlen(1,ni), v);
866
+ }
867
+
868
+ //
869
+ // Forming result
870
+ //
871
+ ctbl.setbounds(0, ni+1);
872
+ for(i = 1; i <= ni; i++)
873
+ {
874
+ ctbl(i-1) = mb(i);
875
+ }
876
+ ctbl(ni) = a;
877
+ ctbl(ni+1) = b;
878
+ }
879
+
880
+
881
+ /*************************************************************************
882
+ Weighted Chebyshev polynomial constrained least squares approximation.
883
+
884
+ The algorithm reduces [A,B] to [-1,1] and builds the Chebyshev polynomials
885
+ series by approximating a given function using the least squares method.
886
+
887
+ Input parameters:
888
+ X - abscissas, array[0..N-1]
889
+ Y - function values, array[0..N-1]
890
+ W - weights, array[0..N-1]. Each item in the squared sum of
891
+ deviations from given values is multiplied by a square of
892
+ corresponding weight.
893
+ A, B- interval in which the approximating polynomials are built.
894
+ N - number of points, N>0.
895
+ XC, YC, DC-
896
+ constraints (see description below)., array[0..NC-1]
897
+ NC - number of constraints. 0 <= NC < M+1.
898
+ M - degree of polynomial, M>=0. This parameter is passed into the
899
+ CalculateChebyshevLeastSquares subroutine.
900
+
901
+ Output parameters:
902
+ CTbl- coefficient table. This parameter is passed into the
903
+ CalculateChebyshevLeastSquares subroutine.
904
+
905
+ Result:
906
+ True, if the algorithm succeeded.
907
+ False, if the internal singular value decomposition subroutine hasn't
908
+ converged or the given constraints could not be met simultaneously (e.g.
909
+ P(0)=0 � P(0)=1).
910
+
911
+ Specifying constraints:
912
+ This subroutine can solve the problem having constrained function
913
+ values or its derivatives in several points. NC specifies the number of
914
+ constraints, DC - the type of constraints, XC and YC - constraints as such.
915
+ Thus, for each i from 0 to NC-1 the following constraint is given:
916
+ P(xc[i]) = yc[i], if DC[i]=0
917
+ or
918
+ d/dx(P(xc[i])) = yc[i], if DC[i]=1
919
+ (here P(x) is approximating polynomial).
920
+ This version of the subroutine supports only either polynomial or its
921
+ derivative value constraints. If DC[i] is not equal to 0 and 1, the
922
+ subroutine will be aborted. The number of constraints should be less than
923
+ the number of degrees of freedom of approximating polynomial - M+1 (at
924
+ that, it could be equal to 0).
925
+
926
+ -- ALGLIB --
927
+ Copyright by Bochkanov Sergey
928
+ *************************************************************************/
929
+ bool buildchebyshevleastsquaresconstrained(const ap::real_1d_array& x,
930
+ const ap::real_1d_array& y,
931
+ const ap::real_1d_array& w,
932
+ double a,
933
+ double b,
934
+ int n,
935
+ const ap::real_1d_array& xc,
936
+ const ap::real_1d_array& yc,
937
+ const ap::integer_1d_array& dc,
938
+ int nc,
939
+ int m,
940
+ ap::real_1d_array& ctbl)
941
+ {
942
+ bool result;
943
+ int i;
944
+ int j;
945
+ int reducedsize;
946
+ ap::real_2d_array designmatrix;
947
+ ap::real_1d_array rightpart;
948
+ ap::real_2d_array cmatrix;
949
+ ap::real_2d_array c;
950
+ ap::real_2d_array u;
951
+ ap::real_2d_array vt;
952
+ ap::real_1d_array d;
953
+ ap::real_1d_array cr;
954
+ ap::real_1d_array ws;
955
+ ap::real_1d_array tj;
956
+ ap::real_1d_array uj;
957
+ ap::real_1d_array dtj;
958
+ ap::real_1d_array tmp;
959
+ ap::real_1d_array tmp2;
960
+ ap::real_2d_array tmpmatrix;
961
+ double v;
962
+
963
+ ap::ap_error::make_assertion(n>0, "");
964
+ ap::ap_error::make_assertion(m>=0, "");
965
+ ap::ap_error::make_assertion(nc>=0&&nc<m+1, "");
966
+ result = true;
967
+
968
+ //
969
+ // Initialize design matrix and right part.
970
+ // Add fictional rows if needed to ensure that N>=M+1.
971
+ //
972
+ designmatrix.setbounds(1, ap::maxint(n, m+1), 1, m+1);
973
+ rightpart.setbounds(1, ap::maxint(n, m+1));
974
+ for(i = 1; i <= n; i++)
975
+ {
976
+ for(j = 1; j <= m+1; j++)
977
+ {
978
+ v = 2*(x(i-1)-a)/(b-a)-1;
979
+ if( j==1 )
980
+ {
981
+ designmatrix(i,j) = 1.0;
982
+ }
983
+ if( j==2 )
984
+ {
985
+ designmatrix(i,j) = v;
986
+ }
987
+ if( j>2 )
988
+ {
989
+ designmatrix(i,j) = 2.0*v*designmatrix(i,j-1)-designmatrix(i,j-2);
990
+ }
991
+ }
992
+ }
993
+ for(i = 1; i <= n; i++)
994
+ {
995
+ for(j = 1; j <= m+1; j++)
996
+ {
997
+ designmatrix(i,j) = w(i-1)*designmatrix(i,j);
998
+ }
999
+ }
1000
+ for(i = n+1; i <= m+1; i++)
1001
+ {
1002
+ for(j = 1; j <= m+1; j++)
1003
+ {
1004
+ designmatrix(i,j) = 0;
1005
+ }
1006
+ }
1007
+ for(i = 0; i <= n-1; i++)
1008
+ {
1009
+ rightpart(i+1) = w(i)*y(i);
1010
+ }
1011
+ for(i = n+1; i <= m+1; i++)
1012
+ {
1013
+ rightpart(i) = 0;
1014
+ }
1015
+ n = ap::maxint(n, m+1);
1016
+
1017
+ //
1018
+ // Now N>=M+1 and we are ready to the next stage.
1019
+ // Handle constraints.
1020
+ // Represent feasible set of coefficients as x = C*t + d
1021
+ //
1022
+ c.setbounds(1, m+1, 1, m+1);
1023
+ d.setbounds(1, m+1);
1024
+ if( nc==0 )
1025
+ {
1026
+
1027
+ //
1028
+ // No constraints
1029
+ //
1030
+ for(i = 1; i <= m+1; i++)
1031
+ {
1032
+ for(j = 1; j <= m+1; j++)
1033
+ {
1034
+ c(i,j) = 0;
1035
+ }
1036
+ d(i) = 0;
1037
+ }
1038
+ for(i = 1; i <= m+1; i++)
1039
+ {
1040
+ c(i,i) = 1;
1041
+ }
1042
+ reducedsize = m+1;
1043
+ }
1044
+ else
1045
+ {
1046
+
1047
+ //
1048
+ // Constraints are present.
1049
+ // Fill constraints matrix CMatrix and solve CMatrix*x = cr.
1050
+ //
1051
+ cmatrix.setbounds(1, nc, 1, m+1);
1052
+ cr.setbounds(1, nc);
1053
+ tj.setbounds(0, m);
1054
+ uj.setbounds(0, m);
1055
+ dtj.setbounds(0, m);
1056
+ for(i = 0; i <= nc-1; i++)
1057
+ {
1058
+ v = 2*(xc(i)-a)/(b-a)-1;
1059
+ for(j = 0; j <= m; j++)
1060
+ {
1061
+ if( j==0 )
1062
+ {
1063
+ tj(j) = 1;
1064
+ uj(j) = 1;
1065
+ dtj(j) = 0;
1066
+ }
1067
+ if( j==1 )
1068
+ {
1069
+ tj(j) = v;
1070
+ uj(j) = 2*v;
1071
+ dtj(j) = 1;
1072
+ }
1073
+ if( j>1 )
1074
+ {
1075
+ tj(j) = 2*v*tj(j-1)-tj(j-2);
1076
+ uj(j) = 2*v*uj(j-1)-uj(j-2);
1077
+ dtj(j) = j*uj(j-1);
1078
+ }
1079
+ ap::ap_error::make_assertion(dc(i)==0||dc(i)==1, "");
1080
+ if( dc(i)==0 )
1081
+ {
1082
+ cmatrix(i+1,j+1) = tj(j);
1083
+ }
1084
+ if( dc(i)==1 )
1085
+ {
1086
+ cmatrix(i+1,j+1) = dtj(j);
1087
+ }
1088
+ }
1089
+ cr(i+1) = yc(i);
1090
+ }
1091
+
1092
+ //
1093
+ // Solve CMatrix*x = cr.
1094
+ // Fill C and d:
1095
+ // 1. SVD: CMatrix = U * WS * V^T
1096
+ // 2. C := V[1:M+1,NC+1:M+1]
1097
+ // 3. tmp := WS^-1 * U^T * cr
1098
+ // 4. d := V[1:M+1,1:NC] * tmp
1099
+ //
1100
+ if( !svddecomposition(cmatrix, nc, m+1, 2, 2, 2, ws, u, vt) )
1101
+ {
1102
+ result = false;
1103
+ return result;
1104
+ }
1105
+ if( ws(1)==0||ws(nc)<=ap::machineepsilon*10*sqrt(double(nc))*ws(1) )
1106
+ {
1107
+ result = false;
1108
+ return result;
1109
+ }
1110
+ c.setbounds(1, m+1, 1, m+1-nc);
1111
+ d.setbounds(1, m+1);
1112
+ for(i = 1; i <= m+1-nc; i++)
1113
+ {
1114
+ ap::vmove(c.getcolumn(i, 1, m+1), vt.getrow(nc+i, 1, m+1));
1115
+ }
1116
+ tmp.setbounds(1, nc);
1117
+ for(i = 1; i <= nc; i++)
1118
+ {
1119
+ v = ap::vdotproduct(u.getcolumn(i, 1, nc), cr.getvector(1, nc));
1120
+ tmp(i) = v/ws(i);
1121
+ }
1122
+ for(i = 1; i <= m+1; i++)
1123
+ {
1124
+ d(i) = 0;
1125
+ }
1126
+ for(i = 1; i <= nc; i++)
1127
+ {
1128
+ v = tmp(i);
1129
+ ap::vadd(&d(1), &vt(i, 1), ap::vlen(1,m+1), v);
1130
+ }
1131
+
1132
+ //
1133
+ // Reduce problem:
1134
+ // 1. RightPart := RightPart - DesignMatrix*d
1135
+ // 2. DesignMatrix := DesignMatrix*C
1136
+ //
1137
+ for(i = 1; i <= n; i++)
1138
+ {
1139
+ v = ap::vdotproduct(&designmatrix(i, 1), &d(1), ap::vlen(1,m+1));
1140
+ rightpart(i) = rightpart(i)-v;
1141
+ }
1142
+ reducedsize = m+1-nc;
1143
+ tmpmatrix.setbounds(1, n, 1, reducedsize);
1144
+ tmp.setbounds(1, n);
1145
+ matrixmatrixmultiply(designmatrix, 1, n, 1, m+1, false, c, 1, m+1, 1, reducedsize, false, 1.0, tmpmatrix, 1, n, 1, reducedsize, 0.0, tmp);
1146
+ copymatrix(tmpmatrix, 1, n, 1, reducedsize, designmatrix, 1, n, 1, reducedsize);
1147
+ }
1148
+
1149
+ //
1150
+ // Solve reduced problem DesignMatrix*t = RightPart.
1151
+ //
1152
+ if( !svddecomposition(designmatrix, n, reducedsize, 1, 1, 2, ws, u, vt) )
1153
+ {
1154
+ result = false;
1155
+ return result;
1156
+ }
1157
+ tmp.setbounds(1, reducedsize);
1158
+ tmp2.setbounds(1, reducedsize);
1159
+ for(i = 1; i <= reducedsize; i++)
1160
+ {
1161
+ tmp(i) = 0;
1162
+ }
1163
+ for(i = 1; i <= n; i++)
1164
+ {
1165
+ v = rightpart(i);
1166
+ ap::vadd(&tmp(1), &u(i, 1), ap::vlen(1,reducedsize), v);
1167
+ }
1168
+ for(i = 1; i <= reducedsize; i++)
1169
+ {
1170
+ if( ws(i)!=0&&ws(i)>ap::machineepsilon*10*sqrt(double(nc))*ws(1) )
1171
+ {
1172
+ tmp(i) = tmp(i)/ws(i);
1173
+ }
1174
+ else
1175
+ {
1176
+ tmp(i) = 0;
1177
+ }
1178
+ }
1179
+ for(i = 1; i <= reducedsize; i++)
1180
+ {
1181
+ tmp2(i) = 0;
1182
+ }
1183
+ for(i = 1; i <= reducedsize; i++)
1184
+ {
1185
+ v = tmp(i);
1186
+ ap::vadd(&tmp2(1), &vt(i, 1), ap::vlen(1,reducedsize), v);
1187
+ }
1188
+
1189
+ //
1190
+ // Solution is in the tmp2.
1191
+ // Transform it from t to x.
1192
+ //
1193
+ ctbl.setbounds(0, m+2);
1194
+ for(i = 1; i <= m+1; i++)
1195
+ {
1196
+ v = ap::vdotproduct(&c(i, 1), &tmp2(1), ap::vlen(1,reducedsize));
1197
+ ctbl(i-1) = v+d(i);
1198
+ }
1199
+ ctbl(m+1) = a;
1200
+ ctbl(m+2) = b;
1201
+ return result;
1202
+ }
1203
+
1204
+
1205
+ /*************************************************************************
1206
+ Calculation of a Chebyshev polynomial obtained during least squares
1207
+ approximaion at the given point.
1208
+
1209
+ Input parameters:
1210
+ M - order of polynomial (parameter of the
1211
+ BuildChebyshevLeastSquares function).
1212
+ A - coefficient table.
1213
+ A[0..M] contains coefficients of the i-th Chebyshev polynomial.
1214
+ A[M+1] contains left boundary of approximation interval.
1215
+ A[M+2] contains right boundary of approximation interval.
1216
+ X - point to perform calculations in.
1217
+
1218
+ The result is the value at the given point.
1219
+
1220
+ It should be noted that array A contains coefficients of the Chebyshev
1221
+ polynomials defined on interval [-1,1]. Argument is reduced to this
1222
+ interval before calculating polynomial value.
1223
+ -- ALGLIB --
1224
+ Copyright by Bochkanov Sergey
1225
+ *************************************************************************/
1226
+ double calculatechebyshevleastsquares(const int& m,
1227
+ const ap::real_1d_array& a,
1228
+ double x)
1229
+ {
1230
+ double result;
1231
+ double b1;
1232
+ double b2;
1233
+ int i;
1234
+
1235
+ x = 2*(x-a(m+1))/(a(m+2)-a(m+1))-1;
1236
+ b1 = 0;
1237
+ b2 = 0;
1238
+ i = m;
1239
+ do
1240
+ {
1241
+ result = 2*x*b1-b2+a(i);
1242
+ b2 = b1;
1243
+ b1 = result;
1244
+ i = i-1;
1245
+ }
1246
+ while(i>=0);
1247
+ result = result-x*b2;
1248
+ return result;
1249
+ }
1250
+
1251
+
1252
+