1 // Copyright (C) 2022-2024 CEA, EDF
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // Implementation coming from Numerical Recipes in C of 1994 (version 2.04)
22 #include "InterpKernelLUDecomp.hxx"
23 #include "InterpKernelException.hxx"
28 using namespace INTERP_KERNEL;
30 LUDecomp::LUDecomp(const INTERP_KERNEL::DenseMatrix& a) : n(a.nrows()), lu(a), aref(a), indx(n)
32 const double TINY=1.0e-40;
35 std::vector<double> vv(n);
41 if ((temp=std::abs(lu[i][j])) > big) big=temp;
42 if (big == 0.0) THROW_IK_EXCEPTION("Singular matrix in LUDecomp");
51 temp=vv[i]*std::abs(lu[i][k]);
68 if (lu[k][k] == 0.0) lu[k][k]=TINY;
70 temp=lu[i][k] /= lu[k][k];
72 lu[i][j] -= temp*lu[k][j];
76 void LUDecomp::solve(const std::vector<double>& b, std::vector<double> &x)
80 if (b.size() != ToSizeT(n) || x.size() != ToSizeT(n))
81 THROW_IK_EXCEPTION("LUDecomp::solve bad sizes");
82 for (i=0;i<n;i++) x[i] = b[i];
88 for (j=ii-1;j<i;j++) sum -= lu[i][j]*x[j];
93 for (i=n-1;i>=0;i--) {
95 for (j=i+1;j<n;j++) sum -= lu[i][j]*x[j];
100 void LUDecomp::solve(const INTERP_KERNEL::DenseMatrix& b, INTERP_KERNEL::DenseMatrix &x)
102 mcIdType i,j,m(b.ncols());
103 if (b.nrows() != n || x.nrows() != n || b.ncols() != x.ncols())
104 THROW_IK_EXCEPTION("LUDecomp::solve bad sizes");
105 std::vector<double> xx(n);
107 for (i=0;i<n;i++) xx[i] = b[i][j];
109 for (i=0;i<n;i++) x[i][j] = xx[i];
113 void LUDecomp::inverse(INTERP_KERNEL::DenseMatrix &ainv)
118 for (j=0;j<n;j++) ainv[i][j] = 0.;
124 double LUDecomp::det()
127 for (mcIdType i=0;i<n;i++) dd *= lu[i][i];
131 void LUDecomp::mprove(const std::vector<double>& b, std::vector<double> &x)
134 std::vector<double> r(n);
136 long double sdp = -b[i];
138 sdp += (long double)aref[i][j] * (long double)x[j];
142 for (i=0;i<n;i++) x[i] -= r[i];