mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-26 10:19:45 +03:00
693 lines
17 KiB
C++
693 lines
17 KiB
C++
// Copyright (c) 1997-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
// This preprocessor directive is a kludge to get around
|
|
// a bug in the Sun Workshop 5.0 compiler, it keeps the
|
|
// /usr/include/memory.h file from being #included
|
|
// with an incompatible extern "C" definition of memchr
|
|
// October 18, 2000 <rboehne@ricardo-us.com>
|
|
#if __SUNPRO_CC == 0x500
|
|
#define _MEMORY_H
|
|
#endif
|
|
|
|
//#ifndef OCCT_DEBUG
|
|
#define No_Standard_RangeError
|
|
#define No_Standard_OutOfRange
|
|
#define No_Standard_DimensionError
|
|
//#endif
|
|
|
|
#include <cmath>
|
|
|
|
#include <math_Recipes.hxx>
|
|
|
|
#include <Standard_Failure.hxx>
|
|
#include <Standard_NotImplemented.hxx>
|
|
|
|
#include <math_Vector.hxx>
|
|
#include <math_IntegerVector.hxx>
|
|
#include <math_Matrix.hxx>
|
|
|
|
namespace {
|
|
static inline Standard_Real PYTHAG (const Standard_Real a, const Standard_Real b)
|
|
{
|
|
Standard_Real at = fabs (a), bt = fabs (b), ct = 0.;
|
|
if (at > bt) {
|
|
ct = bt / at;
|
|
ct = at * sqrt (1.0 + ct * ct);
|
|
} else if (bt) {
|
|
ct = at / bt;
|
|
ct = bt * sqrt (1.0 + ct * ct);
|
|
}
|
|
return ct;
|
|
}
|
|
}
|
|
|
|
#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
|
|
|
|
|
|
#define ROTATE(a,i,j,k,l) g=a(i,j);\
|
|
h=a(k,l);\
|
|
a(i,j)=g-s*(h+g*tau);\
|
|
a(k,l)=h+s*(g-h*tau);
|
|
|
|
#define M 714025
|
|
#define IA 1366
|
|
#define IC 150889
|
|
|
|
static void EigenSort(math_Vector& d, math_Matrix& v) { // descending order
|
|
|
|
Standard_Integer k, i, j;
|
|
Standard_Real p;
|
|
Standard_Integer n = d.Length();
|
|
|
|
for(i = 1; i < n; i++) {
|
|
p = d(k = i);
|
|
for(j = i + 1; j <= n; j++)
|
|
if(d(j) >= p) p = d(k = j);
|
|
if(k != i) {
|
|
d(k) = d(i);
|
|
d(i) = p;
|
|
for(j = 1; j <= n; j++) {
|
|
p = v(j, i);
|
|
v(j, i) = v(j, k);
|
|
v(j, k) = p;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Standard_Integer Jacobi(math_Matrix& a, math_Vector& d, math_Matrix& v, Standard_Integer& nrot) {
|
|
|
|
Standard_Integer n = a.RowNumber();
|
|
Standard_Integer j, iq, ip, i;
|
|
Standard_Real tresh, theta, tau, t, sm, s, h, g, c;
|
|
math_Vector b(1, n);
|
|
math_Vector z(1, n);
|
|
|
|
for(ip = 1; ip <= n; ip++) {
|
|
for(iq = 1; iq <= n; iq++)
|
|
v(ip, iq) = 0.0;
|
|
v(ip, ip) = 1.0;
|
|
}
|
|
for(ip = 1; ip <= n; ip++) {
|
|
b(ip) = d(ip) = a(ip, ip);
|
|
z(ip) = 0.0;
|
|
}
|
|
nrot = 0;
|
|
for(i = 1; i <= 50; i++) {
|
|
sm = 0.0;
|
|
for(ip = 1; ip < n; ip++) {
|
|
for(iq = ip + 1; iq <= n; iq++)
|
|
sm += fabs(a(ip, iq));
|
|
}
|
|
if(sm == 0.0) {
|
|
EigenSort(d, v);
|
|
return math_Status_OK;
|
|
}
|
|
if(i < 4) {
|
|
tresh = 0.2 * sm / (n * n);
|
|
}
|
|
else {
|
|
tresh = 0.0;
|
|
}
|
|
for(ip = 1; ip < n; ip++) {
|
|
for(iq = ip + 1; iq <= n; iq++) {
|
|
g = 100.0 * fabs(a(ip, iq));
|
|
if(i > 4 &&
|
|
fabs(d(ip)) + g == fabs(d(ip)) &&
|
|
fabs(d(iq)) + g == fabs(d(iq))) a(ip, iq) = 0.0;
|
|
else if(fabs(a(ip, iq)) > tresh) {
|
|
h = d(iq) - d(ip);
|
|
if(fabs(h) + g == fabs(h))
|
|
t = a(ip, iq) / h;
|
|
else {
|
|
theta = 0.5 * h / a(ip, iq);
|
|
t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
|
|
if(theta < 0.0) t = -t;
|
|
}
|
|
c = 1.0 / sqrt(1 + t * t);
|
|
s = t * c;
|
|
tau = s / (1.0 + c);
|
|
h = t * a(ip, iq);
|
|
z(ip) -= h;
|
|
z(iq) += h;
|
|
d(ip) -= h;
|
|
d(iq) += h;
|
|
a(ip, iq) = 0.0;
|
|
for(j = 1; j < ip; j++) {
|
|
ROTATE(a, j, ip, j, iq)
|
|
}
|
|
for(j = ip + 1; j < iq; j++) {
|
|
ROTATE(a, ip, j, j, iq)
|
|
}
|
|
for(j = iq + 1; j <= n; j++) {
|
|
ROTATE(a, ip, j, iq, j)
|
|
}
|
|
for(j = 1; j <= n; j++) {
|
|
ROTATE(v, j, ip, j, iq)
|
|
}
|
|
nrot++;
|
|
}
|
|
}
|
|
}
|
|
for(ip = 1; ip <= n; ip++) {
|
|
b(ip) += z(ip);
|
|
d(ip) = b(ip);
|
|
z(ip) = 0.0;
|
|
}
|
|
}
|
|
EigenSort(d, v);
|
|
return math_Status_NoConvergence;
|
|
}
|
|
|
|
Standard_Integer LU_Decompose(math_Matrix& a,
|
|
math_IntegerVector& indx,
|
|
Standard_Real& d,
|
|
math_Vector& vv,
|
|
Standard_Real TINY) {
|
|
|
|
Standard_Integer i, imax=0, j, k;
|
|
Standard_Real big, dum, sum, temp;
|
|
|
|
Standard_Integer n = a.RowNumber();
|
|
d = 1.0;
|
|
|
|
for(i = 1; i <= n; i++) {
|
|
big = 0.0;
|
|
for (j = 1; j <= n; j++)
|
|
if((temp = fabs(a(i, j))) > big) big = temp;
|
|
if(big <= TINY) {
|
|
return math_Status_SingularMatrix;
|
|
}
|
|
vv(i) = 1.0 / big;
|
|
}
|
|
for(j = 1; j <= n; j++) {
|
|
for(i = 1; i < j; i++) {
|
|
sum = a(i,j);
|
|
for(k = 1; k < i; k++)
|
|
sum -= a(i,k) * a(k,j);
|
|
a(i,j) = sum;
|
|
}
|
|
big = 0.0;
|
|
for(i = j; i <= n; i++) {
|
|
sum = a(i,j);
|
|
for(k = 1; k < j; k++)
|
|
sum -= a(i,k) * a(k,j);
|
|
a(i,j) = sum;
|
|
// Note that comparison is made so as to have imax updated even if argument is NAN, Inf or IND, see #25559
|
|
if((dum = vv(i) * fabs(sum)) < big)
|
|
{
|
|
continue;
|
|
}
|
|
big = dum;
|
|
imax = i;
|
|
}
|
|
if(j != imax) {
|
|
for(k = 1; k <= n; k++) {
|
|
dum = a(imax,k);
|
|
a(imax,k) = a(j,k);
|
|
a(j,k) = dum;
|
|
}
|
|
d = -d;
|
|
vv(imax) = vv(j);
|
|
}
|
|
indx(j) = imax;
|
|
if(fabs(a(j, j)) <= TINY) {
|
|
return math_Status_SingularMatrix;
|
|
}
|
|
if(j != n) {
|
|
dum = 1.0 / (a(j,j));
|
|
for(i = j + 1; i <= n; i++)
|
|
a(i,j) *= dum;
|
|
}
|
|
}
|
|
return math_Status_OK;
|
|
}
|
|
|
|
Standard_Integer LU_Decompose(math_Matrix& a,
|
|
math_IntegerVector& indx,
|
|
Standard_Real& d,
|
|
Standard_Real TINY) {
|
|
|
|
math_Vector vv(1, a.RowNumber());
|
|
return LU_Decompose(a, indx, d, vv, TINY);
|
|
}
|
|
|
|
void LU_Solve(const math_Matrix& a,
|
|
const math_IntegerVector& indx,
|
|
math_Vector& b) {
|
|
|
|
Standard_Integer i, ii = 0, ip, j;
|
|
Standard_Real sum;
|
|
|
|
Standard_Integer n=a.RowNumber();
|
|
Standard_Integer nblow=b.Lower()-1;
|
|
for(i = 1; i <= n; i++) {
|
|
ip = indx(i);
|
|
sum = b(ip+nblow);
|
|
b(ip+nblow) = b(i+nblow);
|
|
if(ii)
|
|
for(j = ii; j < i; j++)
|
|
sum -= a(i,j) * b(j+nblow);
|
|
else if(sum) ii = i;
|
|
b(i+nblow) = sum;
|
|
}
|
|
for(i = n; i >= 1; i--) {
|
|
sum = b(i+nblow);
|
|
for(j = i + 1; j <= n; j++)
|
|
sum -= a(i,j) * b(j+nblow);
|
|
b(i+nblow) = sum / a(i,i);
|
|
}
|
|
}
|
|
|
|
Standard_Integer LU_Invert(math_Matrix& a) {
|
|
|
|
Standard_Integer n=a.RowNumber();
|
|
math_Matrix inv(1, n, 1, n);
|
|
math_Vector col(1, n);
|
|
math_IntegerVector indx(1, n);
|
|
Standard_Real d;
|
|
Standard_Integer i, j;
|
|
|
|
Standard_Integer Error = LU_Decompose(a, indx, d);
|
|
if(!Error) {
|
|
for(j = 1; j <= n; j++) {
|
|
for(i = 1; i <= n; i++)
|
|
col(i) = 0.0;
|
|
col(j) = 1.0;
|
|
LU_Solve(a, indx, col);
|
|
for(i = 1; i <= n; i++)
|
|
inv(i,j) = col(i);
|
|
}
|
|
for(j = 1; j <= n; j++) {
|
|
for(i = 1; i <= n; i++) {
|
|
a(i,j) = inv(i,j);
|
|
}
|
|
}
|
|
}
|
|
|
|
return Error;
|
|
}
|
|
|
|
Standard_Integer SVD_Decompose(math_Matrix& a,
|
|
math_Vector& w,
|
|
math_Matrix& v) {
|
|
|
|
math_Vector rv1(1, a.ColNumber());
|
|
return SVD_Decompose(a, w, v, rv1);
|
|
}
|
|
|
|
|
|
Standard_Integer SVD_Decompose(math_Matrix& a,
|
|
math_Vector& w,
|
|
math_Matrix& v,
|
|
math_Vector& rv1) {
|
|
|
|
Standard_Integer flag, i, its, j, jj, k, l=0, nm=0;
|
|
Standard_Real ar, aw, aik, aki, c, f, h, s, x, y, z;
|
|
Standard_Real anorm = 0.0, g = 0.0, scale = 0.0;
|
|
Standard_Integer m = a.RowNumber();
|
|
Standard_Integer n = a.ColNumber();
|
|
|
|
for(i = 1; i <= n; i++) {
|
|
l = i + 1;
|
|
rv1(i) = scale * g;
|
|
g = s = scale = 0.0;
|
|
if(i <= m) {
|
|
for(k = i; k <= m; k++) {
|
|
aki = a(k,i);
|
|
if (aki > 0) scale += aki;
|
|
else scale -= aki;
|
|
}
|
|
if(scale) {
|
|
for(k = i; k <= m; k++) {
|
|
a(k,i) /= scale;
|
|
s += a(k,i) * a(k,i);
|
|
}
|
|
f = a(i,i);
|
|
g = -SIGN(sqrt(s), f);
|
|
h = f * g - s;
|
|
a(i,i) = f - g;
|
|
if(i != n) {
|
|
for(j = l; j <= n; j++) {
|
|
for(s = 0.0, k = i; k <= m; k++)
|
|
s += a(k,i) * a(k,j);
|
|
f = s / h;
|
|
for(k = i; k <= m; k++)
|
|
a(k,j) += f * a(k,i);
|
|
}
|
|
}
|
|
for(k = i; k <= m; k++)
|
|
a(k,i) *= scale;
|
|
}
|
|
}
|
|
w(i) = scale * g;
|
|
g = s = scale = 0.0;
|
|
if(i <= m && i != n) {
|
|
for(k = l; k <= n; k++) {
|
|
aik = a(i,k);
|
|
if (aik > 0) scale += aik;
|
|
else scale -= aik;
|
|
}
|
|
if(scale) {
|
|
for(k = l; k <= n; k++) {
|
|
a(i,k) /= scale;
|
|
s += a(i,k) * a(i,k);
|
|
}
|
|
f = a(i,l);
|
|
g = -SIGN(sqrt(s), f);
|
|
h = f * g - s;
|
|
a(i,l) = f - g;
|
|
for (k = l; k <= n; k++)
|
|
rv1(k) = a(i,k) / h;
|
|
if(i != m) {
|
|
for(j = l; j <=m; j++) {
|
|
for(s = 0.0, k = l; k <= n; k++)
|
|
s += a(j,k) * a(i,k);
|
|
for(k = l; k <=n; k++)
|
|
a(j,k) += s * rv1(k);
|
|
}
|
|
}
|
|
for (k = l; k <= n; k++)
|
|
a(i,k) *= scale;
|
|
}
|
|
}
|
|
aw = w(i);
|
|
if (aw < 0) aw = - aw;
|
|
ar = rv1(i);
|
|
if (ar > 0) ar = aw + ar;
|
|
else ar = aw - ar;
|
|
if (anorm < ar) anorm = ar;
|
|
}
|
|
for(i = n; i >= 1; i--) {
|
|
if(i < n) {
|
|
if(g) {
|
|
for(j = l; j <= n; j++)
|
|
v(j,i) = (a(i,j) / a(i,l)) / g;
|
|
for(j = l; j <= n; j++) {
|
|
for(s = 0.0, k = l; k <= n; k++)
|
|
s += a(i,k) * v(k,j);
|
|
for(k = l; k <= n; k++)
|
|
v(k,j) += s * v(k,i);
|
|
}
|
|
}
|
|
for(j = l; j <= n; j++)
|
|
v(i,j) = v(j,i) = 0.0;
|
|
}
|
|
v(i,i) = 1.0;
|
|
g = rv1(i);
|
|
l = i;
|
|
}
|
|
for(i = n; i >= 1; i--) {
|
|
l = i + 1;
|
|
g = w(i);
|
|
if(i < n) for(j = l; j <= n; j++)
|
|
a(i,j) = 0.0;
|
|
if(g) {
|
|
g = 1.0 / g;
|
|
if(i != n) {
|
|
for(j = l; j <= n; j++) {
|
|
for(s = 0.0, k = l; k <= m; k++)
|
|
s += a(k,i) * a(k,j);
|
|
f = (s / a(i,i)) * g;
|
|
for(k = i; k <= m; k++)
|
|
a(k,j) += f * a(k,i);
|
|
}
|
|
}
|
|
for(j = i; j <= m; j++)
|
|
a(j,i) *= g;
|
|
}
|
|
else {
|
|
for(j = i; j <= m; j++)
|
|
a(j,i) = 0.0;
|
|
}
|
|
++a(i,i);
|
|
}
|
|
for(k = n; k >= 1; k--) {
|
|
for(its = 1; its <= 30; its++) {
|
|
flag = 1;
|
|
for(l = k; l >= 1; l--) {
|
|
nm = l - 1;
|
|
if(fabs(rv1(l)) + anorm == anorm) {
|
|
flag = 0;
|
|
break;
|
|
}
|
|
if(fabs(w(nm)) + anorm == anorm) break;
|
|
}
|
|
if(flag) {
|
|
c = 0.0;
|
|
s = 1.0;
|
|
for(i = l; i <= k; i++) {
|
|
f = s * rv1(i);
|
|
if(fabs(f) + anorm != anorm) {
|
|
g = w(i);
|
|
h = PYTHAG(f, g);
|
|
w(i) = h;
|
|
h = 1.0 / h;
|
|
c = g * h;
|
|
s = (-f * h);
|
|
for(j = 1; j <= m; j++) {
|
|
y = a(j,nm);
|
|
z = a(j,i);
|
|
a(j,nm) = y * c + z * s;
|
|
a(j,i) = z * c - y * s;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
z = w(k);
|
|
if(l == k) {
|
|
if(z < 0.0) {
|
|
w(k) = -z;
|
|
for(j = 1; j <= n; j++)
|
|
v(j,k) = (-v(j,k));
|
|
}
|
|
break;
|
|
}
|
|
if(its == 30) {
|
|
return math_Status_NoConvergence;
|
|
}
|
|
x = w(l);
|
|
nm = k - 1;
|
|
y = w(nm);
|
|
g = rv1(nm);
|
|
h = rv1(k);
|
|
f = ((y - z) * (y + z) + (g - h) * (g + h)) / ( 2.0 * h * y);
|
|
g = PYTHAG(f, 1.0);
|
|
f = ((x - z) * (x + z) + h * ((y / ( f + SIGN(g, f))) - h)) / x;
|
|
|
|
c = s = 1.0;
|
|
for(j = l; j <= nm; j++) {
|
|
i = j + 1;
|
|
g = rv1(i);
|
|
y = w(i);
|
|
h = s * g;
|
|
g = c * g;
|
|
z = PYTHAG(f, h);
|
|
rv1(j) = z;
|
|
c = f / z;
|
|
s = h / z;
|
|
f = x * c + g * s;
|
|
g = g * c - x * s;
|
|
h = y * s;
|
|
y = y * c;
|
|
for(jj = 1; jj <= n; jj++) {
|
|
x = v(jj,j);
|
|
z = v(jj,i);
|
|
v(jj,j) = x * c + z * s;
|
|
v(jj,i) = z * c - x * s;
|
|
}
|
|
z = PYTHAG(f, h);
|
|
w(j) = z;
|
|
if(z) {
|
|
z = 1.0 / z;
|
|
c = f * z;
|
|
s = h * z;
|
|
}
|
|
f = (c * g) + (s * y);
|
|
x = (c * y) - (s * g);
|
|
for(jj = 1; jj <= m; jj++) {
|
|
y = a(jj,j);
|
|
z = a(jj,i);
|
|
a(jj,j) = y * c + z * s;
|
|
a(jj,i) = z * c - y * s;
|
|
}
|
|
}
|
|
rv1(l) = 0.0;
|
|
rv1(k) = f;
|
|
w(k) = x;
|
|
}
|
|
}
|
|
return math_Status_OK;
|
|
}
|
|
|
|
void SVD_Solve(const math_Matrix& u,
|
|
const math_Vector& w,
|
|
const math_Matrix& v,
|
|
const math_Vector& b,
|
|
math_Vector& x) {
|
|
|
|
Standard_Integer jj, j, i;
|
|
Standard_Real s;
|
|
|
|
Standard_Integer m = u.RowNumber();
|
|
Standard_Integer n = u.ColNumber();
|
|
math_Vector tmp(1, n);
|
|
|
|
for(j = 1; j <= n; j++) {
|
|
s = 0.0;
|
|
if(w(j)) {
|
|
for(i = 1; i <= m; i++)
|
|
s += u(i,j) * b(i);
|
|
s /= w(j);
|
|
}
|
|
tmp(j) = s;
|
|
}
|
|
for(j = 1; j <= n; j++) {
|
|
s = 0.0;
|
|
for(jj = 1; jj <= n; jj++)
|
|
s += v(j,jj) * tmp(jj);
|
|
x(j) = s;
|
|
}
|
|
}
|
|
|
|
Standard_Integer DACTCL_Decompose(math_Vector& a,
|
|
const math_IntegerVector& indx,
|
|
const Standard_Real MinPivot) {
|
|
|
|
Standard_Integer i, j, Neq = indx.Length();
|
|
Standard_Integer jr, jd, jh, is, ie, k, ir, id, ih, mh;
|
|
Standard_Integer idot, idot1, idot2;
|
|
Standard_Real aa, d, dot;
|
|
Standard_Boolean diag;
|
|
|
|
jr = 0;
|
|
for (j = 1; j <= Neq; j++) {
|
|
diag = Standard_False;
|
|
jd = indx(j);
|
|
jh = jd-jr;
|
|
is = j-jh+2;
|
|
if (jh-2 == 0) diag = Standard_True;
|
|
if (jh-2 > 0) {
|
|
ie = j-1;
|
|
k = jr+2;
|
|
id = indx(is-1);
|
|
// Reduction des coefficients non diagonaux:
|
|
// =========================================
|
|
for (i = is; i <= ie; i++) {
|
|
ir = id;
|
|
id = indx(i);
|
|
ih = id - ir - 1;
|
|
mh = i - is + 1;
|
|
if (ih > mh) ih = mh;
|
|
if (ih > 0.0) {
|
|
dot = 0.0;
|
|
idot1 = k-ih-1;
|
|
idot2 = id-ih-1;
|
|
for (idot = 1; idot <= ih; idot++) {
|
|
dot = dot +a(idot1+idot)*a(idot2+idot);
|
|
}
|
|
a(k) = a(k)-dot;
|
|
}
|
|
k++;
|
|
}
|
|
diag = Standard_True;
|
|
}
|
|
|
|
if (diag) {
|
|
// Reduction des coefficients diagonaux:
|
|
// =====================================
|
|
ir = jr+1;
|
|
ie = jd-1;
|
|
k = j-jd;
|
|
for (i = ir; i <= ie; i++) {
|
|
id = indx(k+i);
|
|
aa = a(id);
|
|
if (aa < 0) aa = - aa;
|
|
if (aa <= MinPivot)
|
|
return math_Status_SingularMatrix;
|
|
d = a(i);
|
|
a(i) = d/a(id);
|
|
a(jd) = a(jd)-d*a(i);
|
|
}
|
|
|
|
}
|
|
jr = jd;
|
|
}
|
|
return math_Status_OK;
|
|
}
|
|
|
|
|
|
Standard_Integer DACTCL_Solve(const math_Vector& a,
|
|
math_Vector& b,
|
|
const math_IntegerVector& indx,
|
|
const Standard_Real MinPivot) {
|
|
|
|
Standard_Integer i, j, Neq = indx.Length();
|
|
Standard_Integer jr, jd, jh, is, k, id;
|
|
Standard_Integer jh1, idot, idot1, idot2;
|
|
Standard_Real aa, d, dot;
|
|
|
|
jr = 0;
|
|
for (j = 1; j <= Neq; j++) {
|
|
jd = indx(j);
|
|
jh = jd-jr;
|
|
is = j-jh+2;
|
|
|
|
// Reduction du second membre:
|
|
// ===========================
|
|
dot = 0.0;
|
|
idot1 = jr;
|
|
idot2 = is-2;
|
|
jh1 = jh-1;
|
|
for (idot = 1; idot <= jh1; idot++) {
|
|
dot = dot + a(idot1+idot)*b(idot2+idot);
|
|
}
|
|
b(j) = b(j)-dot;
|
|
|
|
jr = jd;
|
|
}
|
|
|
|
// Division par les pivots diagonaux:
|
|
// ==================================
|
|
for (i = 1; i <= Neq; i++) {
|
|
id = indx(i);
|
|
aa = a(id);
|
|
if (aa < 0) aa = - aa;
|
|
if (aa <= MinPivot)
|
|
return math_Status_SingularMatrix;
|
|
b(i) = b(i)/a(id);
|
|
}
|
|
|
|
|
|
// Substitution arriere:
|
|
// =====================
|
|
jd = indx(Neq);
|
|
for (j = Neq-1; j > 0; j--) {
|
|
d = b(j+1);
|
|
jr = indx(j);
|
|
if (jd-jr > 1) {
|
|
is = j-jd+jr+2;
|
|
k = jr-is+1;
|
|
for (i = is; i <= j; i++) {
|
|
b(i) = b(i)-a(i+k)*d;
|
|
}
|
|
}
|
|
jd = jr;
|
|
}
|
|
return math_Status_OK;
|
|
|
|
}
|
|
|