/*********************************************************************/ /* File: special_matrix.cpp */ /* Author: Joachim Schoeberl */ /* Date: 14. Mar. 2002 */ /*********************************************************************/ /* bilinear-form and linear-form integrators */ #include namespace ngla { using namespace ngla; template Real2ComplexMatrix :: Real2ComplexMatrix (const BaseMatrix * arealmatrix) : hx(0), hy(0) { SetMatrix (arealmatrix); } template void Real2ComplexMatrix :: SetMatrix (const BaseMatrix * arealmatrix) { realmatrix = arealmatrix; if (realmatrix) { hx.SetSize (realmatrix->Height()); hy.SetSize (realmatrix->Width()); } } template void Real2ComplexMatrix :: MultAdd (double s, const BaseVector & x, BaseVector & y) const { MultAdd (Complex(s), x, y); } template void Real2ComplexMatrix :: MultAdd (Complex s, const BaseVector & x, BaseVector & y) const { try { const FlatVector cx = dynamic_cast&> (x).FV(); FlatVector cy = dynamic_cast&> (y).FV(); VVector & hhx = const_cast&> (hx); VVector & hhy = const_cast&> (hy); int i, j; /* for (i = 0; i < cx.Size(); i++) hhx.FV()(i)(0) = cx(i)(0).real(); */ for (i = 0; i < cx.Size(); i++) for (j = 0; j < TVR::SIZE; j++) hhx(i)(j) = cx(i)(j).real(); realmatrix -> Mult (hhx, hhy); cy += s * hhy.FV(); /* for (i = 0; i < cx.Size(); i++) hhx.FV()(i)(0) = cx(i)(0).imag(); */ for (i = 0; i < cx.Size(); i++) for (j = 0; j < TVR::SIZE; j++) hhx(i)(j) = cx(i)(j).imag(); realmatrix -> Mult (hhx, hhy); cy += (s*Complex(0,1)) * hhy.FV(); } catch (Exception & e) { e.Append (string ("\nthrown by Complex2RealMatrix::MultAdd ")); throw; } } template <> void Real2ComplexMatrix :: MultAdd (Complex s, const BaseVector & x, BaseVector & y) const { const FlatVector cx = dynamic_cast&> (x).FV(); FlatVector cy = dynamic_cast&> (y).FV(); VVector & hhx = const_cast&> (hx); VVector & hhy = const_cast&> (hy); int i; /* for (i = 0; i < cx.Size(); i++) hhx.FV()(i)(0) = cx(i)(0).real(); */ for (i = 0; i < cx.Size(); i++) hhx(i) = cx(i).real(); realmatrix -> Mult (hhx, hhy); cy += s * hhy.FV(); /* for (i = 0; i < cx.Size(); i++) hhx.FV()(i)(0) = cx(i)(0).imag(); */ for (i = 0; i < cx.Size(); i++) hhx(i) = cx(i).imag(); realmatrix -> Mult (hhx, hhy); cy += (s*Complex(0,1)) * hhy.FV(); } template class Real2ComplexMatrix; template class Real2ComplexMatrix,Vec<2,Complex> >; template class Real2ComplexMatrix,Vec<3,Complex> >; template class Real2ComplexMatrix,Vec<4,Complex> >; //////////////////////////////////////////////////////////////////////////////// // added 08/19/2003 template Sym2NonSymMatrix :: Sym2NonSymMatrix (const BaseMatrix * abasematrix) : hx(0), hy(0) { SetMatrix (abasematrix); } template void Sym2NonSymMatrix :: SetMatrix (const BaseMatrix * abasematrix) { base = abasematrix; if (base) { hx.SetSize (base->Height()); hy.SetSize (base->Width()); } } template void Sym2NonSymMatrix :: MultAdd (double s, const BaseVector & x, BaseVector & y) const { const FlatVector cx = dynamic_cast&> (x).FV(); FlatVector cy = dynamic_cast&> (y).FV(); VVector & hhx = const_cast&> (hx); VVector & hhy = const_cast&> (hy); int i, j; // for each set of values (x_cos, x_sin), // replace them by (x_cos+x_sin,x_cos-x_sin) for (i = 0; i < cx.Size(); i++) for (j = 0; j < TVR::SIZE; j+=2) { hhx(i)(j) = cx(i)(j) + cx(i)(j+1); hhx(i)(j+1) = cx(i)(j) - cx(i)(j+1); } base -> Mult (hhx, hhy); cy -= (s/2) * hhy.FV(); // TODO: passt des minus eh? } template class Sym2NonSymMatrix >; template class Sym2NonSymMatrix >; template class Sym2NonSymMatrix >; template class Sym2NonSymMatrix >; //////////////////////////////////////////////////////////////////////////////// // added 09/02/2003 template Small2BigNonSymMatrix :: Small2BigNonSymMatrix (const BaseMatrix * abasematrix) : hx1(0), hx2(0), hy1(0), hy2(0) { SetMatrix (abasematrix); } template void Small2BigNonSymMatrix :: SetMatrix (const BaseMatrix * abasematrix) { base = abasematrix; if (base) { hx1.SetSize (base->Width()); hx2.SetSize (base->Width()); hy1.SetSize (base->Height()); hy2.SetSize (base->Height()); } } template void Small2BigNonSymMatrix :: MultAdd (double s, const BaseVector & x, BaseVector & y) const { const FlatVector cx = dynamic_cast&> (x).FV(); FlatVector cy = dynamic_cast&> (y).FV(); VVector & hhx1 = const_cast&> (hx1); VVector & hhx2 = const_cast&> (hx2); VVector & hhy1 = const_cast&> (hy1); VVector & hhy2 = const_cast&> (hy2); int i, j; // for each set of values (x_cos, x_sin), // store (x_cos+x_sin) in hhx1, // (x_cos-x_sin) in hhx2 for (i = 0; i < cx.Size(); i++) for (j = 0; j < TVSMALL::SIZE; j++) { hhx1(i)(j) = cx(i)(2*j) + cx(i)(2*j+1); hhx2(i)(j) = cx(i)(2*j) - cx(i)(2*j+1); } base -> Mult (hhx1, hhy1); base -> Mult (hhx2, hhy2); // TODO: passt des minus eh? for (i = 0; i < cx.Size(); i++) for (j = 0; j < TVSMALL::SIZE; j++) { cy(i)(2*j) -= s/2 * hhy1(i)(j); cy(i)(2*j+1) -= s/2 * hhy2(i)(j); } } template <> void Small2BigNonSymMatrix > :: MultAdd (double s, const BaseVector & x, BaseVector & y) const { const FlatVector > cx = dynamic_cast >&> (x).FV(); FlatVector > cy = dynamic_cast >&> (y).FV(); VVector & hhx1 = const_cast&> (hx1); VVector & hhx2 = const_cast&> (hx2); VVector & hhy1 = const_cast&> (hy1); VVector & hhy2 = const_cast&> (hy2); // for each set of values (x_cos, x_sin), // store (x_cos+x_sin) in hhx1, // (x_cos-x_sin) in hhx2 for (int i = 0; i < cx.Size(); i++) { hhx1(i) = cx(i)(0) + cx(i)(1); hhx2(i) = cx(i)(0) - cx(i)(1); } base -> Mult (hhx1, hhy1); base -> Mult (hhx2, hhy2); // TODO: passt des minus eh? for (int i = 0; i < cx.Size(); i++) { cy(i)(0) -= s/2 * hhy1(i); cy(i)(1) -= s/2 * hhy2(i); } } // C = C^T -> no extra implementation template void Small2BigNonSymMatrix :: MultTransAdd (double s, const BaseVector & x, BaseVector & y) const { MultAdd(s,x,y); } template class Small2BigNonSymMatrix >; template class Small2BigNonSymMatrix, Vec<4,double> >; template class Small2BigNonSymMatrix, Vec<6,double> >; template class Small2BigNonSymMatrix, Vec<8,double> >; }