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,290 @@
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
+ #ifndef _leastsquares_h
34
+ #define _leastsquares_h
35
+
36
+ #include "ap.h"
37
+ #include "ialglib.h"
38
+
39
+ #include "spline3.h"
40
+ #include "reflections.h"
41
+ #include "lq.h"
42
+ #include "bidiagonal.h"
43
+ #include "rotations.h"
44
+ #include "bdsvd.h"
45
+ #include "qr.h"
46
+ #include "blas.h"
47
+ #include "svd.h"
48
+
49
+
50
+ /*************************************************************************
51
+ Weighted approximation by arbitrary function basis in a space of arbitrary
52
+ dimension using linear least squares method.
53
+
54
+ Input parameters:
55
+ Y - array[0..N-1]
56
+ It contains a set of function values in N points. Space
57
+ dimension and points don't matter. Procedure works with
58
+ function values in these points and values of basis functions
59
+ only.
60
+
61
+ W - array[0..N-1]
62
+ It contains weights corresponding to function values. Each
63
+ summand in square sum of approximation deviations from given
64
+ values is multiplied by the square of corresponding weight.
65
+
66
+ FMatrix-a table of basis functions values, array[0..N-1, 0..M-1].
67
+ FMatrix[I, J] - value of J-th basis function in I-th point.
68
+
69
+ N - number of points used. N>=1.
70
+ M - number of basis functions, M>=1.
71
+
72
+ Output parameters:
73
+ C - decomposition coefficients.
74
+ Array of real numbers whose index goes from 0 to M-1.
75
+ C[j] - j-th basis function coefficient.
76
+
77
+ -- ALGLIB --
78
+ Copyright by Bochkanov Sergey
79
+ *************************************************************************/
80
+ void buildgeneralleastsquares(const ap::real_1d_array& y,
81
+ const ap::real_1d_array& w,
82
+ const ap::real_2d_array& fmatrix,
83
+ int n,
84
+ int m,
85
+ ap::real_1d_array& c);
86
+
87
+
88
+ /*************************************************************************
89
+ Linear approximation using least squares method
90
+
91
+ The subroutine calculates coefficients of the line approximating given
92
+ function.
93
+
94
+ Input parameters:
95
+ X - array[0..N-1], it contains a set of abscissas.
96
+ Y - array[0..N-1], function values.
97
+ N - number of points, N>=1
98
+
99
+ Output parameters:
100
+ a, b- coefficients of linear approximation a+b*t
101
+
102
+ -- ALGLIB --
103
+ Copyright by Bochkanov Sergey
104
+ *************************************************************************/
105
+ void buildlinearleastsquares(const ap::real_1d_array& x,
106
+ const ap::real_1d_array& y,
107
+ int n,
108
+ double& a,
109
+ double& b);
110
+
111
+
112
+ /*************************************************************************
113
+ Weighted cubic spline approximation using linear least squares
114
+
115
+ Input parameters:
116
+ X - array[0..N-1], abscissas
117
+ Y - array[0..N-1], function values
118
+ W - array[0..N-1], weights.
119
+ A, B- interval to build splines in.
120
+ N - number of points used. N>=1.
121
+ M - number of basic splines, M>=2.
122
+
123
+ Output parameters:
124
+ CTbl- coefficients table to be used by SplineInterpolation function.
125
+ -- ALGLIB --
126
+ Copyright by Bochkanov Sergey
127
+ *************************************************************************/
128
+ void buildsplineleastsquares(const ap::real_1d_array& x,
129
+ const ap::real_1d_array& y,
130
+ const ap::real_1d_array& w,
131
+ double a,
132
+ double b,
133
+ int n,
134
+ int m,
135
+ ap::real_1d_array& ctbl);
136
+
137
+
138
+ /*************************************************************************
139
+ Polynomial approximation using least squares method
140
+
141
+ The subroutine calculates coefficients of the polynomial approximating
142
+ given function. It is recommended to use this function only if you need to
143
+ obtain coefficients of approximation polynomial. If you have to build and
144
+ calculate polynomial approximation (NOT coefficients), it's better to use
145
+ BuildChebyshevLeastSquares subroutine in combination with
146
+ CalculateChebyshevLeastSquares subroutine. The result of Chebyshev
147
+ polynomial approximation is equivalent to the result obtained using powers
148
+ of X, but has higher accuracy due to better numerical properties of
149
+ Chebyshev polynomials.
150
+
151
+ Input parameters:
152
+ X - array[0..N-1], abscissas
153
+ Y - array[0..N-1], function values
154
+ N - number of points, N>=1
155
+ M - order of polynomial required, M>=0
156
+
157
+ Output parameters:
158
+ C - approximating polynomial coefficients, array[0..M],
159
+ C[i] - coefficient at X^i.
160
+
161
+ -- ALGLIB --
162
+ Copyright by Bochkanov Sergey
163
+ *************************************************************************/
164
+ void buildpolynomialleastsquares(const ap::real_1d_array& x,
165
+ const ap::real_1d_array& y,
166
+ int n,
167
+ int m,
168
+ ap::real_1d_array& c);
169
+
170
+
171
+ /*************************************************************************
172
+ Chebyshev polynomial approximation using least squares method.
173
+
174
+ The algorithm reduces interval [A, B] to the interval [-1,1], then builds
175
+ least squares approximation using Chebyshev polynomials.
176
+
177
+ Input parameters:
178
+ X - array[0..N-1], abscissas
179
+ Y - array[0..N-1], function values
180
+ W - array[0..N-1], weights
181
+ A, B- interval to build approximating polynomials in.
182
+ N - number of points used. N>=1.
183
+ M - order of polynomial, M>=0. This parameter is passed into
184
+ CalculateChebyshevLeastSquares function.
185
+
186
+ Output parameters:
187
+ CTbl - coefficient table. This parameter is passed into
188
+ CalculateChebyshevLeastSquares function.
189
+ -- ALGLIB --
190
+ Copyright by Bochkanov Sergey
191
+ *************************************************************************/
192
+ void buildchebyshevleastsquares(const ap::real_1d_array& x,
193
+ const ap::real_1d_array& y,
194
+ const ap::real_1d_array& w,
195
+ double a,
196
+ double b,
197
+ int n,
198
+ int m,
199
+ ap::real_1d_array& ctbl);
200
+
201
+
202
+ /*************************************************************************
203
+ Weighted Chebyshev polynomial constrained least squares approximation.
204
+
205
+ The algorithm reduces [A,B] to [-1,1] and builds the Chebyshev polynomials
206
+ series by approximating a given function using the least squares method.
207
+
208
+ Input parameters:
209
+ X - abscissas, array[0..N-1]
210
+ Y - function values, array[0..N-1]
211
+ W - weights, array[0..N-1]. Each item in the squared sum of
212
+ deviations from given values is multiplied by a square of
213
+ corresponding weight.
214
+ A, B- interval in which the approximating polynomials are built.
215
+ N - number of points, N>0.
216
+ XC, YC, DC-
217
+ constraints (see description below)., array[0..NC-1]
218
+ NC - number of constraints. 0 <= NC < M+1.
219
+ M - degree of polynomial, M>=0. This parameter is passed into the
220
+ CalculateChebyshevLeastSquares subroutine.
221
+
222
+ Output parameters:
223
+ CTbl- coefficient table. This parameter is passed into the
224
+ CalculateChebyshevLeastSquares subroutine.
225
+
226
+ Result:
227
+ True, if the algorithm succeeded.
228
+ False, if the internal singular value decomposition subroutine hasn't
229
+ converged or the given constraints could not be met simultaneously (e.g.
230
+ P(0)=0 � P(0)=1).
231
+
232
+ Specifying constraints:
233
+ This subroutine can solve the problem having constrained function
234
+ values or its derivatives in several points. NC specifies the number of
235
+ constraints, DC - the type of constraints, XC and YC - constraints as such.
236
+ Thus, for each i from 0 to NC-1 the following constraint is given:
237
+ P(xc[i]) = yc[i], if DC[i]=0
238
+ or
239
+ d/dx(P(xc[i])) = yc[i], if DC[i]=1
240
+ (here P(x) is approximating polynomial).
241
+ This version of the subroutine supports only either polynomial or its
242
+ derivative value constraints. If DC[i] is not equal to 0 and 1, the
243
+ subroutine will be aborted. The number of constraints should be less than
244
+ the number of degrees of freedom of approximating polynomial - M+1 (at
245
+ that, it could be equal to 0).
246
+
247
+ -- ALGLIB --
248
+ Copyright by Bochkanov Sergey
249
+ *************************************************************************/
250
+ bool buildchebyshevleastsquaresconstrained(const ap::real_1d_array& x,
251
+ const ap::real_1d_array& y,
252
+ const ap::real_1d_array& w,
253
+ double a,
254
+ double b,
255
+ int n,
256
+ const ap::real_1d_array& xc,
257
+ const ap::real_1d_array& yc,
258
+ const ap::integer_1d_array& dc,
259
+ int nc,
260
+ int m,
261
+ ap::real_1d_array& ctbl);
262
+
263
+
264
+ /*************************************************************************
265
+ Calculation of a Chebyshev polynomial obtained during least squares
266
+ approximaion at the given point.
267
+
268
+ Input parameters:
269
+ M - order of polynomial (parameter of the
270
+ BuildChebyshevLeastSquares function).
271
+ A - coefficient table.
272
+ A[0..M] contains coefficients of the i-th Chebyshev polynomial.
273
+ A[M+1] contains left boundary of approximation interval.
274
+ A[M+2] contains right boundary of approximation interval.
275
+ X - point to perform calculations in.
276
+
277
+ The result is the value at the given point.
278
+
279
+ It should be noted that array A contains coefficients of the Chebyshev
280
+ polynomials defined on interval [-1,1]. Argument is reduced to this
281
+ interval before calculating polynomial value.
282
+ -- ALGLIB --
283
+ Copyright by Bochkanov Sergey
284
+ *************************************************************************/
285
+ double calculatechebyshevleastsquares(const int& m,
286
+ const ap::real_1d_array& a,
287
+ double x);
288
+
289
+
290
+ #endif
@@ -0,0 +1,107 @@
1
+
2
+ #include <stdafx.h>
3
+ #include "legendre.h"
4
+
5
+ /*************************************************************************
6
+ Calculation of the value of the Legendre polynomial Pn.
7
+
8
+ Parameters:
9
+ n - degree, n>=0
10
+ x - argument
11
+
12
+ Result:
13
+ the value of the Legendre polynomial Pn at x
14
+ *************************************************************************/
15
+ double legendrecalculate(const int& n, const double& x)
16
+ {
17
+ double result;
18
+ double a;
19
+ double b;
20
+ int i;
21
+
22
+ result = 1;
23
+ a = 1;
24
+ b = x;
25
+ if( n==0 )
26
+ {
27
+ result = a;
28
+ return result;
29
+ }
30
+ if( n==1 )
31
+ {
32
+ result = b;
33
+ return result;
34
+ }
35
+ for(i = 2; i <= n; i++)
36
+ {
37
+ result = ((2*i-1)*x*b-(i-1)*a)/i;
38
+ a = b;
39
+ b = result;
40
+ }
41
+ return result;
42
+ }
43
+
44
+
45
+ /*************************************************************************
46
+ Summation of Legendre polynomials using Clenshaw�s recurrence formula.
47
+
48
+ This routine calculates
49
+ c[0]*P0(x) + c[1]*P1(x) + ... + c[N]*PN(x)
50
+
51
+ Parameters:
52
+ n - degree, n>=0
53
+ x - argument
54
+
55
+ Result:
56
+ the value of the Legendre polynomial at x
57
+ *************************************************************************/
58
+ double legendresum(const ap::real_1d_array& c, const int& n, const double& x)
59
+ {
60
+ double result;
61
+ double b1;
62
+ double b2;
63
+ int i;
64
+
65
+ b1 = 0;
66
+ b2 = 0;
67
+ for(i = n; i >= 0; i--)
68
+ {
69
+ result = (2*i+1)*x*b1/(i+1)-(i+1)*b2/(i+2)+c(i);
70
+ b2 = b1;
71
+ b1 = result;
72
+ }
73
+ return result;
74
+ }
75
+
76
+
77
+ /*************************************************************************
78
+ Representation of Pn as C[0] + C[1]*X + ... + C[N]*X^N
79
+
80
+ Input parameters:
81
+ N - polynomial degree, n>=0
82
+
83
+ Output parameters:
84
+ C - coefficients
85
+ *************************************************************************/
86
+ void legendrecoefficients(const int& n, ap::real_1d_array& c)
87
+ {
88
+ int i;
89
+
90
+ c.setbounds(0, n);
91
+ for(i = 0; i <= n; i++)
92
+ {
93
+ c(i) = 0;
94
+ }
95
+ c(n) = 1;
96
+ for(i = 1; i <= n; i++)
97
+ {
98
+ c(n) = c(n)*(n+i)/2/i;
99
+ }
100
+ for(i = 0; i <= n/2-1; i++)
101
+ {
102
+ c(n-2*(i+1)) = -c(n-2*i)*(n-2*i)*(n-2*i-1)/2/(i+1)/(2*(n-i)-1);
103
+ }
104
+ }
105
+
106
+
107
+
@@ -0,0 +1,49 @@
1
+
2
+ #ifndef _legendre_h
3
+ #define _legendre_h
4
+
5
+ #include "ap.h"
6
+ #include "ialglib.h"
7
+
8
+ /*************************************************************************
9
+ Calculation of the value of the Legendre polynomial Pn.
10
+
11
+ Parameters:
12
+ n - degree, n>=0
13
+ x - argument
14
+
15
+ Result:
16
+ the value of the Legendre polynomial Pn at x
17
+ *************************************************************************/
18
+ double legendrecalculate(const int& n, const double& x);
19
+
20
+
21
+ /*************************************************************************
22
+ Summation of Legendre polynomials using Clenshaw�s recurrence formula.
23
+
24
+ This routine calculates
25
+ c[0]*P0(x) + c[1]*P1(x) + ... + c[N]*PN(x)
26
+
27
+ Parameters:
28
+ n - degree, n>=0
29
+ x - argument
30
+
31
+ Result:
32
+ the value of the Legendre polynomial at x
33
+ *************************************************************************/
34
+ double legendresum(const ap::real_1d_array& c, const int& n, const double& x);
35
+
36
+
37
+ /*************************************************************************
38
+ Representation of Pn as C[0] + C[1]*X + ... + C[N]*X^N
39
+
40
+ Input parameters:
41
+ N - polynomial degree, n>=0
42
+
43
+ Output parameters:
44
+ C - coefficients
45
+ *************************************************************************/
46
+ void legendrecoefficients(const int& n, ap::real_1d_array& c);
47
+
48
+
49
+ #endif
@@ -0,0 +1,1185 @@
1
+ /*************************************************************************
2
+ Copyright (c) 2007-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
+ #include <stdafx.h>
34
+ #include "linreg.h"
35
+
36
+ static const int lrvnum = 5;
37
+
38
+ static void lrinternal(const ap::real_2d_array& xy,
39
+ const ap::real_1d_array& s,
40
+ int npoints,
41
+ int nvars,
42
+ int& info,
43
+ linearmodel& lm,
44
+ lrreport& ar);
45
+
46
+ /*************************************************************************
47
+ Linear regression
48
+
49
+ Subroutine builds model:
50
+
51
+ Y = A(0)*X[0] + ... + A(N-1)*X[N-1] + A(N)
52
+
53
+ and model found in ALGLIB format, covariation matrix, training set errors
54
+ (rms, average, average relative) and leave-one-out cross-validation
55
+ estimate of the generalization error. CV estimate calculated using fast
56
+ algorithm with O(NPoints*NVars) complexity.
57
+
58
+ When covariation matrix is calculated standard deviations of function
59
+ values are assumed to be equal to RMS error on the training set.
60
+
61
+ INPUT PARAMETERS:
62
+ XY - training set, array [0..NPoints-1,0..NVars]:
63
+ * NVars columns - independent variables
64
+ * last column - dependent variable
65
+ NPoints - training set size, NPoints>NVars+1
66
+ NVars - number of independent variables
67
+
68
+ OUTPUT PARAMETERS:
69
+ Info - return code:
70
+ * -255, in case of unknown internal error
71
+ * -4, if internal SVD subroutine haven't converged
72
+ * -1, if incorrect parameters was passed (NPoints<NVars+2, NVars<1).
73
+ * 1, if subroutine successfully finished
74
+ LM - linear model in the ALGLIB format. Use subroutines of
75
+ this unit to work with the model.
76
+ AR - additional results
77
+
78
+
79
+ -- ALGLIB --
80
+ Copyright 02.08.2008 by Bochkanov Sergey
81
+ *************************************************************************/
82
+ void lrbuild(const ap::real_2d_array& xy,
83
+ int npoints,
84
+ int nvars,
85
+ int& info,
86
+ linearmodel& lm,
87
+ lrreport& ar)
88
+ {
89
+ ap::real_1d_array s;
90
+ int i;
91
+ double sigma2;
92
+
93
+ if( npoints<=nvars+1||nvars<1 )
94
+ {
95
+ info = -1;
96
+ return;
97
+ }
98
+ s.setbounds(0, npoints-1);
99
+ for(i = 0; i <= npoints-1; i++)
100
+ {
101
+ s(i) = 1;
102
+ }
103
+ lrbuilds(xy, s, npoints, nvars, info, lm, ar);
104
+ if( info<0 )
105
+ {
106
+ return;
107
+ }
108
+ sigma2 = ap::sqr(ar.rmserror)*npoints/(npoints-nvars-1);
109
+ for(i = 0; i <= nvars; i++)
110
+ {
111
+ ap::vmul(&ar.c(i, 0), ap::vlen(0,nvars), sigma2);
112
+ }
113
+ }
114
+
115
+
116
+ /*************************************************************************
117
+ Linear regression
118
+
119
+ Variant of LRBuild which uses vector of standatd deviations (errors in
120
+ function values).
121
+
122
+ INPUT PARAMETERS:
123
+ XY - training set, array [0..NPoints-1,0..NVars]:
124
+ * NVars columns - independent variables
125
+ * last column - dependent variable
126
+ S - standard deviations (errors in function values)
127
+ array[0..NPoints-1], S[i]>0.
128
+ NPoints - training set size, NPoints>NVars+1
129
+ NVars - number of independent variables
130
+
131
+ OUTPUT PARAMETERS:
132
+ Info - return code:
133
+ * -255, in case of unknown internal error
134
+ * -4, if internal SVD subroutine haven't converged
135
+ * -1, if incorrect parameters was passed (NPoints<NVars+2, NVars<1).
136
+ * -2, if S[I]<=0
137
+ * 1, if subroutine successfully finished
138
+ LM - linear model in the ALGLIB format. Use subroutines of
139
+ this unit to work with the model.
140
+ AR - additional results
141
+
142
+
143
+ -- ALGLIB --
144
+ Copyright 02.08.2008 by Bochkanov Sergey
145
+ *************************************************************************/
146
+ void lrbuilds(const ap::real_2d_array& xy,
147
+ const ap::real_1d_array& s,
148
+ int npoints,
149
+ int nvars,
150
+ int& info,
151
+ linearmodel& lm,
152
+ lrreport& ar)
153
+ {
154
+ ap::real_2d_array xyi;
155
+ ap::real_1d_array x;
156
+ ap::real_1d_array means;
157
+ ap::real_1d_array sigmas;
158
+ int i;
159
+ int j;
160
+ double v;
161
+ int offs;
162
+ double mean;
163
+ double variance;
164
+ double skewness;
165
+ double kurtosis;
166
+
167
+
168
+ //
169
+ // Test parameters
170
+ //
171
+ if( npoints<=nvars+1||nvars<1 )
172
+ {
173
+ info = -1;
174
+ return;
175
+ }
176
+
177
+ //
178
+ // Copy data, add one more column (constant term)
179
+ //
180
+ xyi.setbounds(0, npoints-1, 0, nvars+1);
181
+ for(i = 0; i <= npoints-1; i++)
182
+ {
183
+ ap::vmove(&xyi(i, 0), &xy(i, 0), ap::vlen(0,nvars-1));
184
+ xyi(i,nvars) = 1;
185
+ xyi(i,nvars+1) = xy(i,nvars);
186
+ }
187
+
188
+ //
189
+ // Standartization
190
+ //
191
+ x.setbounds(0, npoints-1);
192
+ means.setbounds(0, nvars-1);
193
+ sigmas.setbounds(0, nvars-1);
194
+ for(j = 0; j <= nvars-1; j++)
195
+ {
196
+ ap::vmove(x.getvector(0, npoints-1), xy.getcolumn(j, 0, npoints-1));
197
+ calculatemoments(x, npoints, mean, variance, skewness, kurtosis);
198
+ means(j) = mean;
199
+ sigmas(j) = sqrt(variance);
200
+ if( sigmas(j)==0 )
201
+ {
202
+ sigmas(j) = 1;
203
+ }
204
+ for(i = 0; i <= npoints-1; i++)
205
+ {
206
+ xyi(i,j) = (xyi(i,j)-means(j))/sigmas(j);
207
+ }
208
+ }
209
+
210
+ //
211
+ // Internal processing
212
+ //
213
+ lrinternal(xyi, s, npoints, nvars+1, info, lm, ar);
214
+ if( info<0 )
215
+ {
216
+ return;
217
+ }
218
+
219
+ //
220
+ // Un-standartization
221
+ //
222
+ offs = ap::round(lm.w(3));
223
+ for(j = 0; j <= nvars-1; j++)
224
+ {
225
+
226
+ //
227
+ // Constant term is updated (and its covariance too,
228
+ // since it gets some variance from J-th component)
229
+ //
230
+ lm.w(offs+nvars) = lm.w(offs+nvars)-lm.w(offs+j)*means(j)/sigmas(j);
231
+ v = means(j)/sigmas(j);
232
+ ap::vsub(&ar.c(nvars, 0), &ar.c(j, 0), ap::vlen(0,nvars), v);
233
+ ap::vsub(ar.c.getcolumn(nvars, 0, nvars), ar.c.getcolumn(j, 0, nvars), v);
234
+
235
+ //
236
+ // J-th term is updated
237
+ //
238
+ lm.w(offs+j) = lm.w(offs+j)/sigmas(j);
239
+ v = 1/sigmas(j);
240
+ ap::vmul(&ar.c(j, 0), ap::vlen(0,nvars), v);
241
+ ap::vmul(ar.c.getcolumn(j, 0, nvars), v);
242
+ }
243
+ }
244
+
245
+
246
+ /*************************************************************************
247
+ Like LRBuildS, but builds model
248
+
249
+ Y = A(0)*X[0] + ... + A(N-1)*X[N-1]
250
+
251
+ i.e. with zero constant term.
252
+
253
+ -- ALGLIB --
254
+ Copyright 30.10.2008 by Bochkanov Sergey
255
+ *************************************************************************/
256
+ void lrbuildzs(const ap::real_2d_array& xy,
257
+ const ap::real_1d_array& s,
258
+ int npoints,
259
+ int nvars,
260
+ int& info,
261
+ linearmodel& lm,
262
+ lrreport& ar)
263
+ {
264
+ ap::real_2d_array xyi;
265
+ ap::real_1d_array x;
266
+ ap::real_1d_array c;
267
+ int i;
268
+ int j;
269
+ double v;
270
+ int offs;
271
+ double mean;
272
+ double variance;
273
+ double skewness;
274
+ double kurtosis;
275
+
276
+
277
+ //
278
+ // Test parameters
279
+ //
280
+ if( npoints<=nvars+1||nvars<1 )
281
+ {
282
+ info = -1;
283
+ return;
284
+ }
285
+
286
+ //
287
+ // Copy data, add one more column (constant term)
288
+ //
289
+ xyi.setbounds(0, npoints-1, 0, nvars+1);
290
+ for(i = 0; i <= npoints-1; i++)
291
+ {
292
+ ap::vmove(&xyi(i, 0), &xy(i, 0), ap::vlen(0,nvars-1));
293
+ xyi(i,nvars) = 0;
294
+ xyi(i,nvars+1) = xy(i,nvars);
295
+ }
296
+
297
+ //
298
+ // Standartization: unusual scaling
299
+ //
300
+ x.setbounds(0, npoints-1);
301
+ c.setbounds(0, nvars-1);
302
+ for(j = 0; j <= nvars-1; j++)
303
+ {
304
+ ap::vmove(x.getvector(0, npoints-1), xy.getcolumn(j, 0, npoints-1));
305
+ calculatemoments(x, npoints, mean, variance, skewness, kurtosis);
306
+ if( fabs(mean)>sqrt(variance) )
307
+ {
308
+
309
+ //
310
+ // variation is relatively small, it is better to
311
+ // bring mean value to 1
312
+ //
313
+ c(j) = mean;
314
+ }
315
+ else
316
+ {
317
+
318
+ //
319
+ // variation is large, it is better to bring variance to 1
320
+ //
321
+ if( variance==0 )
322
+ {
323
+ variance = 1;
324
+ }
325
+ c(j) = sqrt(variance);
326
+ }
327
+ for(i = 0; i <= npoints-1; i++)
328
+ {
329
+ xyi(i,j) = xyi(i,j)/c(j);
330
+ }
331
+ }
332
+
333
+ //
334
+ // Internal processing
335
+ //
336
+ lrinternal(xyi, s, npoints, nvars+1, info, lm, ar);
337
+ if( info<0 )
338
+ {
339
+ return;
340
+ }
341
+
342
+ //
343
+ // Un-standartization
344
+ //
345
+ offs = ap::round(lm.w(3));
346
+ for(j = 0; j <= nvars-1; j++)
347
+ {
348
+
349
+ //
350
+ // J-th term is updated
351
+ //
352
+ lm.w(offs+j) = lm.w(offs+j)/c(j);
353
+ v = 1/c(j);
354
+ ap::vmul(&ar.c(j, 0), ap::vlen(0,nvars), v);
355
+ ap::vmul(ar.c.getcolumn(j, 0, nvars), v);
356
+ }
357
+ }
358
+
359
+
360
+ /*************************************************************************
361
+ Like LRBuild but builds model
362
+
363
+ Y = A(0)*X[0] + ... + A(N-1)*X[N-1]
364
+
365
+ i.e. with zero constant term.
366
+
367
+ -- ALGLIB --
368
+ Copyright 30.10.2008 by Bochkanov Sergey
369
+ *************************************************************************/
370
+ void lrbuildz(const ap::real_2d_array& xy,
371
+ int npoints,
372
+ int nvars,
373
+ int& info,
374
+ linearmodel& lm,
375
+ lrreport& ar)
376
+ {
377
+ ap::real_1d_array s;
378
+ int i;
379
+ double sigma2;
380
+
381
+ if( npoints<=nvars+1||nvars<1 )
382
+ {
383
+ info = -1;
384
+ return;
385
+ }
386
+ s.setbounds(0, npoints-1);
387
+ for(i = 0; i <= npoints-1; i++)
388
+ {
389
+ s(i) = 1;
390
+ }
391
+ lrbuildzs(xy, s, npoints, nvars, info, lm, ar);
392
+ if( info<0 )
393
+ {
394
+ return;
395
+ }
396
+ sigma2 = ap::sqr(ar.rmserror)*npoints/(npoints-nvars-1);
397
+ for(i = 0; i <= nvars; i++)
398
+ {
399
+ ap::vmul(&ar.c(i, 0), ap::vlen(0,nvars), sigma2);
400
+ }
401
+ }
402
+
403
+
404
+ /*************************************************************************
405
+ Unpacks coefficients of linear model.
406
+
407
+ INPUT PARAMETERS:
408
+ LM - linear model in ALGLIB format
409
+
410
+ OUTPUT PARAMETERS:
411
+ V - coefficients, array[0..NVars]
412
+ NVars - number of independent variables (one less than number
413
+ of coefficients)
414
+
415
+ -- ALGLIB --
416
+ Copyright 30.08.2008 by Bochkanov Sergey
417
+ *************************************************************************/
418
+ void lrunpack(const linearmodel& lm, ap::real_1d_array& v, int& nvars)
419
+ {
420
+ int offs;
421
+
422
+ ap::ap_error::make_assertion(ap::round(lm.w(1))==lrvnum, "LINREG: Incorrect LINREG version!");
423
+ nvars = ap::round(lm.w(2));
424
+ offs = ap::round(lm.w(3));
425
+ v.setbounds(0, nvars);
426
+ ap::vmove(&v(0), &lm.w(offs), ap::vlen(0,nvars));
427
+ }
428
+
429
+
430
+ /*************************************************************************
431
+ "Packs" coefficients and creates linear model in ALGLIB format (LRUnpack
432
+ reversed).
433
+
434
+ INPUT PARAMETERS:
435
+ V - coefficients, array[0..NVars]
436
+ NVars - number of independent variables
437
+
438
+ OUTPUT PAREMETERS:
439
+ LM - linear model.
440
+
441
+ -- ALGLIB --
442
+ Copyright 30.08.2008 by Bochkanov Sergey
443
+ *************************************************************************/
444
+ void lrpack(const ap::real_1d_array& v, int nvars, linearmodel& lm)
445
+ {
446
+ int offs;
447
+
448
+ lm.w.setbounds(0, 4+nvars);
449
+ offs = 4;
450
+ lm.w(0) = 4+nvars+1;
451
+ lm.w(1) = lrvnum;
452
+ lm.w(2) = nvars;
453
+ lm.w(3) = offs;
454
+ ap::vmove(&lm.w(offs), &v(0), ap::vlen(offs,offs+nvars));
455
+ }
456
+
457
+
458
+ /*************************************************************************
459
+ Procesing
460
+
461
+ INPUT PARAMETERS:
462
+ LM - linear model
463
+ X - input vector, array[0..NVars-1].
464
+
465
+ Result:
466
+ value of linear model regression estimate
467
+
468
+ -- ALGLIB --
469
+ Copyright 03.09.2008 by Bochkanov Sergey
470
+ *************************************************************************/
471
+ double lrprocess(const linearmodel& lm, const ap::real_1d_array& x)
472
+ {
473
+ double result;
474
+ double v;
475
+ int offs;
476
+ int nvars;
477
+
478
+ ap::ap_error::make_assertion(ap::round(lm.w(1))==lrvnum, "LINREG: Incorrect LINREG version!");
479
+ nvars = ap::round(lm.w(2));
480
+ offs = ap::round(lm.w(3));
481
+ v = ap::vdotproduct(&x(0), &lm.w(offs), ap::vlen(0,nvars-1));
482
+ result = v+lm.w(offs+nvars);
483
+ return result;
484
+ }
485
+
486
+
487
+ /*************************************************************************
488
+ RMS error on the test set
489
+
490
+ INPUT PARAMETERS:
491
+ LM - linear model
492
+ XY - test set
493
+ NPoints - test set size
494
+
495
+ RESULT:
496
+ root mean square error.
497
+
498
+ -- ALGLIB --
499
+ Copyright 30.08.2008 by Bochkanov Sergey
500
+ *************************************************************************/
501
+ double lrrmserror(const linearmodel& lm,
502
+ const ap::real_2d_array& xy,
503
+ int npoints)
504
+ {
505
+ double result;
506
+ int i;
507
+ double v;
508
+ int offs;
509
+ int nvars;
510
+
511
+ ap::ap_error::make_assertion(ap::round(lm.w(1))==lrvnum, "LINREG: Incorrect LINREG version!");
512
+ nvars = ap::round(lm.w(2));
513
+ offs = ap::round(lm.w(3));
514
+ result = 0;
515
+ for(i = 0; i <= npoints-1; i++)
516
+ {
517
+ v = ap::vdotproduct(&xy(i, 0), &lm.w(offs), ap::vlen(0,nvars-1));
518
+ v = v+lm.w(offs+nvars);
519
+ result = result+ap::sqr(v-xy(i,nvars));
520
+ }
521
+ result = sqrt(result/npoints);
522
+ return result;
523
+ }
524
+
525
+
526
+ /*************************************************************************
527
+ Average error on the test set
528
+
529
+ INPUT PARAMETERS:
530
+ LM - linear model
531
+ XY - test set
532
+ NPoints - test set size
533
+
534
+ RESULT:
535
+ average error.
536
+
537
+ -- ALGLIB --
538
+ Copyright 30.08.2008 by Bochkanov Sergey
539
+ *************************************************************************/
540
+ double lravgerror(const linearmodel& lm,
541
+ const ap::real_2d_array& xy,
542
+ int npoints)
543
+ {
544
+ double result;
545
+ int i;
546
+ double v;
547
+ int offs;
548
+ int nvars;
549
+
550
+ ap::ap_error::make_assertion(ap::round(lm.w(1))==lrvnum, "LINREG: Incorrect LINREG version!");
551
+ nvars = ap::round(lm.w(2));
552
+ offs = ap::round(lm.w(3));
553
+ result = 0;
554
+ for(i = 0; i <= npoints-1; i++)
555
+ {
556
+ v = ap::vdotproduct(&xy(i, 0), &lm.w(offs), ap::vlen(0,nvars-1));
557
+ v = v+lm.w(offs+nvars);
558
+ result = result+fabs(v-xy(i,nvars));
559
+ }
560
+ result = result/npoints;
561
+ return result;
562
+ }
563
+
564
+
565
+ /*************************************************************************
566
+ RMS error on the test set
567
+
568
+ INPUT PARAMETERS:
569
+ LM - linear model
570
+ XY - test set
571
+ NPoints - test set size
572
+
573
+ RESULT:
574
+ average relative error.
575
+
576
+ -- ALGLIB --
577
+ Copyright 30.08.2008 by Bochkanov Sergey
578
+ *************************************************************************/
579
+ double lravgrelerror(const linearmodel& lm,
580
+ const ap::real_2d_array& xy,
581
+ int npoints)
582
+ {
583
+ double result;
584
+ int i;
585
+ int k;
586
+ double v;
587
+ int offs;
588
+ int nvars;
589
+
590
+ ap::ap_error::make_assertion(ap::round(lm.w(1))==lrvnum, "LINREG: Incorrect LINREG version!");
591
+ nvars = ap::round(lm.w(2));
592
+ offs = ap::round(lm.w(3));
593
+ result = 0;
594
+ k = 0;
595
+ for(i = 0; i <= npoints-1; i++)
596
+ {
597
+ if( xy(i,nvars)!=0 )
598
+ {
599
+ v = ap::vdotproduct(&xy(i, 0), &lm.w(offs), ap::vlen(0,nvars-1));
600
+ v = v+lm.w(offs+nvars);
601
+ result = result+fabs((v-xy(i,nvars))/xy(i,nvars));
602
+ k = k+1;
603
+ }
604
+ }
605
+ if( k!=0 )
606
+ {
607
+ result = result/k;
608
+ }
609
+ return result;
610
+ }
611
+
612
+
613
+ /*************************************************************************
614
+ Copying of LinearModel strucure
615
+
616
+ INPUT PARAMETERS:
617
+ LM1 - original
618
+
619
+ OUTPUT PARAMETERS:
620
+ LM2 - copy
621
+
622
+ -- ALGLIB --
623
+ Copyright 15.03.2009 by Bochkanov Sergey
624
+ *************************************************************************/
625
+ void lrcopy(const linearmodel& lm1, linearmodel& lm2)
626
+ {
627
+ int k;
628
+
629
+ k = ap::round(lm1.w(0));
630
+ lm2.w.setbounds(0, k-1);
631
+ ap::vmove(&lm2.w(0), &lm1.w(0), ap::vlen(0,k-1));
632
+ }
633
+
634
+
635
+ /*************************************************************************
636
+ Serialization of LinearModel strucure
637
+
638
+ INPUT PARAMETERS:
639
+ LM - original
640
+
641
+ OUTPUT PARAMETERS:
642
+ RA - array of real numbers which stores model,
643
+ array[0..RLen-1]
644
+ RLen - RA lenght
645
+
646
+ -- ALGLIB --
647
+ Copyright 15.03.2009 by Bochkanov Sergey
648
+ *************************************************************************/
649
+ void lrserialize(const linearmodel& lm, ap::real_1d_array& ra, int& rlen)
650
+ {
651
+
652
+ rlen = ap::round(lm.w(0))+1;
653
+ ra.setbounds(0, rlen-1);
654
+ ra(0) = lrvnum;
655
+ ap::vmove(&ra(1), &lm.w(0), ap::vlen(1,rlen-1));
656
+ }
657
+
658
+
659
+ /*************************************************************************
660
+ Unserialization of DecisionForest strucure
661
+
662
+ INPUT PARAMETERS:
663
+ RA - real array which stores decision forest
664
+
665
+ OUTPUT PARAMETERS:
666
+ LM - unserialized structure
667
+
668
+ -- ALGLIB --
669
+ Copyright 15.03.2009 by Bochkanov Sergey
670
+ *************************************************************************/
671
+ void lrunserialize(const ap::real_1d_array& ra, linearmodel& lm)
672
+ {
673
+
674
+ ap::ap_error::make_assertion(ap::round(ra(0))==lrvnum, "LRUnserialize: incorrect array!");
675
+ lm.w.setbounds(0, ap::round(ra(1))-1);
676
+ ap::vmove(&lm.w(0), &ra(1), ap::vlen(0,ap::round(ra(1))-1));
677
+ }
678
+
679
+
680
+ /*************************************************************************
681
+ Obsolete subroutine, use LRBuildS
682
+
683
+ -- ALGLIB --
684
+ Copyright 26.04.2008 by Bochkanov Sergey
685
+
686
+ References:
687
+ 1. Numerical Recipes in C, "15.2 Fitting Data to a Straight Line"
688
+ *************************************************************************/
689
+ void lrlines(const ap::real_2d_array& xy,
690
+ const ap::real_1d_array& s,
691
+ int n,
692
+ int& info,
693
+ double& a,
694
+ double& b,
695
+ double& vara,
696
+ double& varb,
697
+ double& covab,
698
+ double& corrab,
699
+ double& p)
700
+ {
701
+ int i;
702
+ double ss;
703
+ double sx;
704
+ double sxx;
705
+ double sy;
706
+ double stt;
707
+ double e1;
708
+ double e2;
709
+ double t;
710
+ double chi2;
711
+
712
+ if( n<2 )
713
+ {
714
+ info = -1;
715
+ return;
716
+ }
717
+ for(i = 0; i <= n-1; i++)
718
+ {
719
+ if( s(i)<=0 )
720
+ {
721
+ info = -2;
722
+ return;
723
+ }
724
+ }
725
+ info = 1;
726
+
727
+ //
728
+ // Calculate S, SX, SY, SXX
729
+ //
730
+ ss = 0;
731
+ sx = 0;
732
+ sy = 0;
733
+ sxx = 0;
734
+ for(i = 0; i <= n-1; i++)
735
+ {
736
+ t = ap::sqr(s(i));
737
+ ss = ss+1/t;
738
+ sx = sx+xy(i,0)/t;
739
+ sy = sy+xy(i,1)/t;
740
+ sxx = sxx+ap::sqr(xy(i,0))/t;
741
+ }
742
+
743
+ //
744
+ // Test for condition number
745
+ //
746
+ t = sqrt(4*ap::sqr(sx)+ap::sqr(ss-sxx));
747
+ e1 = 0.5*(ss+sxx+t);
748
+ e2 = 0.5*(ss+sxx-t);
749
+ if( ap::minreal(e1, e2)<=1000*ap::machineepsilon*ap::maxreal(e1, e2) )
750
+ {
751
+ info = -3;
752
+ return;
753
+ }
754
+
755
+ //
756
+ // Calculate A, B
757
+ //
758
+ a = 0;
759
+ b = 0;
760
+ stt = 0;
761
+ for(i = 0; i <= n-1; i++)
762
+ {
763
+ t = (xy(i,0)-sx/ss)/s(i);
764
+ b = b+t*xy(i,1)/s(i);
765
+ stt = stt+ap::sqr(t);
766
+ }
767
+ b = b/stt;
768
+ a = (sy-sx*b)/ss;
769
+
770
+ //
771
+ // Calculate goodness-of-fit
772
+ //
773
+ if( n>2 )
774
+ {
775
+ chi2 = 0;
776
+ for(i = 0; i <= n-1; i++)
777
+ {
778
+ chi2 = chi2+ap::sqr((xy(i,1)-a-b*xy(i,0))/s(i));
779
+ }
780
+ p = incompletegammac(double(n-2)/double(2), chi2/2);
781
+ }
782
+ else
783
+ {
784
+ p = 1;
785
+ }
786
+
787
+ //
788
+ // Calculate other parameters
789
+ //
790
+ vara = (1+ap::sqr(sx)/(ss*stt))/ss;
791
+ varb = 1/stt;
792
+ covab = -sx/(ss*stt);
793
+ corrab = covab/sqrt(vara*varb);
794
+ }
795
+
796
+
797
+ /*************************************************************************
798
+ Obsolete subroutine, use LRBuild
799
+
800
+ -- ALGLIB --
801
+ Copyright 02.08.2008 by Bochkanov Sergey
802
+ *************************************************************************/
803
+ void lrline(const ap::real_2d_array& xy,
804
+ int n,
805
+ int& info,
806
+ double& a,
807
+ double& b)
808
+ {
809
+ ap::real_1d_array s;
810
+ int i;
811
+ double vara;
812
+ double varb;
813
+ double covab;
814
+ double corrab;
815
+ double p;
816
+
817
+ if( n<2 )
818
+ {
819
+ info = -1;
820
+ return;
821
+ }
822
+ s.setbounds(0, n-1);
823
+ for(i = 0; i <= n-1; i++)
824
+ {
825
+ s(i) = 1;
826
+ }
827
+ lrlines(xy, s, n, info, a, b, vara, varb, covab, corrab, p);
828
+ }
829
+
830
+
831
+ /*************************************************************************
832
+ Internal linear regression subroutine
833
+ *************************************************************************/
834
+ static void lrinternal(const ap::real_2d_array& xy,
835
+ const ap::real_1d_array& s,
836
+ int npoints,
837
+ int nvars,
838
+ int& info,
839
+ linearmodel& lm,
840
+ lrreport& ar)
841
+ {
842
+ ap::real_2d_array a;
843
+ ap::real_2d_array u;
844
+ ap::real_2d_array vt;
845
+ ap::real_2d_array vm;
846
+ ap::real_2d_array xym;
847
+ ap::real_1d_array b;
848
+ ap::real_1d_array sv;
849
+ ap::real_1d_array t;
850
+ ap::real_1d_array svi;
851
+ ap::real_1d_array work;
852
+ int i;
853
+ int j;
854
+ int k;
855
+ int ncv;
856
+ int na;
857
+ int nacv;
858
+ double r;
859
+ double p;
860
+ double epstol;
861
+ lrreport ar2;
862
+ int offs;
863
+ linearmodel tlm;
864
+
865
+ epstol = 1000;
866
+
867
+ //
868
+ // Check for errors in data
869
+ //
870
+ if( npoints<nvars||nvars<1 )
871
+ {
872
+ info = -1;
873
+ return;
874
+ }
875
+ for(i = 0; i <= npoints-1; i++)
876
+ {
877
+ if( s(i)<=0 )
878
+ {
879
+ info = -2;
880
+ return;
881
+ }
882
+ }
883
+ info = 1;
884
+
885
+ //
886
+ // Create design matrix
887
+ //
888
+ a.setbounds(0, npoints-1, 0, nvars-1);
889
+ b.setbounds(0, npoints-1);
890
+ for(i = 0; i <= npoints-1; i++)
891
+ {
892
+ r = 1/s(i);
893
+ ap::vmove(&a(i, 0), &xy(i, 0), ap::vlen(0,nvars-1), r);
894
+ b(i) = xy(i,nvars)/s(i);
895
+ }
896
+
897
+ //
898
+ // Allocate W:
899
+ // W[0] array size
900
+ // W[1] version number, 0
901
+ // W[2] NVars (minus 1, to be compatible with external representation)
902
+ // W[3] coefficients offset
903
+ //
904
+ lm.w.setbounds(0, 4+nvars-1);
905
+ offs = 4;
906
+ lm.w(0) = 4+nvars;
907
+ lm.w(1) = lrvnum;
908
+ lm.w(2) = nvars-1;
909
+ lm.w(3) = offs;
910
+
911
+ //
912
+ // Solve problem using SVD:
913
+ //
914
+ // 0. check for degeneracy (different types)
915
+ // 1. A = U*diag(sv)*V'
916
+ // 2. T = b'*U
917
+ // 3. w = SUM((T[i]/sv[i])*V[..,i])
918
+ // 4. cov(wi,wj) = SUM(Vji*Vjk/sv[i]^2,K=1..M)
919
+ //
920
+ // see $15.4 of "Numerical Recipes in C" for more information
921
+ //
922
+ t.setbounds(0, nvars-1);
923
+ svi.setbounds(0, nvars-1);
924
+ ar.c.setbounds(0, nvars-1, 0, nvars-1);
925
+ vm.setbounds(0, nvars-1, 0, nvars-1);
926
+ if( !rmatrixsvd(a, npoints, nvars, 1, 1, 2, sv, u, vt) )
927
+ {
928
+ info = -4;
929
+ return;
930
+ }
931
+ if( sv(0)<=0 )
932
+ {
933
+
934
+ //
935
+ // Degenerate case: zero design matrix.
936
+ //
937
+ for(i = offs; i <= offs+nvars-1; i++)
938
+ {
939
+ lm.w(i) = 0;
940
+ }
941
+ ar.rmserror = lrrmserror(lm, xy, npoints);
942
+ ar.avgerror = lravgerror(lm, xy, npoints);
943
+ ar.avgrelerror = lravgrelerror(lm, xy, npoints);
944
+ ar.cvrmserror = ar.rmserror;
945
+ ar.cvavgerror = ar.avgerror;
946
+ ar.cvavgrelerror = ar.avgrelerror;
947
+ ar.ncvdefects = 0;
948
+ ar.cvdefects.setbounds(0, nvars-1);
949
+ ar.c.setbounds(0, nvars-1, 0, nvars-1);
950
+ for(i = 0; i <= nvars-1; i++)
951
+ {
952
+ for(j = 0; j <= nvars-1; j++)
953
+ {
954
+ ar.c(i,j) = 0;
955
+ }
956
+ }
957
+ return;
958
+ }
959
+ if( sv(nvars-1)<=epstol*ap::machineepsilon*sv(0) )
960
+ {
961
+
962
+ //
963
+ // Degenerate case, non-zero design matrix.
964
+ //
965
+ // We can leave it and solve task in SVD least squares fashion.
966
+ // Solution and covariance matrix will be obtained correctly,
967
+ // but CV error estimates - will not. It is better to reduce
968
+ // it to non-degenerate task and to obtain correct CV estimates.
969
+ //
970
+ for(k = nvars; k >= 1; k--)
971
+ {
972
+ if( sv(k-1)>epstol*ap::machineepsilon*sv(0) )
973
+ {
974
+
975
+ //
976
+ // Reduce
977
+ //
978
+ xym.setbounds(0, npoints-1, 0, k);
979
+ for(i = 0; i <= npoints-1; i++)
980
+ {
981
+ for(j = 0; j <= k-1; j++)
982
+ {
983
+ r = ap::vdotproduct(&xy(i, 0), &vt(j, 0), ap::vlen(0,nvars-1));
984
+ xym(i,j) = r;
985
+ }
986
+ xym(i,k) = xy(i,nvars);
987
+ }
988
+
989
+ //
990
+ // Solve
991
+ //
992
+ lrinternal(xym, s, npoints, k, info, tlm, ar2);
993
+ if( info!=1 )
994
+ {
995
+ return;
996
+ }
997
+
998
+ //
999
+ // Convert back to un-reduced format
1000
+ //
1001
+ for(j = 0; j <= nvars-1; j++)
1002
+ {
1003
+ lm.w(offs+j) = 0;
1004
+ }
1005
+ for(j = 0; j <= k-1; j++)
1006
+ {
1007
+ r = tlm.w(offs+j);
1008
+ ap::vadd(&lm.w(offs), &vt(j, 0), ap::vlen(offs,offs+nvars-1), r);
1009
+ }
1010
+ ar.rmserror = ar2.rmserror;
1011
+ ar.avgerror = ar2.avgerror;
1012
+ ar.avgrelerror = ar2.avgrelerror;
1013
+ ar.cvrmserror = ar2.cvrmserror;
1014
+ ar.cvavgerror = ar2.cvavgerror;
1015
+ ar.cvavgrelerror = ar2.cvavgrelerror;
1016
+ ar.ncvdefects = ar2.ncvdefects;
1017
+ ar.cvdefects.setbounds(0, nvars-1);
1018
+ for(j = 0; j <= ar.ncvdefects-1; j++)
1019
+ {
1020
+ ar.cvdefects(j) = ar2.cvdefects(j);
1021
+ }
1022
+ ar.c.setbounds(0, nvars-1, 0, nvars-1);
1023
+ work.setbounds(1, nvars);
1024
+ matrixmatrixmultiply(ar2.c, 0, k-1, 0, k-1, false, vt, 0, k-1, 0, nvars-1, false, 1.0, vm, 0, k-1, 0, nvars-1, 0.0, work);
1025
+ matrixmatrixmultiply(vt, 0, k-1, 0, nvars-1, true, vm, 0, k-1, 0, nvars-1, false, 1.0, ar.c, 0, nvars-1, 0, nvars-1, 0.0, work);
1026
+ return;
1027
+ }
1028
+ }
1029
+ info = -255;
1030
+ return;
1031
+ }
1032
+ for(i = 0; i <= nvars-1; i++)
1033
+ {
1034
+ if( sv(i)>epstol*ap::machineepsilon*sv(0) )
1035
+ {
1036
+ svi(i) = 1/sv(i);
1037
+ }
1038
+ else
1039
+ {
1040
+ svi(i) = 0;
1041
+ }
1042
+ }
1043
+ for(i = 0; i <= nvars-1; i++)
1044
+ {
1045
+ t(i) = 0;
1046
+ }
1047
+ for(i = 0; i <= npoints-1; i++)
1048
+ {
1049
+ r = b(i);
1050
+ ap::vadd(&t(0), &u(i, 0), ap::vlen(0,nvars-1), r);
1051
+ }
1052
+ for(i = 0; i <= nvars-1; i++)
1053
+ {
1054
+ lm.w(offs+i) = 0;
1055
+ }
1056
+ for(i = 0; i <= nvars-1; i++)
1057
+ {
1058
+ r = t(i)*svi(i);
1059
+ ap::vadd(&lm.w(offs), &vt(i, 0), ap::vlen(offs,offs+nvars-1), r);
1060
+ }
1061
+ for(j = 0; j <= nvars-1; j++)
1062
+ {
1063
+ r = svi(j);
1064
+ ap::vmove(vm.getcolumn(j, 0, nvars-1), vt.getrow(j, 0, nvars-1), r);
1065
+ }
1066
+ for(i = 0; i <= nvars-1; i++)
1067
+ {
1068
+ for(j = i; j <= nvars-1; j++)
1069
+ {
1070
+ r = ap::vdotproduct(&vm(i, 0), &vm(j, 0), ap::vlen(0,nvars-1));
1071
+ ar.c(i,j) = r;
1072
+ ar.c(j,i) = r;
1073
+ }
1074
+ }
1075
+
1076
+ //
1077
+ // Leave-1-out cross-validation error.
1078
+ //
1079
+ // NOTATIONS:
1080
+ // A design matrix
1081
+ // A*x = b original linear least squares task
1082
+ // U*S*V' SVD of A
1083
+ // ai i-th row of the A
1084
+ // bi i-th element of the b
1085
+ // xf solution of the original LLS task
1086
+ //
1087
+ // Cross-validation error of i-th element from a sample is
1088
+ // calculated using following formula:
1089
+ //
1090
+ // ERRi = ai*xf - (ai*xf-bi*(ui*ui'))/(1-ui*ui') (1)
1091
+ //
1092
+ // This formula can be derived from normal equations of the
1093
+ // original task
1094
+ //
1095
+ // (A'*A)x = A'*b (2)
1096
+ //
1097
+ // by applying modification (zeroing out i-th row of A) to (2):
1098
+ //
1099
+ // (A-ai)'*(A-ai) = (A-ai)'*b
1100
+ //
1101
+ // and using Sherman-Morrison formula for updating matrix inverse
1102
+ //
1103
+ // NOTE 1: b is not zeroed out since it is much simpler and
1104
+ // does not influence final result.
1105
+ //
1106
+ // NOTE 2: some design matrices A have such ui that 1-ui*ui'=0.
1107
+ // Formula (1) can't be applied for such cases and they are skipped
1108
+ // from CV calculation (which distorts resulting CV estimate).
1109
+ // But from the properties of U we can conclude that there can
1110
+ // be no more than NVars such vectors. Usually
1111
+ // NVars << NPoints, so in a normal case it only slightly
1112
+ // influences result.
1113
+ //
1114
+ ncv = 0;
1115
+ na = 0;
1116
+ nacv = 0;
1117
+ ar.rmserror = 0;
1118
+ ar.avgerror = 0;
1119
+ ar.avgrelerror = 0;
1120
+ ar.cvrmserror = 0;
1121
+ ar.cvavgerror = 0;
1122
+ ar.cvavgrelerror = 0;
1123
+ ar.ncvdefects = 0;
1124
+ ar.cvdefects.setbounds(0, nvars-1);
1125
+ for(i = 0; i <= npoints-1; i++)
1126
+ {
1127
+
1128
+ //
1129
+ // Error on a training set
1130
+ //
1131
+ r = ap::vdotproduct(&xy(i, 0), &lm.w(offs), ap::vlen(0,nvars-1));
1132
+ ar.rmserror = ar.rmserror+ap::sqr(r-xy(i,nvars));
1133
+ ar.avgerror = ar.avgerror+fabs(r-xy(i,nvars));
1134
+ if( xy(i,nvars)!=0 )
1135
+ {
1136
+ ar.avgrelerror = ar.avgrelerror+fabs((r-xy(i,nvars))/xy(i,nvars));
1137
+ na = na+1;
1138
+ }
1139
+
1140
+ //
1141
+ // Error using fast leave-one-out cross-validation
1142
+ //
1143
+ p = ap::vdotproduct(&u(i, 0), &u(i, 0), ap::vlen(0,nvars-1));
1144
+ if( p>1-epstol*ap::machineepsilon )
1145
+ {
1146
+ ar.cvdefects(ar.ncvdefects) = i;
1147
+ ar.ncvdefects = ar.ncvdefects+1;
1148
+ continue;
1149
+ }
1150
+ r = s(i)*(r/s(i)-b(i)*p)/(1-p);
1151
+ ar.cvrmserror = ar.cvrmserror+ap::sqr(r-xy(i,nvars));
1152
+ ar.cvavgerror = ar.cvavgerror+fabs(r-xy(i,nvars));
1153
+ if( xy(i,nvars)!=0 )
1154
+ {
1155
+ ar.cvavgrelerror = ar.cvavgrelerror+fabs((r-xy(i,nvars))/xy(i,nvars));
1156
+ nacv = nacv+1;
1157
+ }
1158
+ ncv = ncv+1;
1159
+ }
1160
+ if( ncv==0 )
1161
+ {
1162
+
1163
+ //
1164
+ // Something strange: ALL ui are degenerate.
1165
+ // Unexpected...
1166
+ //
1167
+ info = -255;
1168
+ return;
1169
+ }
1170
+ ar.rmserror = sqrt(ar.rmserror/npoints);
1171
+ ar.avgerror = ar.avgerror/npoints;
1172
+ if( na!=0 )
1173
+ {
1174
+ ar.avgrelerror = ar.avgrelerror/na;
1175
+ }
1176
+ ar.cvrmserror = sqrt(ar.cvrmserror/ncv);
1177
+ ar.cvavgerror = ar.cvavgerror/ncv;
1178
+ if( nacv!=0 )
1179
+ {
1180
+ ar.cvavgrelerror = ar.cvavgrelerror/nacv;
1181
+ }
1182
+ }
1183
+
1184
+
1185
+