1 //static const char* sccsid = "@(#)math_Recipes.cxx 3.2 95/01/10"; // Do not delete this line. Used by sccs.
3 // This preprocessor directive is a kludge to get around
4 // a bug in the Sun Workshop 5.0 compiler, it keeps the
5 // /usr/include/memory.h file from being #included
6 // with an incompatible extern "C" definition of memchr
7 // October 18, 2000 <rboehne@ricardo-us.com>
8 #if __SUNPRO_CC == 0x500
13 #define No_Standard_RangeError
14 #define No_Standard_OutOfRange
15 #define No_Standard_DimensionError
20 #include <math_Recipes.hxx>
22 #include <Standard_Failure.hxx>
23 #include <Standard_NotImplemented.hxx>
25 #include <math_Vector.hxx>
26 #include <math_IntegerVector.hxx>
27 #include <math_Matrix.hxx>
29 static Standard_Real at, bt, ct;
30 #define PYTHAG(a,b) ((at=fabs(a)) > (bt=fabs(b)) ? \
31 (ct=bt/at,at*sqrt(1.0+ct*ct)) : (bt ? (ct=at/bt,bt*sqrt(1.0+ct*ct)) : 0.0))
33 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
36 #define ROTATE(a,i,j,k,l) g=a(i,j);\
38 a(i,j)=g-s*(h+g*tau);\
45 static void EigenSort(math_Vector& d, math_Matrix& v) { // descending order
47 Standard_Integer k, i, j;
49 Standard_Integer n = d.Length();
51 for(i = 1; i < n; i++) {
53 for(j = i + 1; j <= n; j++)
54 if(d(j) >= p) p = d(k = j);
58 for(j = 1; j <= n; j++) {
67 Standard_Integer Jacobi(math_Matrix& a, math_Vector& d, math_Matrix& v, Standard_Integer& nrot) {
69 Standard_Integer n = a.RowNumber();
70 Standard_Integer j, iq, ip, i;
71 Standard_Real tresh, theta, tau, t, sm, s, h, g, c;
75 for(ip = 1; ip <= n; ip++) {
76 for(iq = 1; iq <= n; iq++)
80 for(ip = 1; ip <= n; ip++) {
81 b(ip) = d(ip) = a(ip, ip);
85 for(i = 1; i <= 50; i++) {
87 for(ip = 1; ip < n; ip++) {
88 for(iq = ip + 1; iq <= n; iq++)
89 sm += fabs(a(ip, iq));
93 return math_Status_OK;
96 tresh = 0.2 * sm / (n * n);
101 for(ip = 1; ip < n; ip++) {
102 for(iq = ip + 1; iq <= n; iq++) {
103 g = 100.0 * fabs(a(ip, iq));
105 fabs(d(ip)) + g == fabs(d(ip)) &&
106 fabs(d(iq)) + g == fabs(d(iq))) a(ip, iq) = 0.0;
107 else if(fabs(a(ip, iq)) > tresh) {
109 if(fabs(h) + g == fabs(h))
112 theta = 0.5 * h / a(ip, iq);
113 t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
114 if(theta < 0.0) t = -t;
116 c = 1.0 / sqrt(1 + t * t);
125 for(j = 1; j < ip; j++) {
126 ROTATE(a, j, ip, j, iq)
128 for(j = ip + 1; j < iq; j++) {
129 ROTATE(a, ip, j, j, iq)
131 for(j = iq + 1; j <= n; j++) {
132 ROTATE(a, ip, j, iq, j)
134 for(j = 1; j <= n; j++) {
135 ROTATE(v, j, ip, j, iq)
141 for(ip = 1; ip <= n; ip++) {
148 return math_Status_NoConvergence;
151 Standard_Integer LU_Decompose(math_Matrix& a,
152 math_IntegerVector& indx,
155 Standard_Real TINY) {
157 Standard_Integer i, imax=0, j, k;
158 Standard_Real big, dum, sum, temp;
160 Standard_Integer n = a.RowNumber();
163 for(i = 1; i <= n; i++) {
165 for (j = 1; j <= n; j++)
166 if((temp = fabs(a(i, j))) > big) big = temp;
168 return math_Status_SingularMatrix;
172 for(j = 1; j <= n; j++) {
173 for(i = 1; i < j; i++) {
175 for(k = 1; k < i; k++)
176 sum -= a(i,k) * a(k,j);
180 for(i = j; i <= n; i++) {
182 for(k = 1; k < j; k++)
183 sum -= a(i,k) * a(k,j);
185 if((dum = vv(i) * fabs(sum)) >= big) {
191 for(k = 1; k <= n; k++) {
200 if(fabs(a(j, j)) <= TINY) {
201 return math_Status_SingularMatrix;
204 dum = 1.0 / (a(j,j));
205 for(i = j + 1; i <= n; i++)
209 return math_Status_OK;
212 Standard_Integer LU_Decompose(math_Matrix& a,
213 math_IntegerVector& indx,
215 Standard_Real TINY) {
217 math_Vector vv(1, a.RowNumber());
218 return LU_Decompose(a, indx, d, vv, TINY);
221 void LU_Solve(const math_Matrix& a,
222 const math_IntegerVector& indx,
225 Standard_Integer i, ii = 0, ip, j;
228 Standard_Integer n=a.RowNumber();
229 Standard_Integer nblow=b.Lower()-1;
230 for(i = 1; i <= n; i++) {
233 b(ip+nblow) = b(i+nblow);
235 for(j = ii; j < i; j++)
236 sum -= a(i,j) * b(j+nblow);
240 for(i = n; i >= 1; i--) {
242 for(j = i + 1; j <= n; j++)
243 sum -= a(i,j) * b(j+nblow);
244 b(i+nblow) = sum / a(i,i);
248 Standard_Integer LU_Invert(math_Matrix& a) {
250 Standard_Integer n=a.RowNumber();
251 math_Matrix inv(1, n, 1, n);
252 math_Vector col(1, n);
253 math_IntegerVector indx(1, n);
255 Standard_Integer i, j;
257 Standard_Integer Error = LU_Decompose(a, indx, d);
259 for(j = 1; j <= n; j++) {
260 for(i = 1; i <= n; i++)
263 LU_Solve(a, indx, col);
264 for(i = 1; i <= n; i++)
267 for(j = 1; j <= n; j++) {
268 for(i = 1; i <= n; i++) {
277 Standard_Integer SVD_Decompose(math_Matrix& a,
281 math_Vector rv1(1, a.ColNumber());
282 return SVD_Decompose(a, w, v, rv1);
286 Standard_Integer SVD_Decompose(math_Matrix& a,
291 Standard_Integer flag, i, its, j, jj, k, l=0, nm=0;
292 Standard_Real ar, aw, aik, aki, c, f, h, s, x, y, z;
293 Standard_Real anorm = 0.0, g = 0.0, scale = 0.0;
294 Standard_Integer m = a.RowNumber();
295 Standard_Integer n = a.ColNumber();
297 for(i = 1; i <= n; i++) {
302 for(k = i; k <= m; k++) {
304 if (aki > 0) scale += aki;
308 for(k = i; k <= m; k++) {
310 s += a(k,i) * a(k,i);
313 g = -SIGN(sqrt(s), f);
317 for(j = l; j <= n; j++) {
318 for(s = 0.0, k = i; k <= m; k++)
319 s += a(k,i) * a(k,j);
321 for(k = i; k <= m; k++)
322 a(k,j) += f * a(k,i);
325 for(k = i; k <= m; k++)
331 if(i <= m && i != n) {
332 for(k = l; k <= n; k++) {
334 if (aik > 0) scale += aik;
338 for(k = l; k <= n; k++) {
340 s += a(i,k) * a(i,k);
343 g = -SIGN(sqrt(s), f);
346 for (k = l; k <= n; k++)
349 for(j = l; j <=m; j++) {
350 for(s = 0.0, k = l; k <= n; k++)
351 s += a(j,k) * a(i,k);
352 for(k = l; k <=n; k++)
353 a(j,k) += s * rv1(k);
356 for (k = l; k <= n; k++)
361 if (aw < 0) aw = - aw;
363 if (ar > 0) ar = aw + ar;
365 if (anorm < ar) anorm = ar;
367 for(i = n; i >= 1; i--) {
370 for(j = l; j <= n; j++)
371 v(j,i) = (a(i,j) / a(i,l)) / g;
372 for(j = l; j <= n; j++) {
373 for(s = 0.0, k = l; k <= n; k++)
374 s += a(i,k) * v(k,j);
375 for(k = l; k <= n; k++)
376 v(k,j) += s * v(k,i);
379 for(j = l; j <= n; j++)
380 v(i,j) = v(j,i) = 0.0;
386 for(i = n; i >= 1; i--) {
389 if(i < n) for(j = l; j <= n; j++)
394 for(j = l; j <= n; j++) {
395 for(s = 0.0, k = l; k <= m; k++)
396 s += a(k,i) * a(k,j);
397 f = (s / a(i,i)) * g;
398 for(k = i; k <= m; k++)
399 a(k,j) += f * a(k,i);
402 for(j = i; j <= m; j++)
406 for(j = i; j <= m; j++)
411 for(k = n; k >= 1; k--) {
412 for(its = 1; its <= 30; its++) {
414 for(l = k; l >= 1; l--) {
416 if(fabs(rv1(l)) + anorm == anorm) {
420 if(fabs(w(nm)) + anorm == anorm) break;
425 for(i = l; i <= k; i++) {
427 if(fabs(f) + anorm != anorm) {
434 for(j = 1; j <= m; j++) {
437 a(j,nm) = y * c + z * s;
438 a(j,i) = z * c - y * s;
447 for(j = 1; j <= n; j++)
453 return math_Status_NoConvergence;
460 f = ((y - z) * (y + z) + (g - h) * (g + h)) / ( 2.0 * h * y);
462 f = ((x - z) * (x + z) + h * ((y / ( f + SIGN(g, f))) - h)) / x;
465 for(j = l; j <= nm; j++) {
479 for(jj = 1; jj <= n; jj++) {
482 v(jj,j) = x * c + z * s;
483 v(jj,i) = z * c - x * s;
492 f = (c * g) + (s * y);
493 x = (c * y) - (s * g);
494 for(jj = 1; jj <= m; jj++) {
497 a(jj,j) = y * c + z * s;
498 a(jj,i) = z * c - y * s;
506 return math_Status_OK;
509 void SVD_Solve(const math_Matrix& u,
510 const math_Vector& w,
511 const math_Matrix& v,
512 const math_Vector& b,
515 Standard_Integer jj, j, i;
518 Standard_Integer m = u.RowNumber();
519 Standard_Integer n = u.ColNumber();
520 math_Vector tmp(1, n);
522 for(j = 1; j <= n; j++) {
525 for(i = 1; i <= m; i++)
531 for(j = 1; j <= n; j++) {
533 for(jj = 1; jj <= n; jj++)
534 s += v(j,jj) * tmp(jj);
539 Standard_Real Random2(Standard_Integer& idum) {
541 static Standard_Integer iy, ir[98];
542 static Standard_Integer iff = 0;
546 if(idum < 0 || iff == 0) {
548 if((idum = (IC - idum) % M) < 0) idum = -idum;
549 for(j = 1; j <= 97; j++) {
550 idum = (IA * idum + IC) % M;
553 idum = (IA * idum + IC) % M;
556 j = (Standard_Integer)(1 + 97.0 * iy / M);
557 if(j > 97 || j < 1) Standard_Failure::Raise();
559 idum = (IA * idum + IC) % M;
561 return Standard_Real(iy) / Standard_Real(M);
566 Standard_Integer DACTCL_Decompose(math_Vector& a,
567 const math_IntegerVector& indx,
568 const Standard_Real MinPivot) {
570 Standard_Integer i, j, Neq = indx.Length();
571 Standard_Integer jr, jd, jh, is, ie, k, ir, id, ih, mh;
572 Standard_Integer idot, idot1, idot2;
573 Standard_Real aa, d, dot;
574 Standard_Boolean diag;
577 for (j = 1; j <= Neq; j++) {
578 diag = Standard_False;
582 if (jh-2 == 0) diag = Standard_True;
587 // Reduction des coefficients non diagonaux:
588 // =========================================
589 for (i = is; i <= ie; i++) {
594 if (ih > mh) ih = mh;
599 for (idot = 1; idot <= ih; idot++) {
600 dot = dot +a(idot1+idot)*a(idot2+idot);
606 diag = Standard_True;
610 // Reduction des coefficients diagonaux:
611 // =====================================
615 for (i = ir; i <= ie; i++) {
618 if (aa < 0) aa = - aa;
620 return math_Status_SingularMatrix;
623 a(jd) = a(jd)-d*a(i);
629 return math_Status_OK;
633 Standard_Integer DACTCL_Solve(const math_Vector& a,
635 const math_IntegerVector& indx,
636 const Standard_Real MinPivot) {
638 Standard_Integer i, j, Neq = indx.Length();
639 Standard_Integer jr, jd, jh, is, k, id;
640 Standard_Integer jh1, idot, idot1, idot2;
641 Standard_Real aa, d, dot;
642 Standard_Boolean diag;
645 for (j = 1; j <= Neq; j++) {
646 diag = Standard_False;
651 // Reduction du second membre:
652 // ===========================
657 for (idot = 1; idot <= jh1; idot++) {
658 dot = dot + a(idot1+idot)*b(idot2+idot);
665 // Division par les pivots diagonaux:
666 // ==================================
667 for (i = 1; i <= Neq; i++) {
670 if (aa < 0) aa = - aa;
672 return math_Status_SingularMatrix;
677 // Substitution arriere:
678 // =====================
680 for (j = Neq-1; j > 0; j--) {
686 for (i = is; i <= j; i++) {
687 b(i) = b(i)-a(i+k)*d;
692 return math_Status_OK;