21 #ifndef SELDON_FILE_FUNCTIONS_MATVECT_CXX
22 #define SELDON_FILE_FUNCTIONS_MATVECT_CXX
25 #include "Functions_MatVect.hxx"
54 template <
class T1,
class Prop1,
class Allocator1,
55 class T2,
class Storage2,
class Allocator2,
56 class T4,
class Storage4,
class Allocator4>
57 void MltVector(
const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
58 const Vector<T2, Storage2, Allocator2>& X,
59 Vector<T4, Storage4, Allocator4>& Y)
63 #ifdef SELDON_CHECK_DIMENSIONS
70 long* ptr = M.GetPtr();
71 int* ind = M.GetInd();
72 T1* data = M.GetData();
74 for (
int i = 0; i < ma; i++)
77 for (
long j = ptr[i]; j < ptr[i+1]; j++)
78 temp += data[j] * X(ind[j]);
86 template <
class T1,
class Prop1,
class Allocator1,
87 class T2,
class Storage2,
class Allocator2,
88 class T4,
class Storage4,
class Allocator4>
89 void MltVector(
const Matrix<T1, Prop1, ColSparse, Allocator1>& M,
90 const Vector<T2, Storage2, Allocator2>& X,
91 Vector<T4, Storage4, Allocator4>& Y)
93 #ifdef SELDON_CHECK_DIMENSIONS
97 long* ptr = M.GetPtr();
98 int* ind = M.GetInd();
99 T1* data = M.GetData();
102 for (
int j = 0; j < M.GetN(); j++)
104 for (
long k = ptr[j]; k < ptr[j+1]; k++)
105 Y(ind[k]) += data[k] * X(j);
111 template <
class T1,
class Prop1,
class Allocator1,
112 class T2,
class Storage2,
class Allocator2,
113 class T4,
class Storage4,
class Allocator4>
114 void MltVector(
const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
115 const Vector<T2, Storage2, Allocator2>& X,
116 Vector<T4, Storage4, Allocator4>& Y)
120 #ifdef SELDON_CHECK_DIMENSIONS
126 SetComplexZero(zero);
128 long* ptr = M.GetPtr();
129 int* ind = M.GetInd();
130 T1* data = M.GetData();
132 for (i = 0; i < ma; i++)
135 for (j = ptr[i]; j < ptr[i + 1]; j++)
136 temp += data[j] * X(ind[j]);
141 for (i = 0; i < ma-1; i++)
142 for (j = ptr[i]; j < ptr[i + 1]; j++)
144 Y(ind[j]) += data[j] * X(i);
149 template <
class T1,
class Prop1,
class Allocator1,
150 class T2,
class Storage2,
class Allocator2,
151 class T4,
class Storage4,
class Allocator4>
152 void MltVector(
const Matrix<T1, Prop1, ColSymSparse, Allocator1>& M,
153 const Vector<T2, Storage2, Allocator2>& X,
154 Vector<T4, Storage4, Allocator4>& Y)
158 #ifdef SELDON_CHECK_DIMENSIONS
164 SetComplexZero(zero);
166 long* ptr = M.GetPtr();
167 int* ind = M.GetInd();
168 T1* data = M.GetData();
170 for (i = 0; i < ma; i++)
173 for (j = ptr[i]; j < ptr[i + 1]; j++)
175 temp += data[j] * X(ind[j]);
180 for (i = 0; i < ma; i++)
181 for (j = ptr[i]; j < ptr[i + 1]; j++)
182 Y(ind[j]) += data[j] * X(i);
188 template <
class T1,
class Prop1,
class Allocator1,
189 class T2,
class Storage2,
class Allocator2,
190 class T4,
class Storage4,
class Allocator4>
191 void MltVector(
const SeldonTranspose& Trans,
192 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
193 const Vector<T2, Storage2, Allocator2>& X,
194 Vector<T4, Storage4, Allocator4>& Y)
205 #ifdef SELDON_CHECK_DIMENSIONS
206 CheckDim(Trans, M, X, Y,
"Mlt(SeldonTrans, M, X, Y)");
209 long* ptr = M.GetPtr();
210 int* ind = M.GetInd();
211 T1* data = M.GetData();
216 for (i = 0; i < ma; i++)
217 for (j = ptr[i]; j < ptr[i + 1]; j++)
218 Y(ind[j]) += data[j] * X(i);
222 for (i = 0; i < ma; i++)
223 for (j = ptr[i]; j < ptr[i + 1]; j++)
224 Y(ind[j]) += conjugate(data[j]) * X(i);
230 template <
class T1,
class Prop1,
class Allocator1,
231 class T2,
class Storage2,
class Allocator2,
232 class T4,
class Storage4,
class Allocator4>
233 void MltVector(
const SeldonTranspose& Trans,
234 const Matrix<T1, Prop1, ColSparse, Allocator1>& M,
235 const Vector<T2, Storage2, Allocator2>& X,
236 Vector<T4, Storage4, Allocator4>& Y)
246 #ifdef SELDON_CHECK_DIMENSIONS
247 CheckDim(Trans, M, X, Y,
"Mlt(SeldonTrans, M, X, Y)");
251 SetComplexZero(zero);
253 long* ptr = M.GetPtr();
254 int* ind = M.GetInd();
255 T1* data = M.GetData();
259 for (i = 0; i < M.GetN(); i++)
262 for (j = ptr[i]; j < ptr[i + 1]; j++)
263 temp += data[j] * X(ind[j]);
270 for (i = 0; i < M.GetN(); i++)
273 for (j = ptr[i]; j < ptr[i + 1]; j++)
274 temp += conjugate(data[j]) * X(ind[j]);
283 template <
class T1,
class Prop1,
class Allocator1,
284 class T2,
class Storage2,
class Allocator2,
285 class T4,
class Storage4,
class Allocator4>
286 void MltVector(
const SeldonTranspose& Trans,
287 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
288 const Vector<T2, Storage2, Allocator2>& X,
289 Vector<T4, Storage4, Allocator4>& Y)
291 if (!Trans.ConjTrans())
299 #ifdef SELDON_CHECK_DIMENSIONS
300 CheckDim(Trans, M, X, Y,
"Mlt(SeldonConjTrans, M, X, Y)");
305 SetComplexZero(zero);
307 long* ptr = M.GetPtr();
308 int* ind = M.GetInd();
309 T1* data = M.GetData();
311 for (i = 0; i < ma; i++)
314 for (j = ptr[i]; j < ptr[i + 1]; j++)
315 temp += conjugate(data[j]) * X(ind[j]);
320 for (i = 0; i < ma - 1; i++)
321 for (j = ptr[i]; j < ptr[i + 1]; j++)
323 Y(ind[j]) += conjugate(data[j]) * X(i);
328 template <
class T1,
class Prop1,
class Allocator1,
329 class T2,
class Storage2,
class Allocator2,
330 class T4,
class Storage4,
class Allocator4>
331 void MltVector(
const SeldonTranspose& Trans,
332 const Matrix<T1, Prop1, ColSymSparse, Allocator1>& M,
333 const Vector<T2, Storage2, Allocator2>& X,
334 Vector<T4, Storage4, Allocator4>& Y)
336 if (!Trans.ConjTrans())
344 #ifdef SELDON_CHECK_DIMENSIONS
345 CheckDim(Trans, M, X, Y,
"Mlt(SeldonConjTrans, M, X, Y)");
350 SetComplexZero(zero);
352 long* ptr = M.GetPtr();
353 int* ind = M.GetInd();
354 T1* data = M.GetData();
356 for (i = 0; i < ma; i++)
359 for (j = ptr[i]; j < ptr[i + 1]; j++)
360 temp += conjugate(data[j]) * X(ind[j]);
365 for (i = 0; i < ma; i++)
366 for (j = ptr[i]; j < ptr[i + 1]; j++)
368 Y(ind[j]) += conjugate(data[j]) * X(i);
373 template <
class T1,
class Prop1,
class Storage1,
class Allocator1,
374 class T2,
class Storage2,
class Allocator2,
375 class T4,
class Storage4,
class Allocator4>
376 void MltVector(
const Matrix<T1, Prop1, Storage1, Allocator1>& M,
377 const Vector<T2, Storage2, Allocator2>& X,
378 Vector<T4, Storage4, Allocator4>& Y)
383 #ifdef SELDON_CHECK_DIMENSIONS
388 if (Storage1::Sparse)
389 throw WrongArgument(
"Mlt",
"This function is intended to dense"
390 " matrices only and not to sparse matrices");
393 SetComplexZero(zero);
395 for (
int i = 0; i < ma; i++)
398 for (
int j = 0; j < na; j++)
399 temp += M(i, j) * X(j);
407 template <
class T1,
class Prop1,
class Storage1,
class Allocator1,
408 class T2,
class Storage2,
class Allocator2,
409 class T4,
class Storage4,
class Allocator4>
410 void MltVector(
const SeldonTranspose& Trans,
411 const Matrix<T1, Prop1, Storage1, Allocator1>& M,
412 const Vector<T2, Storage2, Allocator2>& X,
413 Vector<T4, Storage4, Allocator4>& Y)
424 #ifdef SELDON_CHECK_DIMENSIONS
425 CheckDim(Trans, M, X, Y,
"Mlt(trans, M, X, Y)");
428 if (Storage1::Sparse)
429 throw WrongArgument(
"MltAdd",
"This function is intended to dense"
430 " matrices only and not to sparse matrices");
433 SetComplexZero(zero);
437 for (
int i = 0; i < na; i++)
440 for (
int j = 0; j < ma; j++)
441 temp += M(j, i) * X(j);
448 for (
int i = 0; i < na; i++)
451 for (
int j = 0; j < ma; j++)
452 temp += conjugate(M(j, i)) * X(j);
472 class T1,
class Prop1,
class Allocator1,
473 class T2,
class Allocator2,
475 class T4,
class Allocator4>
476 void MltAddVector(
const T0& alpha,
477 const Matrix<T1, Prop1, PETScMPIAIJ, Allocator1>& M,
478 const Vector<T2, PETScSeq, Allocator2>& X,
479 const T3& beta, Vector<T4, PETScSeq, Allocator4>& Y)
481 #ifdef SELDON_CHECK_DIMENSIONS
482 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
493 MatMult(M.GetPetscMatrix(), X.GetPetscVector(), Y.GetPetscVector());
495 VecScale(Y.GetPetscVector(), alpha);
502 VecScale(Y.GetPetscVector(), beta);
503 MatMultAdd(M.GetPetscMatrix(), X.GetPetscVector(),
504 Y.GetPetscVector(),Y.GetPetscVector());
507 Vector<T2, PETScSeq, Allocator2> tmp;
509 MatMult(M.GetPetscMatrix(), X.GetPetscVector(), tmp.GetPetscVector());
510 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
516 class T1,
class Prop1,
class Allocator1,
517 class T2,
class Allocator2,
519 class T4,
class Allocator4>
520 void MltAddVector(
const T0& alpha,
521 const Matrix<T1, Prop1, PETScMPIAIJ, Allocator1>& M,
522 const Vector<T2, PETScPar, Allocator2>& X,
523 const T3& beta, Vector<T4, PETScPar, Allocator4>& Y)
525 #ifdef SELDON_CHECK_DIMENSIONS
526 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
537 MatMult(M.GetPetscMatrix(), X.GetPetscVector(), Y.GetPetscVector());
539 VecScale(Y.GetPetscVector(), alpha);
546 VecScale(Y.GetPetscVector(), beta);
547 MatMultAdd(M.GetPetscMatrix(), X.GetPetscVector(),
548 Y.GetPetscVector(),Y.GetPetscVector());
551 Vector<T2, PETScPar, Allocator2> tmp;
553 MatMult(M.GetPetscMatrix(), X.GetPetscVector(), tmp.GetPetscVector());
554 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
560 class T1,
class Prop1,
class Allocator1,
561 class T2,
class Allocator2,
563 class T4,
class Allocator4>
564 void MltAddVector(
const T0& alpha,
565 const Matrix<T1, Prop1, PETScMPIAIJ, Allocator1>& M,
566 const Vector<T2, VectFull, Allocator2>& X,
567 const T3& beta, Vector<T4, PETScSeq, Allocator4>& Y)
569 #ifdef SELDON_CHECK_DIMENSIONS
570 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
573 Vector<T4, PETScSeq, Allocator4> X_Petsc;
574 X_Petsc.Reallocate(X.GetM());
575 for (
int i = 0; i < X.GetM(); i++)
576 X_Petsc.SetBuffer(i, X(i));
588 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
591 VecScale(Y.GetPetscVector(), alpha);
598 VecScale(Y.GetPetscVector(), beta);
599 MatMultAdd(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
600 Y.GetPetscVector(),Y.GetPetscVector());
603 Vector<T2, PETScSeq, Allocator2> tmp;
605 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
606 tmp.GetPetscVector());
607 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
613 class T1,
class Prop1,
class Allocator1,
614 class T2,
class Allocator2,
616 class T4,
class Allocator4>
617 void MltAddVector(
const T0& alpha,
618 const Matrix<T1, Prop1, PETScMPIAIJ, Allocator1>& M,
619 const Vector<T2, VectFull, Allocator2>& X,
620 const T3& beta, Vector<T4, PETScPar, Allocator4>& Y)
622 #ifdef SELDON_CHECK_DIMENSIONS
623 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
626 Vector<T4, PETScPar, Allocator4> X_Petsc;
627 X_Petsc.SetCommunicator(M.GetCommunicator());
628 X_Petsc.Reallocate(X.GetM());
629 for (
int i = 0; i < X.GetM(); i++)
630 X_Petsc.SetBuffer(i, X(i));
642 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
645 VecScale(Y.GetPetscVector(), alpha);
652 VecScale(Y.GetPetscVector(), beta);
653 MatMultAdd(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
654 Y.GetPetscVector(),Y.GetPetscVector());
657 Vector<T2, PETScPar, Allocator2> tmp;
659 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
660 tmp.GetPetscVector());
661 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
667 class T1,
class Prop1,
class Allocator1,
668 class T2,
class Allocator2,
670 class T4,
class Allocator4>
671 void MltAddVector(
const T0& alpha,
672 const Matrix<T1, Prop1, PETScMPIDense, Allocator1>& M,
673 const Vector<T2, VectFull, Allocator2>& X,
674 const T3& beta, Vector<T4, PETScPar, Allocator4>& Y)
676 #ifdef SELDON_CHECK_DIMENSIONS
677 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
680 Vector<T4, PETScPar, Allocator4> X_Petsc;
681 X_Petsc.SetCommunicator(M.GetCommunicator());
682 X_Petsc.Reallocate(X.GetM());
683 for (
int i = 0; i < X.GetM(); i++)
684 X_Petsc.SetBuffer(i, X(i));
696 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
699 VecScale(Y.GetPetscVector(), alpha);
706 VecScale(Y.GetPetscVector(), beta);
707 MatMultAdd(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
708 Y.GetPetscVector(),Y.GetPetscVector());
711 Vector<T2, PETScPar, Allocator2> tmp;
713 tmp.SetCommunicator(M.GetCommunicator());
714 MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
715 tmp.GetPetscVector());
716 VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
726 class T1,
class Prop1,
class Allocator1,
727 class T2,
class Storage2,
class Allocator2,
729 class T4,
class Storage4,
class Allocator4>
730 void MltAddVector(
const T0& alpha,
731 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
732 const Vector<T2, Storage2, Allocator2>& X,
733 const T3& beta, Vector<T4, Storage4, Allocator4>& Y)
737 #ifdef SELDON_CHECK_DIMENSIONS
738 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
744 SetComplexZero(zero);
746 long* ptr = M.GetPtr();
747 int* ind = M.GetInd();
748 typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
751 for (
int i = 0; i < ma; i++)
754 for (
long j = ptr[i]; j < ptr[i+1]; j++)
755 temp += data[j] * X(ind[j]);
756 Y(i) += alpha * temp;
762 class T1,
class Prop1,
class Allocator1,
763 class T2,
class Storage2,
class Allocator2,
765 class T4,
class Allocator4>
766 void MltAddVector(
const T0& alpha,
767 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
768 const Vector<T2, Storage2, Allocator2>& X,
769 const T3& beta, Vector<T4, Collection, Allocator4>& Y)
773 #ifdef SELDON_CHECK_DIMENSIONS
774 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
779 typename T4::value_type zero;
780 SetComplexZero(zero);
781 typename T4::value_type temp;
783 long* ptr = M.GetPtr();
784 int* ind = M.GetInd();
785 typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
788 for (
int i = 0; i < ma; i++)
791 for (
long j = ptr[i]; j < ptr[i+1]; j++)
792 temp += data[j] * X(ind[j]);
793 Y(i) += alpha * temp;
799 class T1,
class Prop1,
class Allocator1,
800 class T2,
class Storage2,
class Allocator2,
802 class T4,
class Storage4,
class Allocator4>
803 void MltAddVector(
const T0& alpha,
804 const Matrix<T1, Prop1, ColSparse, Allocator1>& M,
805 const Vector<T2, Storage2, Allocator2>& X,
806 const T3& beta, Vector<T4, Storage4, Allocator4>& Y)
808 #ifdef SELDON_CHECK_DIMENSIONS
809 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
814 long* ptr = M.GetPtr();
815 int* ind = M.GetInd();
816 typename Matrix<T1, Prop1, ColSparse, Allocator1>::pointer
819 for (
int j = 0; j < M.GetN(); j++)
821 for (
long k = ptr[j]; k < ptr[j+1]; k++)
822 Y(ind[k]) += alpha * data[k] * X(j);
831 class T1,
class Prop1,
class Allocator1,
832 class T2,
class Storage2,
class Allocator2,
834 class T4,
class Storage4,
class Allocator4>
835 void MltAddVector(
const T0& alpha,
836 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
837 const Vector<T2, Storage2, Allocator2>& X,
838 const T3& beta, Vector<T4, Storage4, Allocator4>& Y)
842 #ifdef SELDON_CHECK_DIMENSIONS
843 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
850 SetComplexZero(zero);
853 long* ptr = M.GetPtr();
854 int* ind = M.GetInd();
855 typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
858 for (i = 0; i < ma; i++)
861 for (j = ptr[i]; j < ptr[i + 1]; j++)
862 temp += data[j] * X(ind[j]);
863 Y(i) += alpha * temp;
865 for (i = 0; i < ma-1; i++)
866 for (j = ptr[i]; j < ptr[i + 1]; j++)
868 Y(ind[j]) += alpha * data[j] * X(i);
873 class T1,
class Prop1,
class Allocator1,
874 class T2,
class Storage2,
class Allocator2,
876 class T4,
class Storage4,
class Allocator4>
877 void MltAddVector(
const T0& alpha,
878 const Matrix<T1, Prop1, ColSymSparse, Allocator1>& M,
879 const Vector<T2, Storage2, Allocator2>& X,
880 const T3& beta, Vector<T4, Storage4, Allocator4>& Y)
884 #ifdef SELDON_CHECK_DIMENSIONS
885 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
892 SetComplexZero(zero);
895 long* ptr = M.GetPtr();
896 int* ind = M.GetInd();
897 typename Matrix<T1, Prop1, ColSymSparse, Allocator1>::pointer
900 for (i = 0; i < ma; i++)
903 for (j = ptr[i]; j < ptr[i + 1]; j++)
905 temp += data[j] * X(ind[j]);
907 Y(i) += alpha * temp;
909 for (j = ptr[i]; j < ptr[i + 1]; j++)
910 Y(ind[j]) += alpha * data[j] * X(i);
916 class T1,
class Prop1,
class Allocator1,
917 class T2,
class Allocator2,
919 class T4,
class Allocator4>
920 void MltAddVector(
const T0& alpha,
921 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
922 const Vector<T2, Collection, Allocator2>& X,
923 const T3& beta, Vector<T4, Collection, Allocator4>& Y)
927 #ifdef SELDON_CHECK_DIMENSIONS
928 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
934 typename T4::value_type zero;
935 SetComplexZero(zero);
936 typename T4::value_type temp;
938 long* ptr = M.GetPtr();
939 int* ind = M.GetInd();
940 typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
943 for (i = 0; i < ma; i++)
946 for (j = ptr[i]; j < ptr[i + 1]; j++)
947 temp += data[j] * X(ind[j]);
948 Y(i) += alpha * temp;
950 for (i = 0; i < ma-1; i++)
951 for (j = ptr[i]; j < ptr[i + 1]; j++)
953 Y(ind[j]) += alpha * data[j] * X(i);
961 class T1,
class Prop1,
class Allocator1,
962 class T2,
class Storage2,
class Allocator2,
964 class T4,
class Allocator4>
965 void MltAddVector(
const T0& alpha,
966 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
967 const Vector<T2, Storage2, Allocator2>& X,
968 const T3& beta, Vector<T4, Collection, Allocator4>& Y)
972 #ifdef SELDON_CHECK_DIMENSIONS
973 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
979 typename T4::value_type zero;
980 SetComplexZero(zero);
981 typename T4::value_type temp;
983 long* ptr = M.GetPtr();
984 int* ind = M.GetInd();
985 typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
988 for (i = 0; i < ma; i++)
991 for (j = ptr[i]; j < ptr[i + 1]; j++)
992 temp += data[j] * X(ind[j]);
993 Y(i) += alpha * temp;
995 for (i = 0; i < ma-1; i++)
996 for (j = ptr[i]; j < ptr[i + 1]; j++)
998 Y(ind[j]) += alpha * data[j] * X(i);
1006 class T1,
class Prop1,
class Allocator1,
1007 class T2,
class Storage2,
class Allocator2,
1009 class T4,
class Storage4,
class Allocator4>
1010 void MltAddVector(
const T0& alpha,
1011 const SeldonTranspose& Trans,
1012 const Matrix<T1, Prop1, RowSparse, Allocator1>& M,
1013 const Vector<T2, Storage2, Allocator2>& X,
1014 const T3& beta, Vector<T4, Storage4, Allocator4>& Y)
1016 if (Trans.NoTrans())
1018 MltAdd(alpha, M, X, beta, Y);
1026 #ifdef SELDON_CHECK_DIMENSIONS
1027 CheckDim(Trans, M, X, Y,
"MltAdd(alpha, SeldonTrans, M, X, beta, Y)");
1032 long* ptr = M.GetPtr();
1033 int* ind = M.GetInd();
1034 typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
1039 for (i = 0; i < ma; i++)
1040 for (j = ptr[i]; j < ptr[i + 1]; j++)
1041 Y(ind[j]) += alpha * data[j] * X(i);
1045 for (i = 0; i < ma; i++)
1046 for (j = ptr[i]; j < ptr[i + 1]; j++)
1047 Y(ind[j]) += alpha * conjugate(data[j]) * X(i);
1053 class T1,
class Prop1,
class Allocator1,
1054 class T2,
class Storage2,
class Allocator2,
1056 class T4,
class Storage4,
class Allocator4>
1057 void MltAddVector(
const T0& alpha,
1058 const SeldonTranspose& Trans,
1059 const Matrix<T1, Prop1, ColSparse, Allocator1>& M,
1060 const Vector<T2, Storage2, Allocator2>& X,
1061 const T3& beta, Vector<T4, Storage4, Allocator4>& Y)
1063 if (Trans.NoTrans())
1065 MltAdd(alpha, M, X, beta, Y);
1071 #ifdef SELDON_CHECK_DIMENSIONS
1072 CheckDim(Trans, M, X, Y,
"MltAdd(alpha, SeldonTrans, M, X, beta, Y)");
1078 SetComplexZero(zero);
1080 long* ptr = M.GetPtr();
1081 int* ind = M.GetInd();
1082 typename Matrix<T1, Prop1, ColSparse, Allocator1>::pointer
1087 for (i = 0; i < M.GetN(); i++)
1090 for (j = ptr[i]; j < ptr[i + 1]; j++)
1091 temp += data[j] * X(ind[j]);
1093 Y(i) += alpha * temp;
1098 for (i = 0; i < M.GetN(); i++)
1101 for (j = ptr[i]; j < ptr[i + 1]; j++)
1102 temp += conjugate(data[j]) * X(ind[j]);
1104 Y(i) += alpha * temp;
1114 class T1,
class Prop1,
class Allocator1,
1115 class T2,
class Storage2,
class Allocator2,
1117 class T4,
class Storage4,
class Allocator4>
1118 void MltAddVector(
const T0& alpha,
1119 const SeldonTranspose& Trans,
1120 const Matrix<T1, Prop1, RowSymSparse, Allocator1>& M,
1121 const Vector<T2, Storage2, Allocator2>& X,
1122 const T3& beta, Vector<T4, Storage4, Allocator4>& Y)
1124 if (!Trans.ConjTrans())
1126 MltAddVector(alpha, M, X, beta, Y);
1132 #ifdef SELDON_CHECK_DIMENSIONS
1133 CheckDim(Trans, M, X, Y,
"MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
1140 SetComplexZero(zero);
1142 long* ptr = M.GetPtr();
1143 int* ind = M.GetInd();
1144 T1* data = M.GetData();
1146 for (i = 0; i < ma; i++)
1149 for (j = ptr[i]; j < ptr[i + 1]; j++)
1150 temp += conjugate(data[j]) * X(ind[j]);
1152 Y(i) += alpha * temp;
1154 for (i = 0; i < ma - 1; i++)
1155 for (j = ptr[i]; j < ptr[i + 1]; j++)
1157 Y(ind[j]) += alpha * conjugate(data[j]) * X(i);
1162 class T1,
class Prop1,
class Allocator1,
1163 class T2,
class Storage2,
class Allocator2,
1165 class T4,
class Storage4,
class Allocator4>
1166 void MltAddVector(
const T0& alpha,
1167 const SeldonTranspose& Trans,
1168 const Matrix<T1, Prop1, ColSymSparse, Allocator1>& M,
1169 const Vector<T2, Storage2, Allocator2>& X,
1170 const T3& beta, Vector<T4, Storage4, Allocator4>& Y)
1172 if (!Trans.ConjTrans())
1174 MltAddVector(alpha, M, X, beta, Y);
1180 #ifdef SELDON_CHECK_DIMENSIONS
1181 CheckDim(Trans, M, X, Y,
"MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
1188 SetComplexZero(zero);
1190 long* ptr = M.GetPtr();
1191 int* ind = M.GetInd();
1192 T1* data = M.GetData();
1194 for (i = 0; i < ma; i++)
1197 for (j = ptr[i]; j < ptr[i + 1]; j++)
1198 temp += conjugate(data[j]) * X(ind[j]);
1200 Y(i) += alpha * temp;
1202 for (j = ptr[i]; j < ptr[i + 1]; j++)
1204 Y(ind[j]) += alpha * conjugate(data[j]) * X(i);
1232 class T1,
class Prop1,
class Storage1,
class Allocator1,
1233 class T2,
class Storage2,
class Allocator2,
1235 class T4,
class Storage4,
class Allocator4>
1236 void MltAddVector(
const T0& alpha,
1245 #ifdef SELDON_CHECK_DIMENSIONS
1246 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
1250 if (Storage1::Sparse)
1251 throw WrongArgument(
"MltAdd",
"This function is intended to dense"
1252 " matrices only and not to sparse matrices");
1257 SetComplexZero(zero);
1260 for (
int i = 0; i < ma; i++)
1263 for (
int j = 0; j < na; j++)
1264 temp += M(i, j) * X(j);
1265 Y(i) += alpha * temp;
1285 class T1,
class Prop1,
class Storage1,
class Allocator1,
1286 class T2,
class Storage2,
class Allocator2,
1288 class T4,
class Allocator4>
1289 void MltAddVector(
const T0& alpha,
1298 #ifdef SELDON_CHECK_DIMENSIONS
1299 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
1302 if (Storage1::Sparse)
1303 throw WrongArgument(
"MltAdd",
"This function is intended to dense"
1304 " matrices only and not to sparse matrices");
1308 typename T4::value_type zero;
1309 SetComplexZero(zero);
1310 typename T4::value_type temp;
1312 for (
int i = 0; i < ma; i++)
1315 for (
int j = 0; j < na; j++)
1316 temp += M(i, j) * X(j);
1317 Y(i) += alpha * temp;
1337 class T1,
class Prop1,
class Allocator1,
1338 class T2,
class Allocator2,
1340 class T4,
class Allocator4>
1341 void MltAddVector(
const T0& alpha,
1347 int ma = M.GetMmatrix();
1348 int na = M.GetNmatrix();
1350 #ifdef SELDON_CHECK_DIMENSIONS
1351 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
1353 typedef typename T4::value_type value_type;
1355 Mlt(value_type(beta), Y);
1357 for (
int i = 0; i < ma; i++)
1358 for (
int j = 0; j < na; j++)
1359 MltAdd(alpha, M.GetMatrix(i, j), X.GetVector(j), value_type(1.),
1379 class T1,
class Prop1,
class Allocator1,
1380 class T2,
class Allocator2,
1382 class T4,
class Allocator4>
1383 void MltAddVector(
const T0& alpha,
1389 int ma = M.GetMmatrix();
1390 int na = M.GetNmatrix();
1392 #ifdef SELDON_CHECK_DIMENSIONS
1393 CheckDim(M, X, Y,
"MltAdd(alpha, M, X, beta, Y)");
1395 typedef typename T4::value_type value_type;
1397 Mlt(value_type(beta), Y);
1399 for (
int i = 0; i < ma; i++)
1400 for (
int j = 0; j < na; j++)
1401 MltAdd(alpha, M.GetMatrix(i, j), X.GetVector(j), value_type(1.),
1424 class T1,
class Prop1,
class Storage1,
class Allocator1,
1425 class T2,
class Storage2,
class Allocator2,
1427 class T4,
class Storage4,
class Allocator4>
1428 void MltAddVector(
const T0& alpha,
1435 if (Trans.NoTrans())
1437 MltAddVector(alpha, M, X, beta, Y);
1444 #ifdef SELDON_CHECK_DIMENSIONS
1445 CheckDim(Trans, M, X, Y,
"MltAdd(alpha, trans, M, X, beta, Y)");
1448 if (Storage1::Sparse)
1449 throw WrongArgument(
"MltAdd",
"This function is intended to dense"
1450 " matrices only and not to sparse matrices");
1453 SetComplexZero(zero3);
1455 SetComplexZero(zero);
1466 for (
int i = 0; i < na; i++)
1469 for (
int j = 0; j < ma; j++)
1470 temp += M(j, i) * X(j);
1471 Y(i) += alpha * temp;
1476 for (
int i = 0; i < na; i++)
1479 for (
int j = 0; j < ma; j++)
1480 temp += conjugate(M(j, i)) * X(j);
1481 Y(i) += alpha * temp;
1503 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
1504 class T1,
class Storage1,
class Allocator1>
1513 #ifdef SELDON_CHECK_DIMENSIONS
1517 "The matrix must be squared.");
1523 if (Storage0::Sparse)
1524 throw WrongArgument(
"Gauss",
"This function is intended to dense"
1525 " matrices only and not to sparse matrices");
1527 for (k = 0; k < ma - 1; k++)
1528 for (i = k + 1; i < ma; i++)
1530 r = M(i, k) / M(k, k);
1531 for (j = k + 1; j < ma; j++)
1532 M(i, j) -= r * M(k, j);
1536 X(ma - 1) = X(ma - 1) / M(ma - 1, ma - 1);
1537 for (k = ma - 2; k > -1; k--)
1540 for (j = k + 1; j < ma; j++)
1541 S -= M(k, j) * X(j);
1563 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
1564 class T1,
class Storage1,
class Allocator1,
1565 class T2,
class Storage2,
class Allocator2>
1569 int iter,
int type_algo)
1576 #ifdef SELDON_CHECK_DIMENSIONS
1579 throw WrongDim(
"GaussSeidel(M, X, Y, iter)",
1580 "The matrix must be squared.");
1582 CheckDim(M, X, Y,
"GaussSeidel(M, X, Y, iter)");
1586 if (Storage0::Sparse)
1587 throw WrongArgument(
"GaussSeidel",
"This function is intended to dense"
1588 " matrices only and not to sparse matrices");
1591 SetComplexZero(zero);
1592 if (type_algo%2 == 0)
1593 for (i = 0; i < iter; i++)
1594 for (j = 0; j < na; j++)
1597 for (k = 0; k < j; k++)
1598 temp -= M(j, k) * Y(k);
1599 for (k = j + 1; k < na; k++)
1600 temp -= M(j, k) * Y(k);
1601 Y(j) = (X(j) + temp) / M(j, j);
1604 if (type_algo%3 == 0)
1605 for (i = 0; i < iter; i++)
1606 for (j = na-1; j >= 0; j--)
1609 for (k = 0; k < j; k++)
1610 temp -= M(j, k) * Y(k);
1611 for (k = j + 1; k < na; k++)
1612 temp -= M(j, k) * Y(k);
1613 Y(j) = (X(j) + temp) / M(j, j);
1634 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
1635 class T1,
class Storage1,
class Allocator1,
1636 class T2,
class Storage2,
class Allocator2,
1641 const T3& omega,
int iter,
int type_ssor)
1649 #ifdef SELDON_CHECK_DIMENSIONS
1652 throw WrongDim(
"SOR(M, X, Y, omega, iter)",
1653 "The matrix must be squared.");
1655 CheckDim(M, X, Y,
"SOR(M, X, Y, omega, iter)");
1659 if (Storage0::Sparse)
1660 throw WrongArgument(
"SOR",
"This function is intended to dense"
1661 " matrices only and not to sparse matrices");
1664 if (type_ssor%2 == 0)
1665 for (i = 0; i < iter; i++)
1666 for (j = 0; j < na; j++)
1668 SetComplexZero(temp);
1669 for (k = 0; k < j; k++)
1670 temp -= M(j, k) * Y(k);
1671 for (k = j + 1; k < na; k++)
1672 temp -= M(j, k) * Y(k);
1673 Y(j) = (one - omega) * Y(j) + omega * (X(j) + temp) / M(j, j);
1676 if (type_ssor%3 == 0)
1677 for (i = 0; i < iter; i++)
1678 for (j = na-1; j >= 0; j--)
1680 SetComplexZero(temp);
1681 for (k = 0; k < j; k++)
1682 temp -= M(j, k) * Y(k);
1683 for (k = j + 1; k < na; k++)
1684 temp -= M(j, k) * Y(k);
1685 Y(j) = (one - omega) * Y(j) + omega * (X(j) + temp) / M(j, j);
1698 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
1699 class T1,
class Storage1,
class Allocator1,
1700 class T2,
class Storage2,
class Allocator2,
1706 const T3& omega,
int iter,
int type_ssor)
1708 if (transM.NoTrans())
1709 return SorVector(M, Y, X, omega, iter, type_ssor);
1717 #ifdef SELDON_CHECK_DIMENSIONS
1720 throw WrongDim(
"SOR(M, X, Y, omega, iter)",
1721 "The matrix must be squared.");
1723 CheckDim(M, X, Y,
"SOR(M, X, Y, omega, iter)");
1727 if (Storage0::Sparse)
1728 throw WrongArgument(
"SOR",
"This function is intended to dense"
1729 " matrices only and not to sparse matrices");
1732 if (type_ssor%2 == 0)
1733 for (i = 0; i < iter; i++)
1734 for (j = 0; j < na; j++)
1736 SetComplexZero(temp);
1737 for (k = 0; k < j; k++)
1738 temp -= M(k, j) * Y(k);
1739 for (k = j + 1; k < na; k++)
1740 temp -= M(k, j) * Y(k);
1741 Y(j) = (one - omega) * Y(j) + omega * (X(j) + temp) / M(j, j);
1744 if (type_ssor%3 == 0)
1745 for (i = 0; i < iter; i++)
1746 for (j = na-1; j >= 0; j--)
1748 SetComplexZero(temp);
1749 for (k = 0; k < j; k++)
1750 temp -= M(k, j) * Y(k);
1751 for (k = j + 1; k < na; k++)
1752 temp -= M(k, j) * Y(k);
1753 Y(j) = (one - omega) * Y(j) + omega * (X(j) + temp) / M(j, j);
1780 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
1781 class T1,
class Storage1,
class Allocator1>
1790 #ifdef SELDON_CHECK_DIMENSIONS
1794 "The matrix must be squared.");
1800 if (Storage0::Sparse)
1801 throw WrongArgument(
"SolveLU",
"This function is intended to dense"
1802 " matrices only and not to sparse matrices");
1805 for (i = 0; i < ma; i++)
1807 SetComplexZero(temp);
1808 for (k = 0; k < i; k++)
1809 temp += M(i, k) * Y(k);
1810 Y(i) = (Y(i) - temp) / M(i, i);
1813 for (i = ma - 2; i > -1; i--)
1815 SetComplexZero(temp);
1816 for (k = i + 1; k < ma; k++)
1817 temp += M(i, k) * Y(k);
1839 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
1840 class T1,
class Storage1,
class Allocator1>
1844 if (Storage0::Sparse)
1845 throw WrongArgument(
"GetAndSolveLU",
"This function is intended to dense"
1846 " matrices only and not to sparse matrices");
1848 #ifdef SELDON_WITH_LAPACK
1868 template <
class T0,
class Prop0,
class Allocator0,
1869 class T1,
class Allocator1>
1880 #ifdef SELDON_CHECK_DIMENSIONS
1883 throw WrongDim(
"Solve(UpLo, TransA, DiagA, A, X, Y)",
1884 "The matrix must be squared.");
1886 CheckDim(A, X,
"Solve(UpLo, TransA, DiagA, A, X, Y)");
1887 CheckDim(A, Y,
"Solve(UpLo, TransA, DiagA, A, X, Y)");
1892 T0* data = A.GetData();
1893 long* ptr = A.GetPtr();
1894 int* ind = A.GetInd();
1895 T0 zero; SetComplexZero(zero);
1899 if (TransA.NoTrans())
1901 if (DiagA.NonUnit())
1903 for (
int i = 0; i < ma; i++)
1909 val -= data[j]*Y(ind[j]);
1913 #ifdef SELDON_CHECK_BOUNDS
1914 if ( (j >= ptr[i+1]) || (ind[j] != i) || (data[j] == zero))
1916 " a non-null diagonal");
1924 for (
int i = 0; i < ma; i++)
1928 while ((j < ptr[i+1]) && (ind[j] < i))
1930 val -= data[j]*Y(ind[j]);
1938 else if (TransA.Trans())
1940 if (DiagA.NonUnit())
1942 for (
int i = ma-1; i >= 0; i--)
1944 long j = ptr[i+1]-1;
1948 #ifdef SELDON_CHECK_BOUNDS
1949 if ( (j < ptr[i]) || (ind[j] != i) || (data[j] == zero))
1951 " a non-null diagonal");
1958 Y(ind[j]) -= data[j]*Y(i);
1965 for (
int i = ma-1; i >= 0; i--)
1968 while ( (j < ptr[i+1]) && (ind[j] < i))
1970 Y(ind[j]) -= data[j]*Y(i);
1978 if (DiagA.NonUnit())
1980 for (
int i = ma-1; i >= 0; i--)
1982 long j = ptr[i+1]-1;
1986 #ifdef SELDON_CHECK_BOUNDS
1987 if ( (j < ptr[i]) || (ind[j] != i) || (data[j] == zero))
1989 " a non-null diagonal");
1992 Y(i) /= conjugate(data[j]);
1996 Y(ind[j]) -= conjugate(data[j])*Y(i);
2003 for (
int i = ma-1; i >= 0; i--)
2006 while ((j < ptr[i+1]) && (ind[j] < i))
2008 Y(ind[j]) -= conjugate(data[j])*Y(i);
2017 if (TransA.NoTrans())
2019 if (DiagA.NonUnit())
2021 for (
int i = ma-1; i >= 0; i--)
2024 long j = ptr[i+1]-1;
2027 val -= data[j]*Y(ind[j]);
2031 #ifdef SELDON_CHECK_BOUNDS
2032 if ( (j < ptr[i]) || (ind[j] != i) || (data[j] == zero))
2034 " a non-null diagonal");
2042 for (
int i = ma-1; i >= 0; i--)
2045 long j = ptr[i+1]-1;
2046 while ( (j >= ptr[i]) && (ind[j] > i))
2048 val -= data[j]*Y(ind[j]);
2056 else if (TransA.Trans())
2058 if (DiagA.NonUnit())
2060 for (
int i = 0; i < ma; i++)
2066 #ifdef SELDON_CHECK_BOUNDS
2067 if ( (j >= ptr[i+1]) || (ind[j] != i) || (data[j] == zero) )
2069 " a non-null diagonal");
2074 while (j < ptr[i+1])
2076 Y(ind[j]) -= data[j]*Y(i);
2083 for (
int i = 0; i < ma; i++)
2085 long j = ptr[i+1]-1;
2086 while ( (j >= ptr[i]) && (ind[j] > i))
2088 Y(ind[j]) -= data[j]*Y(i);
2096 if (DiagA.NonUnit())
2098 for (
int i = 0; i < ma; i++)
2104 #ifdef SELDON_CHECK_BOUNDS
2105 if ( (j >= ptr[i+1]) || (ind[j] != i) || (data[j] == zero) )
2107 " a non-null diagonal");
2110 Y(i) /= conjugate(data[j]);
2112 while (j < ptr[i+1])
2114 Y(ind[j]) -= conjugate(data[j])*Y(i);
2121 for (
int i = 0; i < ma; i++)
2123 long j = ptr[i+1]-1;
2124 while ( (j >= ptr[i]) && (ind[j] > i))
2126 Y(ind[j]) -= conjugate(data[j])*Y(i);
2154 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
2155 class T1,
class Storage1,
class Allocator1,
2156 class T2,
class Storage2,
class Allocator2>
2162 if (X.GetM() != M.GetN() || Y.GetM() != M.GetM())
2165 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2168 string Mchar(
"M"), Xchar(
"X"), Ychar(
"Y");
2172 string(
"Operation M X + Y -> Y not permitted:")
2173 +
string(
"\n M (") + Mchar +
string(
") is a ")
2175 +
string(
" matrix;\n X (") + Xchar
2176 +
string(
") is vector of length ")
2177 +
to_str(X.GetLength()) +
string(
";\n Y (")
2178 + Ychar +
string(
") is vector of length ")
2179 +
to_str(Y.GetLength()) +
string(
"."));
2194 template <
class T0,
class Prop0,
class Allocator0,
2195 class T1,
class Allocator1,
2196 class T2,
class Allocator2>
2202 if (X.GetNvector() != M.GetNmatrix() || Y.GetNvector() != M.GetMmatrix())
2204 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2207 string Mchar(
"M"), Xchar(
"X"), Ychar(
"Y");
2211 string(
"Operation M X + Y -> Y not permitted:")
2212 +
string(
"\n M (") + Mchar +
string(
") is a ")
2214 +
string(
" matrix;\n X (") + Xchar
2215 +
string(
") is vector of length ")
2216 +
to_str(X.GetNvector()) +
string(
";\n Y (")
2217 + Ychar +
string(
") is vector of length ")
2218 +
to_str(Y.GetNvector()) +
string(
"."));
2233 template <
class T0,
class Prop0,
class Allocator0,
2234 class T1,
class Allocator1,
2235 class T2,
class Allocator2>
2241 if (X.GetNvector() != M.GetNmatrix() || Y.GetNvector() != M.GetMmatrix())
2243 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2246 string Mchar(
"M"), Xchar(
"X"), Ychar(
"Y");
2250 string(
"Operation M X + Y -> Y not permitted:")
2251 +
string(
"\n M (") + Mchar +
string(
") is a ")
2253 +
string(
" matrix;\n X (") + Xchar
2254 +
string(
") is vector of length ")
2255 +
to_str(X.GetNvector()) +
string(
";\n Y (")
2256 + Ychar +
string(
") is vector of length ")
2257 +
to_str(Y.GetNvector()) +
string(
"."));
2272 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
2273 class T1,
class Allocator1,
2274 class T2,
class Storage2,
class Allocator2>
2280 if (X.GetM() != M.GetN() || Y.GetM() != M.GetM())
2282 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2285 string Mchar(
"M"), Xchar(
"X"), Ychar(
"Y");
2289 string(
"Operation M X + Y -> Y not permitted:")
2290 +
string(
"\n M (") + Mchar +
string(
") is a ")
2292 +
string(
" matrix;\n X (") + Xchar
2293 +
string(
") is vector of length ")
2294 +
to_str(X.GetLength()) +
string(
";\n Y (")
2295 + Ychar +
string(
") is vector of length ")
2296 +
to_str(Y.GetLength()) +
string(
"."));
2314 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
2315 class T1,
class Storage1,
class Allocator1,
2316 class T2,
class Storage2,
class Allocator2>
2321 string function,
string op)
2323 if (op ==
"M X + Y -> Y")
2325 op = string(
"Operation M' X + Y -> Y not permitted:");
2326 else if (trans.ConjTrans())
2327 op = string(
"Operation M* X + Y -> Y not permitted:");
2329 op = string(
"Operation M X + Y -> Y not permitted:");
2331 op = string(
"Operation ") + op + string(
" not permitted:");
2333 if (X.GetM() != M.GetN(trans) || Y.GetM() != M.GetM(trans))
2335 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2338 string Mchar(
"M"), Xchar(
"X"), Ychar(
"Y");
2341 throw WrongDim(
function, op +
string(
"\n M (") + Mchar
2342 +
string(
") is a ") +
to_str(M.GetM()) +
string(
" x ")
2343 +
to_str(M.GetN()) +
string(
" matrix;\n X (")
2344 + Xchar +
string(
") is vector of length ")
2345 +
to_str(X.GetLength()) +
string(
";\n Y (")
2346 + Ychar +
string(
") is vector of length ")
2347 +
to_str(Y.GetLength()) +
string(
"."));
2362 template <
class T0,
class Prop0,
class Storage0,
class Allocator0,
2363 class T1,
class Storage1,
class Allocator1>
2366 string function,
string op)
2368 if (X.GetM() != M.GetN())
2370 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2373 string Mchar(
"M"), Xchar(
"X");
2376 throw WrongDim(
function,
string(
"Operation ") + op +
" not permitted:"
2377 +
string(
"\n M (") + Mchar +
string(
") is a ")
2379 +
string(
" matrix;\n X (") + Xchar
2380 +
string(
") is vector of length ")
2381 +
to_str(X.GetLength()) +
string(
"."));