Path: blob/devel/ElmerGUI/netgen/libsrc/linalg/densemat.cpp
3206 views
#include <mystdlib.h>12#include <linalg.hpp>345namespace netgen6{7DenseMatrix :: DenseMatrix ()8{9data = NULL;10height = 0;11width = 0;12}1314DenseMatrix :: DenseMatrix (int h, int w)15{16if (!w) w = h;17width = w;18height = h;19if (h*w)20data = new double[h*w];21else22data = 0;2324for (int i = 0 ; i < (h * w); i++)25data[i] = 0;26}2728/*29DenseMatrix :: DenseMatrix (int h, int w, const double * d)30: BaseMatrix (h, w)31{32int size = h * w;33int i;3435if (size)36{37data = new double[size];38for (i = 0; i < size; i++)39data[i] = d[i];40}41else42data = NULL;43}44*/4546DenseMatrix :: DenseMatrix (const DenseMatrix & m2)47{48data = NULL; height = width = 0;49SetSize (m2.Height(), m2.Width());50memcpy (data, m2.data, sizeof(double) * Height() * Width());51}5253DenseMatrix :: ~DenseMatrix ()54{55delete [] data;56}575859void DenseMatrix :: SetSize (int h, int w)60{61if (!w) w = h;62if (height == h && width == w)63return;6465height = h;66width = w;6768delete[] data;6970if (h*w)71data = new double[h*w];72else73data = NULL;74}757677/*78DenseMatrix & DenseMatrix :: operator= (const BaseMatrix & m2)79{80int i, j;8182SetSize (m2.Height(), m2.Width());8384if (data)85for (i = 1; i <= Height(); i++)86for (j = 1; j <= Width(); j++)87Set (i, j, m2(i, j));88else89(*myerr) << "DenseMatrix::Operator=: Matrix not allocated" << endl;9091return *this;92}93*/949596DenseMatrix & DenseMatrix :: operator= (const DenseMatrix & m2)97{98SetSize (m2.Height(), m2.Width());99100if (data) memcpy (data, m2.data, sizeof(double) * m2.Height() * m2.Width());101return *this;102}103104105DenseMatrix & DenseMatrix :: operator+= (const DenseMatrix & m2)106{107int i;108double * p, * q;109110if (Height() != m2.Height() || Width() != m2.Width())111{112(*myerr) << "DenseMatrix::Operator+=: Sizes don't fit" << endl;113return *this;114}115116if (data)117{118p = data;119q = m2.data;120for (i = Width() * Height(); i > 0; i--)121{122*p += *q;123p++;124q++;125}126}127else128(*myerr) << "DenseMatrix::Operator+=: Matrix not allocated" << endl;129130return *this;131}132133134DenseMatrix & DenseMatrix :: operator-= (const DenseMatrix & m2)135{136int i;137double * p, * q;138139if (Height() != m2.Height() || Width() != m2.Width())140{141(*myerr) << "DenseMatrix::Operator-=: Sizes don't fit" << endl;142return *this;143}144145if (data)146{147p = data;148q = m2.data;149for (i = Width() * Height(); i > 0; i--)150{151*p -= *q;152p++;153q++;154}155}156else157(*myerr) << "DenseMatrix::Operator-=: Matrix not allocated" << endl;158159return *this;160}161162163164165/*166double & DenseMatrix :: operator() (int i, int j)167{168if (i >= 1 && j >= 1 && i <= height && j <= width)169return Elem(i,j);170else (*myerr) << "DenseMatrix: index (" << i << "," << j << ") out of range (1.."171<< height << ",1.." << width << ")\n";172static double dummy = 0;173return dummy;174}175176double DenseMatrix :: operator() (int i, int j) const177{178if (i >= 1 && j >= 1 && i <= height && j <= width)179return Get(i,j);180else (*myerr) << "DenseMatrix: index (" << i << "," << j << ") out of range (1.."181<< height << ",1.." << width << ")\n";182183static double dummy = 0;184return dummy;185}186*/187188DenseMatrix & DenseMatrix :: operator= (double v)189{190int i;191double * p = data;192193if (data)194for (i = width*height; i > 0; i--, p++)195*p = v;196197return *this;198}199200201202DenseMatrix & DenseMatrix :: operator*= (double v)203{204int i;205double * p = data;206207if (data)208for (i = width*height; i > 0; i--, p++)209*p *= v;210211return *this;212}213214215double DenseMatrix :: Det () const216{217if (width != height)218{219(*myerr) << "DenseMatrix :: Det: width != height" << endl;220return 0;221}222223switch (width)224{225case 1: return Get(1, 1);226case 2: return Get(1) * Get(4) - Get(2) * Get(3);227228case 3: return Get(1) * Get(5) * Get(9)229+ Get(2) * Get(6) * Get(7)230+ Get(3) * Get(4) * Get(8)231- Get(1) * Get(6) * Get(8)232- Get(2) * Get(4) * Get(9)233- Get(3) * Get(5) * Get(7);234default:235{236(*myerr) << "Matrix :: Det: general size not implemented (size=" << width << ")" << endl;237return 0;238}239}240}241242243void CalcInverse (const DenseMatrix & m1, DenseMatrix & m2)244{245// int i, j, k, n;246double det;247// DenseMatrix m1 = hm1;248249if (m1.width != m1.height)250{251(*myerr) << "CalcInverse: matrix not symmetric" << endl;252return;253}254if (m1.width != m2.width || m1.height != m2.height)255{256(*myerr) << "CalcInverse: dim(m2) != dim(m1)" << endl;257return;258}259260261if (m1.Width() <= 3)262{263det = m1.Det();264if (det == 0)265{266(*myerr) << "CalcInverse: Matrix singular" << endl;267return;268}269270det = 1e0 / det;271switch (m1.width)272{273case 1:274{275m2.Set(1, 1, det);276return;277}278case 2:279{280m2.Set(1, 1, det * m1.Get(4));281m2.Set(2, 2, det * m1.Get(1));282m2.Set(1, 2, - det * m1.Get(2));283m2.Set(2, 1, - det * m1.Get(3));284return;285}286case 3:287{288m2.Set(1, 1, det * (m1.Get(5) * m1.Get(9) - m1.Get(6) * m1.Get(8)));289m2.Set(2, 1, -det * (m1.Get(4) * m1.Get(9) - m1.Get(6) * m1.Get(7)));290m2.Set(3, 1, det * (m1.Get(4) * m1.Get(8) - m1.Get(5) * m1.Get(7)));291292m2.Set(1, 2, -det * (m1.Get(2) * m1.Get(9) - m1.Get(3) * m1.Get(8)));293m2.Set(2, 2, det * (m1.Get(1) * m1.Get(9) - m1.Get(3) * m1.Get(7)));294m2.Set(3, 2, -det * (m1.Get(1) * m1.Get(8) - m1.Get(2) * m1.Get(7)));295296m2.Set(1, 3, det * (m1.Get(2) * m1.Get(6) - m1.Get(3) * m1.Get(5)));297m2.Set(2, 3, -det * (m1.Get(1) * m1.Get(6) - m1.Get(3) * m1.Get(4)));298m2.Set(3, 3, det * (m1.Get(1) * m1.Get(5) - m1.Get(2) * m1.Get(4)));299return;300}301}302}303304else305{306int i, j, k, n;307n = m1.Height();308309310#ifdef CHOL311int dots = (n > 200);312313// Cholesky314315double x;316Vector p(n);317318m2 = m1;319/*320m2.SetSymmetric();321if (!m2.Symmetric())322cerr << "m should be symmetric for Cholesky" << endl;323*/324325for (i = 1; i <= n; i++)326for (j = 1; j < i; j++)327m2.Elem(j, i) = m2.Get(i, j);328329for (i = 1; i <= n; i++)330{331if (dots && i % 10 == 0)332(*mycout) << "." << flush;333334for (j = i; j <= n; j++)335{336x = m2.Get(i, j);337338const double * pik = &m2.Get(i, 1);339const double * pjk = &m2.Get(j, 1);340341for (k = i-2; k >= 0; --k, ++pik, ++pjk)342x -= (*pik) * (*pjk);343344// for (k = i-1; k >= 1; --k)345// x -= m2.Get(j, k) * m2.Get(i, k);346347if (i == j)348{349if (x <= 0)350{351cerr << "Matrix indefinite 1" << endl;352return;353}354355p.Elem(i) = 1 / sqrt(x);356}357else358{359m2.Elem(j, i) = x * p.Get(i);360}361}362}363364for (i = 1; i <= n; i++)365m2.Elem(i, i) = 1 / p.Get(i);366367// check: A = L L^t368369// for (i = 1; i <= n; i++)370// for (j = 1; j <= n; j++)371// {372// x = 0;373// for (k = 1; k <= i && k <= j; k++)374// x += m2.Get(i, k) * m2.Get(j, k);375// (*testout) << "err " << i << "," << j << " = " << (m1.Get(i, j) - x) << endl;376// }377378379380// calc L^{-1}, store upper triangle381382// DenseMatrix hm(n);383// hm = m2;384385for (i = 1; i <= n; i++)386{387if (dots && i % 10 == 0)388(*mycout) << "+" << flush;389390for (j = i; j <= n; j++)391{392x = 0;393if (j == i) x = 1;394395const double * pjk = &m2.Get(j, i);396const double * pik = &m2.Get(i, i);397for (k = i; k < j; k++, ++pjk, ++pik)398x -= *pik * *pjk;399400// for (k = i; k < j; k++)401// x -= m2.Get(j, k) * m2.Get(i, k);402403m2.Elem(i, j) = x / m2.Get(j, j);404}405}406407// (*testout) << "check L^-1" << endl;408// for (i = 1; i <= n; i++)409// for (j = 1; j <= n; j++)410// {411// x = 0;412// for (k = j; k <= i; k++)413// x += hm.Get(i, k) * m2.Get(j, k);414// (*testout) << "i, j = " << i << "," << j << " x = " << x << endl;415// }416417418// calc A^-1 = L^-T * L^-1419420for (i = 1; i <= n; i++)421{422if (dots && i % 10 == 0)423(*mycout) << "-" << flush;424425for (j = 1; j <= i; j++)426{427x = 0;428k = i;429if (j > i) k = j;430431const double * pik = &m2.Get(i, k);432const double * pjk = &m2.Get(j, k);433434for ( ; k <= n; ++k, ++pik, ++pjk)435x += *pik * *pjk;436// for ( ; k <= n; k++)437// x += m2.Get(i, k) * m2.Get(j, k);438439m2.Elem(i, j) = x;440}441}442443for (i = 1; i <= n; i++)444for (j = 1; j < i; j++)445m2.Elem(j, i) = m2.Get(i, j);446447if (dots) (*mycout) << endl;448#endif449450451452// Gauss - Jordan - algorithm453454int r, hi;455double max, hr;456457458ARRAY<int> p(n); // pivot-permutation459Vector hv(n);460461462m2 = m1;463464/*465if (m2.Symmetric())466for (i = 1; i <= n; i++)467for (j = 1; j < i; j++)468m2.Elem(j, i) = m2.Get(i, j);469*/470471// Algorithm of Stoer, Einf. i. d. Num. Math, S 145472473for (j = 1; j <= n; j++)474p.Set(j, j);475476for (j = 1; j <= n; j++)477{478// pivot search479480max = fabs(m2.Get(j, j));481r = j;482483for (i = j+1; i <= n ;i++)484if (fabs (m2.Get(i, j)) > max)485{486r = i;487max = fabs (m2.Get(i, j));488}489490if (max < 1e-20)491{492cerr << "Inverse matrix: matrix singular" << endl;493return;494}495496r = j;497498// exchange rows499if (r > j)500{501for (k = 1; k <= n; k++)502{503hr = m2.Get(j, k);504m2.Elem(j, k) = m2.Get(r, k);505m2.Elem(r, k) = hr;506}507hi = p.Get(j);508p.Elem(j) = p.Get(r);509p.Elem(r) = hi;510}511512513// transformation514515hr = 1 / m2.Get(j, j);516for (i = 1; i <= n; i++)517m2.Elem(i, j) *= hr;518m2.Elem(j, j) = hr;519520for (k = 1; k <= n; k++)521if (k != j)522{523for (i = 1; i <= n; i++)524if (i != j)525m2.Elem(i, k) -= m2.Elem(i, j) * m2.Elem(j, k);526m2.Elem(j, k) *= -hr;527}528}529530// col exchange531532for (i = 1; i <= n; i++)533{534for (k = 1; k <= n; k++)535hv.Elem(p.Get(k)) = m2.Get(i, k);536for (k = 1; k <= n; k++)537m2.Elem(i, k) = hv.Get(k);538}539540541542/*543if (m1.Symmetric())544for (i = 1; i <= n; i++)545for (j = 1; j < i; j++)546m1.Elem(j, i) = m1.Get(i, j);547548m2 = 0;549550for (i = 1; i <= n; i++)551m2.Elem(i, i) = 1;552553for (i = 1; i <= n; i++)554{555// (*mycout) << '.' << flush;556q = m1.Get(i, i);557for (k = 1; k <= n; k++)558{559m1.Elem(i, k) /= q;560m2.Elem(i, k) /= q;561}562563for (j = i+1; j <= n; j++)564{565q = m1.Elem(j, i);566567double * m1pi = &m1.Elem(i, i);568double * m1pj = &m1.Elem(j, i);569570for (k = n; k >= i; --k, ++m1pi, ++m1pj)571*m1pj -= q * (*m1pi);572573double * m2pi = &m2.Elem(i, 1);574double * m2pj = &m2.Elem(j, 1);575576for (k = i; k > 0; --k, ++m2pi, ++m2pj)577*m2pj -= q * (*m2pi);578579// for (k = 1; k <= n; k++)580// {581// m1.Elem(j, k) -= q * m1.Elem(i, k);582// m2.Elem(j, k) -= q * m2.Elem(i, k);583// }584585}586}587588for (i = n; i >= 1; i--)589{590// (*mycout) << "+" << flush;591for (j = 1; j < i; j++)592{593q = m1.Elem(j, i);594595double * m2pi = &m2.Elem(i, 1);596double * m2pj = &m2.Elem(j, 1);597598for (k = n; k > 0; --k, ++m2pi, ++m2pj)599*m2pj -= q * (*m2pi);600601602// for (k = 1; k <= n; k++)603// {604// m1.Elem(j, k) -= q * m1.Elem(i, k);605// m2.Elem(j, k) -= q * m2.Elem(i, k);606// }607}608}609610if (m2.Symmetric())611{612for (i = 1; i <= n; i++)613for (j = 1; j < i; j++)614m2.Elem(i, j) = m2.Elem(j, i);615}616*/617}618}619620621void CalcAAt (const DenseMatrix & a, DenseMatrix & m2)622{623int n1 = a.Height();624int n2 = a.Width();625int i, j, k;626double sum;627const double *p, *q, *p0;628629if (m2.Height() != n1 || m2.Width() != n1)630{631(*myerr) << "CalcAAt: sizes don't fit" << endl;632return;633}634635for (i = 1; i <= n1; i++)636{637sum = 0;638p = &a.ConstElem(i, 1);639for (k = 1; k <= n2; k++)640{641sum += *p * *p;642p++;643}644m2.Set(i, i, sum);645646p0 = &a.ConstElem(i, 1);647q = a.data;648for (j = 1; j < i; j++)649{650sum = 0;651p = p0;652653for (k = 1; k <= n2; k++)654{655sum += *p * *q;656p++;657q++;658}659m2.Set(i, j, sum);660m2.Set(j, i, sum);661}662}663}664665666667#ifdef ABC668BaseMatrix * DenseMatrix :: InverseMatrix (const BitArray * /* inner */) const669{670if (Height() != Width())671{672(*myerr) << "BaseMatrix::InverseMatrix(): Matrix not symmetric" << endl;673return new DenseMatrix(1);674}675else676{677if (Symmetric())678{679(*mycout) << "Invmat not available" << endl;680BaseMatrix * invmat = NULL;681return invmat;682}683684DenseMatrix * invmat = new DenseMatrix (Height());685686CalcInverse (*this, *invmat);687return invmat;688}689}690#endif691692693694void CalcAtA (const DenseMatrix & a, DenseMatrix & m2)695{696int n1 = a.Height();697int n2 = a.Width();698int i, j, k;699double sum;700701if (m2.Height() != n2 || m2.Width() != n2)702{703(*myerr) << "CalcAtA: sizes don't fit" << endl;704return;705}706707for (i = 1; i <= n2; i++)708for (j = 1; j <= n2; j++)709{710sum = 0;711for (k = 1; k <= n1; k++)712sum += a.Get(k, i) * a.Get(k, j);713m2.Elem(i, j) = sum;714}715}716717718719720721722void CalcABt (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2)723{724int n1 = a.Height();725int n2 = a.Width();726int n3 = b.Height();727int i, j, k;728double sum;729730if (m2.Height() != n1 || m2.Width() != n3 || b.Width() != n2)731{732(*myerr) << "CalcABt: sizes don't fit" << endl;733return;734}735736double * pm2 = &m2.Elem(1, 1);737const double * pa1 = &a.Get(1, 1);738739for (i = 1; i <= n1; i++)740{741const double * pb = &b.Get(1, 1);742for (j = 1; j <= n3; j++)743{744sum = 0;745const double * pa = pa1;746747for (k = 1; k <= n2; k++)748{749sum += *pa * *pb;750pa++; pb++;751}752753*pm2 = sum;754pm2++;755}756pa1 += n2;757}758}759760761void CalcAtB (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2)762{763int n1 = a.Height();764int n2 = a.Width();765int n3 = b.Width();766int i, j, k;767768if (m2.Height() != n2 || m2.Width() != n3 || b.Height() != n1)769{770(*myerr) << "CalcAtB: sizes don't fit" << endl;771return;772}773774for (i = 1; i <= n2 * n3; i++)775m2.data[i-1] = 0;776777for (i = 1; i <= n1; i++)778for (j = 1; j <= n2; j++)779{780const double va = a.Get(i, j);781double * pm2 = &m2.Elem(j, 1);782const double * pb = &b.Get(i, 1);783784for (k = 1; k <= n3; ++k, ++pm2, ++pb)785*pm2 += va * *pb;786// for (k = 1; k <= n3; k++)787// m2.Elem(j, k) += va * b.Get(i, k);788}789/*790for (i = 1; i <= n2; i++)791for (j = 1; j <= n3; j++)792{793sum = 0;794for (k = 1; k <= n1; k++)795sum += a.Get(k, i) * b.Get(k, j);796m2.Elem(i, j) = sum;797}798*/799}800801802803804805806807DenseMatrix operator* (const DenseMatrix & m1, const DenseMatrix & m2)808{809DenseMatrix temp (m1.Height(), m2.Width());810811if (m1.Width() != m2.Height())812{813(*myerr) << "DenseMatrix :: operator*: Matrix Size does not fit" << endl;814}815else if (temp.Height() != m1.Height())816{817(*myerr) << "DenseMatrix :: operator*: temp not allocated" << endl;818}819else820{821Mult (m1, m2, temp);822}823return temp;824}825826827void Mult (const DenseMatrix & m1, const DenseMatrix & m2, DenseMatrix & m3)828{829double sum;830double *p1, *p1s, *p1sn, *p1snn, *p2, *p2s, *p2sn, *p3;831832if (m1.Width() != m2.Height() || m1.Height() != m3.Height() ||833m2.Width() != m3.Width() )834{835(*myerr) << "DenseMatrix :: Mult: Matrix Size does not fit" << endl;836(*myerr) << "m1: " << m1.Height() << " x " << m1.Width() << endl;837(*myerr) << "m2: " << m2.Height() << " x " << m2.Width() << endl;838(*myerr) << "m3: " << m3.Height() << " x " << m3.Width() << endl;839return;840}841/*842else if (m1.Symmetric() || m2.Symmetric() || m3.Symmetric())843{844(*myerr) << "DenseMatrix :: Mult: not implemented for symmetric matrices" << endl;845return;846}847*/848else849{850// int i, j, k;851int n1 = m1.Height();852int n2 = m2.Width();853int n3 = m1.Width();854855/*856for (i = n1 * n2-1; i >= 0; --i)857m3.data[i] = 0;858859const double * pm1 = &m1.Get(1, 1);860for (i = 1; i <= n1; i++)861{862const double * pm2 = &m2.Get(1, 1);863double * pm3i = &m3.Elem(i, 1);864865for (j = 1; j <= n3; j++)866{867const double vm1 = *pm1;868++pm1;869// const double vm1 = m1.Get(i, j);870double * pm3 = pm3i;871// const double * pm2 = &m2.Get(j, 1);872873for (k = 0; k < n2; k++)874{875*pm3 += vm1 * *pm2;876++pm2;877++pm3;878}879880// for (k = 1; k <= n2; k++)881// m3.Elem(i, k) += m1.Get(i, j) * m2.Get(j, k);882}883}884*/885886/*887for (i = 1; i <= n1; i++)888for (j = 1; j <= n2; j++)889{890sum = 0;891for (k = 1; k <= n3; k++)892sum += m1.Get(i, k) * m2.Get(k, j);893m3.Set(i, j, sum);894}895*/896897898/*899for (i = 1; i <= n1; i++)900{901const double pm1i = &m1.Get(i, 1);902const double pm2j = &m2.Get(1, 1);903904for (j = 1; j <= n2; j++)905{906double sum = 0;907const double * pm1 = pm1i;908const double * pm2 = pm2j;909pm2j++;910911for (k = 1; k <= n3; k++)912{913sum += *pm1 * *pm2;914++pm1;915pm2 += n2;916}917918m3.Set (i, j, sum);919}920}921*/922923924p3 = m3.data;925p1s = m1.data;926p2sn = m2.data + n2;927p1snn = p1s + n1 * n3;928929while (p1s != p1snn)930{931p1sn = p1s + n3;932p2s = m2.data;933934while (p2s != p2sn)935{936sum = 0;937p1 = p1s;938p2 = p2s;939p2s++;940941while (p1 != p1sn)942{943sum += *p1 * *p2;944p1++;945p2 += n2;946}947*p3++ = sum;948}949p1s = p1sn;950}951}952}953954955956DenseMatrix operator+ (const DenseMatrix & m1, const DenseMatrix & m2)957{958DenseMatrix temp (m1.Height(), m1.Width());959int i, j;960961if (m1.Width() != m2.Width() || m1.Height() != m2.Height())962{963(*myerr) << "BaseMatrix :: operator+: Matrix Size does not fit" << endl;964}965else if (temp.Height() != m1.Height())966{967(*myerr) << "BaseMatrix :: operator+: temp not allocated" << endl;968}969else970{971for (i = 1; i <= m1.Height(); i++)972for (j = 1; j <= m1.Width(); j++)973{974temp.Set(i, j, m1.Get(i, j) + m2.Get(i, j));975}976}977return temp;978}979980981982983void Transpose (const DenseMatrix & m1, DenseMatrix & m2)984{985int w = m1.Width();986int h = m1.Height();987int i, j;988989m2.SetSize (w, h);990991double * pm2 = &m2.Elem(1, 1);992for (j = 1; j <= w; j++)993{994const double * pm1 = &m1.Get(1, j);995for (i = 1; i <= h; i++)996{997*pm2 = *pm1;998pm2 ++;999pm1 += w;1000}1001}1002}100310041005/*1006void DenseMatrix :: Mult (const Vector & v, Vector & prod) const1007{1008double sum, val;1009const double * mp, * sp;1010double * dp;1011// const Vector & v = bv.CastToVector();1012// Vector & prod = bprod.CastToVector();101310141015int n = Height();1016int m = Width();10171018if (prod.Size() != n)1019prod.SetSize (n);10201021#ifdef DEVELOP1022if (!n)1023{1024cout << "DenseMatrix::Mult mheight = 0" << endl;1025}1026if (!m)1027{1028cout << "DenseMatrix::Mult mwidth = 0" << endl;1029}10301031if (m != v.Size())1032{1033(*myerr) << "\nMatrix and Vector don't fit" << endl;1034}1035else if (Height() != prod.Size())1036{1037(*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl;1038}1039else1040#endif1041{1042if (Symmetric())1043{1044int i, j;104510461047for (i = 1; i <= n; i++)1048{1049sp = &v.Get(1);1050dp = &prod.Elem(1);1051mp = &Get(i, 1);10521053val = v.Get(i);1054sum = Get(i, i) * val;10551056for (j = 1; j < i; ++j, ++mp, ++sp, ++dp)1057{1058sum += *mp * *sp;1059*dp += val * *mp;1060}10611062prod.Elem(i) = sum;1063}1064}1065else1066{1067mp = data;1068dp = &prod.Elem(1);1069for (int i = 1; i <= n; i++)1070{1071sum = 0;1072sp = &v.Get(1);10731074for (int j = 1; j <= m; j++)1075{1076// sum += Get(i,j) * v.Get(j);1077sum += *mp * *sp;1078mp++;1079sp++;1080}10811082// prod.Set (i, sum);1083*dp = sum;1084dp++;1085}1086}1087}1088}1089*/10901091void DenseMatrix :: MultTrans (const Vector & v, Vector & prod) const1092{1093// const Vector & v = (const Vector&)bv; // .CastToVector();1094// Vector & prod = (Vector & )bprod; // .CastToVector();10951096/*1097if (Height() != v.Size())1098{1099(*myerr) << "\nMatrix and Vector don't fit" << endl;1100}1101else if (Width() != prod.Size())1102{1103(*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl;1104}1105else1106*/1107{1108int i, j;1109int w = Width(), h = Height();1110if (prod.Size() != w)1111prod.SetSize (w);11121113const double * pmat = &Get(1, 1);1114const double * pv = &v.Get(1);11151116prod = 0;11171118for (i = 1; i <= h; i++)1119{1120double val = *pv;1121++pv;11221123double * pprod = &prod.Elem(1);11241125for (j = w-1; j >= 0; --j, ++pmat, ++pprod)1126{1127*pprod += val * *pmat;1128}1129}11301131/*1132double sum;11331134for (i = 1; i <= Width(); i++)1135{1136sum = 0;11371138for (int j = 1; j <= Height(); j++)1139sum += Get(j, i) * v.Get(j);11401141prod.Set (i, sum);1142}1143*/1144}1145}114611471148void DenseMatrix :: Residuum (const Vector & x, const Vector & b,1149Vector & res) const1150{1151double sum;1152// const Vector & x = bx.CastToVector();1153// const Vector & b = bb.CastToVector();1154// Vector & res = bres.CastToVector();11551156res.SetSize (Height());11571158if (Width() != x.Size() || Height() != b.Size())1159{1160(*myerr) << "\nMatrix and Vector don't fit" << endl;1161}1162else if (Height() != res.Size())1163{1164(*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl;1165}1166else1167{1168int i, j;1169int h = Height();1170int w = Width();1171const double * mp = &Get(1, 1);11721173for (i = 1; i <= h; i++)1174{1175sum = b.Get(i);1176const double * xp = &x.Get(1);11771178for (j = 1; j <= w; ++j, ++mp, ++xp)1179sum -= *mp * *xp;11801181res.Elem(i) = sum;1182}1183}1184}11851186#ifdef ABC1187double DenseMatrix :: EvaluateBilinearform (const Vector & hx) const1188{1189double sum = 0, hsum;1190// const Vector & hx = x.CastToVector();1191int i, j;11921193if (Width() != hx.Size() || Height() != hx.Size())1194{1195(*myerr) << "Matrix::EvaluateBilinearForm: sizes don't fit" << endl;1196}1197else1198{1199for (i = 1; i <= Height(); i++)1200{1201hsum = 0;1202for (j = 1; j <= Height(); j++)1203{1204hsum += Get(i, j) * hx.Get(j);1205}1206sum += hsum * hx.Get(i);1207}1208}12091210// testout << "sum = " << sum << endl;1211return sum;1212}121312141215void DenseMatrix :: MultElementMatrix (const ARRAY<int> & pnum,1216const Vector & hx, Vector & hy)1217{1218int i, j;1219// const Vector & hx = x.CastToVector();1220// Vector & hy = y.CastToVector();12211222if (Symmetric())1223{1224for (i = 1; i <= Height(); i++)1225{1226for (j = 1; j < i; j++)1227{1228hy.Elem(pnum.Get(i)) += Get(i, j) * hx.Get(pnum.Get(j));1229hy.Elem(pnum.Get(j)) += Get(i, j) * hx.Get(pnum.Get(i));1230}1231hy.Elem(pnum.Get(j)) += Get(i, i) * hx.Get(pnum.Get(i));1232}1233}1234else1235for (i = 1; i <= Height(); i++)1236for (j = 1; j <= Width(); j++)1237hy.Elem(pnum.Get(i)) += Get(i, j) * hx.Get(pnum.Get(j));12381239}12401241void DenseMatrix :: MultTransElementMatrix (const ARRAY<int> & pnum,1242const Vector & hx, Vector & hy)1243{1244int i, j;1245// const Vector & hx = x.CastToVector();1246// Vector & hy = y.CastToVector();12471248if (Symmetric())1249MultElementMatrix (pnum, hx, hy);1250else1251for (i = 1; i <= Height(); i++)1252for (j = 1; j <= Width(); j++)1253hy.Elem(pnum.Get(i)) += Get(j, i) * hx.Get(pnum.Get(j));1254}1255#endif125612571258void DenseMatrix :: Solve (const Vector & v, Vector & sol) const1259{1260DenseMatrix temp (*this);1261temp.SolveDestroy (v, sol);1262}126312641265void DenseMatrix :: SolveDestroy (const Vector & v, Vector & sol)1266{1267double q;12681269if (Width() != Height())1270{1271(*myerr) << "SolveDestroy: Matrix not square";1272return;1273}1274if (Width() != v.Size())1275{1276(*myerr) << "SolveDestroy: Matrix and Vector don't fit";1277return;1278}12791280sol = v;1281if (Height() != sol.Size())1282{1283(*myerr) << "SolveDestroy: Solution Vector not ok";1284return;1285}128612871288if (0 /* Symmetric() */)1289{12901291// Cholesky factorization12921293int i, j, k, n;1294n = Height();12951296// Cholesky12971298double x;1299Vector p(n);13001301for (i = 1; i <= n; i++)1302for (j = 1; j < i; j++)1303Elem(j, i) = Get(i, j);13041305for (i = 1; i <= n; i++)1306{1307// (*mycout) << "." << flush;1308for (j = i; j <= n; j++)1309{1310x = Get(i, j);13111312const double * pik = &Get(i, 1);1313const double * pjk = &Get(j, 1);13141315for (k = i-2; k >= 0; --k, ++pik, ++pjk)1316x -= (*pik) * (*pjk);13171318// for (k = i-1; k >= 1; --k)1319// x -= Get(j, k) * Get(i, k);13201321if (i == j)1322{1323if (x <= 0)1324{1325cerr << "Matrix indefinite" << endl;1326return;1327}13281329p.Elem(i) = 1 / sqrt(x);1330}1331else1332{1333Elem(j, i) = x * p.Get(i);1334}1335}1336}13371338for (i = 1; i <= n; i++)1339Elem(i, i) = 1 / p.Get(i);13401341// A = L L^t1342// L stored in left-lower triangle134313441345sol = v;13461347// Solve L sol = sol13481349for (i = 1; i <= n; i++)1350{1351double val = sol.Get(i);13521353const double * pij = &Get(i, 1);1354const double * solj = &sol.Get(1);13551356for (j = 1; j < i; j++, ++pij, ++solj)1357val -= *pij * *solj;1358// for (j = 1; j < i; j++)1359// val -= Get(i, j) * sol.Get(j);13601361sol.Elem(i) = val / Get(i, i);1362}13631364// Solve L^t sol = sol13651366for (i = n; i >= 1; i--)1367{1368double val = sol.Get(i) / Get(i, i);1369sol.Elem(i) = val;13701371double * solj = &sol.Elem(1);1372const double * pij = &Get(i, 1);13731374for (j = 1; j < i; ++j, ++pij, ++solj)1375*solj -= val * *pij;1376// for (j = 1; j < i; j++)1377// sol.Elem(j) -= Get(i, j) * val;1378}137913801381}1382else1383{1384// (*mycout) << "gauss" << endl;1385int i, j, k, n = Height();1386for (i = 1; i <= n; i++)1387{1388for (j = i+1; j <= n; j++)1389{1390q = Get(j,i) / Get(i,i);1391if (q)1392{1393const double * pik = &Get(i, i+1);1394double * pjk = &Elem(j, i+1);13951396for (k = i+1; k <= n; ++k, ++pik, ++pjk)1397*pjk -= q * *pik;13981399// for (k = i+1; k <= Height(); k++)1400// Elem(j, k) -= q * Get(i,k);140114021403sol.Elem(j) -= q * sol.Get(i);1404}1405}1406}14071408for (i = n; i >= 1; i--)1409{1410q = sol.Get(i);1411for (j = i+1; j <= n; j++)1412q -= Get(i,j) * sol.Get(j);14131414sol.Elem(i) = q / Get(i,i);1415}1416}1417}141814191420/*1421BaseMatrix * DenseMatrix :: Copy () const1422{1423return new DenseMatrix (*this);1424}1425*/14261427142814291430ostream & operator<< (ostream & ost, const DenseMatrix & m)1431{1432for (int i = 0; i < m.Height(); i++)1433{1434for (int j = 0; j < m.Width(); j++)1435ost << m.Get(i+1,j+1) << " ";1436ost << endl;1437}1438return ost;1439}1440144114421443}144414451446