Functions_MatVect.cxx
1 // Copyright (C) 2001-2011 Vivien Mallet
2 // Copyright (C) 2001-2011 Marc DuruflĂ©
3 //
4 // This file is part of the linear-algebra library Seldon,
5 // http://seldon.sourceforge.net/.
6 //
7 // Seldon is free software; you can redistribute it and/or modify it under the
8 // terms of the GNU Lesser General Public License as published by the Free
9 // Software Foundation; either version 2.1 of the License, or (at your option)
10 // any later version.
11 //
12 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 // more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with Seldon. If not, see http://www.gnu.org/licenses/.
19 
20 
21 #ifndef SELDON_FILE_FUNCTIONS_MATVECT_CXX
22 #define SELDON_FILE_FUNCTIONS_MATVECT_CXX
23 
24 
25 #include "Functions_MatVect.hxx"
26 
27 
28 /*
29  Functions defined in this file:
30 
31  alpha M X + beta Y -> Y
32  MltAdd(alpha, M, X, beta, Y)
33 
34  Gauss(M, X)
35 
36  GaussSeidel(M, Y, X, iter)
37 
38  SOR(M, Y, X, omega, iter)
39 
40  SolveLU(M, Y)
41 
42  GetAndSolveLU(M, Y)
43 */
44 
45 
46 namespace Seldon
47 {
48 
50  // MLT //
51 
52 
53  // Y = M X for RowSparse matrices
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)
60  {
61  int ma = M.GetM();
62 
63 #ifdef SELDON_CHECK_DIMENSIONS
64  CheckDim(M, X, Y, "Mlt(M, X, Y)");
65 #endif
66 
67  T4 zero, temp;
68  SetComplexZero(zero);
69 
70  long* ptr = M.GetPtr();
71  int* ind = M.GetInd();
72  T1* data = M.GetData();
73 
74  for (int i = 0; i < ma; i++)
75  {
76  temp = zero;
77  for (long j = ptr[i]; j < ptr[i+1]; j++)
78  temp += data[j] * X(ind[j]);
79 
80  Y(i) = temp;
81  }
82  }
83 
84 
85  // Y = M X for ColSparse matrices
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)
92  {
93 #ifdef SELDON_CHECK_DIMENSIONS
94  CheckDim(M, X, Y, "Mlt(M, X, Y)");
95 #endif
96 
97  long* ptr = M.GetPtr();
98  int* ind = M.GetInd();
99  T1* data = M.GetData();
100  Y.Zero();
101 
102  for (int j = 0; j < M.GetN(); j++)
103  {
104  for (long k = ptr[j]; k < ptr[j+1]; k++)
105  Y(ind[k]) += data[k] * X(j);
106  }
107  }
108 
109 
110  // Y = M X for RowSymSparse
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)
117  {
118  int ma = M.GetM();
119 
120 #ifdef SELDON_CHECK_DIMENSIONS
121  CheckDim(M, X, Y, "Mlt(M, X, Y)");
122 #endif
123 
124  int i; long j;
125  T4 zero, temp;
126  SetComplexZero(zero);
127 
128  long* ptr = M.GetPtr();
129  int* ind = M.GetInd();
130  T1* data = M.GetData();
131 
132  for (i = 0; i < ma; i++)
133  {
134  temp = zero;
135  for (j = ptr[i]; j < ptr[i + 1]; j++)
136  temp += data[j] * X(ind[j]);
137 
138  Y(i) = temp;
139  }
140 
141  for (i = 0; i < ma-1; i++)
142  for (j = ptr[i]; j < ptr[i + 1]; j++)
143  if (ind[j] != i)
144  Y(ind[j]) += data[j] * X(i);
145  }
146 
147 
148  // Y = M X for ColSymSparse
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)
155  {
156  int ma = M.GetM();
157 
158 #ifdef SELDON_CHECK_DIMENSIONS
159  CheckDim(M, X, Y, "Mlt(M, X, Y)");
160 #endif
161 
162  int i; long j;
163  T4 zero, temp;
164  SetComplexZero(zero);
165 
166  long* ptr = M.GetPtr();
167  int* ind = M.GetInd();
168  T1* data = M.GetData();
169 
170  for (i = 0; i < ma; i++)
171  {
172  temp = zero;
173  for (j = ptr[i]; j < ptr[i + 1]; j++)
174  if (ind[j] != i)
175  temp += data[j] * X(ind[j]);
176 
177  Y(i) = temp;
178  }
179 
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);
183 
184  }
185 
186 
187  // Y = M X or M^T X or M^H X for RowSparse
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)
195  {
196  if (Trans.NoTrans())
197  {
198  MltVector(M, X, Y);
199  return;
200  }
201 
202  int i; long j;
203  int ma = M.GetM();
204 
205 #ifdef SELDON_CHECK_DIMENSIONS
206  CheckDim(Trans, M, X, Y, "Mlt(SeldonTrans, M, X, Y)");
207 #endif
208 
209  long* ptr = M.GetPtr();
210  int* ind = M.GetInd();
211  T1* data = M.GetData();
212  Y.Zero();
213 
214  if (Trans.Trans())
215  {
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);
219  }
220  else
221  {
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);
225  }
226  }
227 
228 
229  // Y = M X or M^T X or M^H X for ColSparse
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)
237  {
238  if (Trans.NoTrans())
239  {
240  MltVector(M, X, Y);
241  return;
242  }
243 
244  int i; long j;
245 
246 #ifdef SELDON_CHECK_DIMENSIONS
247  CheckDim(Trans, M, X, Y, "Mlt(SeldonTrans, M, X, Y)");
248 #endif
249 
250  T4 temp, zero;
251  SetComplexZero(zero);
252 
253  long* ptr = M.GetPtr();
254  int* ind = M.GetInd();
255  T1* data = M.GetData();
256 
257  if (Trans.Trans())
258  {
259  for (i = 0; i < M.GetN(); i++)
260  {
261  temp = zero;
262  for (j = ptr[i]; j < ptr[i + 1]; j++)
263  temp += data[j] * X(ind[j]);
264 
265  Y(i) = temp;
266  }
267  }
268  else
269  {
270  for (i = 0; i < M.GetN(); i++)
271  {
272  temp = zero;
273  for (j = ptr[i]; j < ptr[i + 1]; j++)
274  temp += conjugate(data[j]) * X(ind[j]);
275 
276  Y(i) = temp;
277  }
278  }
279  }
280 
281 
282  // Y = M X or M^T X or M^H X for RowSymSparse
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)
290  {
291  if (!Trans.ConjTrans())
292  {
293  MltVector(M, X, Y);
294  return;
295  }
296 
297  int ma = M.GetM();
298 
299 #ifdef SELDON_CHECK_DIMENSIONS
300  CheckDim(Trans, M, X, Y, "Mlt(SeldonConjTrans, M, X, Y)");
301 #endif
302 
303  int i; long j;
304  T4 zero, temp;
305  SetComplexZero(zero);
306 
307  long* ptr = M.GetPtr();
308  int* ind = M.GetInd();
309  T1* data = M.GetData();
310 
311  for (i = 0; i < ma; i++)
312  {
313  temp = zero;
314  for (j = ptr[i]; j < ptr[i + 1]; j++)
315  temp += conjugate(data[j]) * X(ind[j]);
316 
317  Y(i) = temp;
318  }
319 
320  for (i = 0; i < ma - 1; i++)
321  for (j = ptr[i]; j < ptr[i + 1]; j++)
322  if (ind[j] != i)
323  Y(ind[j]) += conjugate(data[j]) * X(i);
324  }
325 
326 
327  // Y = M X or M^T X or M^H X for ColSymSparse
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)
335  {
336  if (!Trans.ConjTrans())
337  {
338  MltVector(M, X, Y);
339  return;
340  }
341 
342  int ma = M.GetM();
343 
344 #ifdef SELDON_CHECK_DIMENSIONS
345  CheckDim(Trans, M, X, Y, "Mlt(SeldonConjTrans, M, X, Y)");
346 #endif
347 
348  int i; long j;
349  T4 zero, temp;
350  SetComplexZero(zero);
351 
352  long* ptr = M.GetPtr();
353  int* ind = M.GetInd();
354  T1* data = M.GetData();
355 
356  for (i = 0; i < ma; i++)
357  {
358  temp = zero;
359  for (j = ptr[i]; j < ptr[i + 1]; j++)
360  temp += conjugate(data[j]) * X(ind[j]);
361 
362  Y(i) = temp;
363  }
364 
365  for (i = 0; i < ma; i++)
366  for (j = ptr[i]; j < ptr[i + 1]; j++)
367  if (ind[j] != i)
368  Y(ind[j]) += conjugate(data[j]) * X(i);
369  }
370 
371 
372  // Y = M X for any matrix
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)
379  {
380  int ma = M.GetM();
381  int na = M.GetN();
382 
383 #ifdef SELDON_CHECK_DIMENSIONS
384  CheckDim(M, X, Y, "Mlt(M, X, Y)");
385 #endif
386 
387  // aborting computation if the matrix is sparse
388  if (Storage1::Sparse)
389  throw WrongArgument("Mlt", "This function is intended to dense"
390  " matrices only and not to sparse matrices");
391 
392  T4 zero, temp;
393  SetComplexZero(zero);
394 
395  for (int i = 0; i < ma; i++)
396  {
397  temp = zero;
398  for (int j = 0; j < na; j++)
399  temp += M(i, j) * X(j);
400 
401  Y(i) = temp;
402  }
403  }
404 
405 
406  // Y = M X or M^T X or M^H X for any matrix
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)
414  {
415  if (Trans.NoTrans())
416  {
417  MltVector(M, X, Y);
418  return;
419  }
420 
421  int ma = M.GetM();
422  int na = M.GetN();
423 
424 #ifdef SELDON_CHECK_DIMENSIONS
425  CheckDim(Trans, M, X, Y, "Mlt(trans, M, X, Y)");
426 #endif
427 
428  if (Storage1::Sparse)
429  throw WrongArgument("MltAdd", "This function is intended to dense"
430  " matrices only and not to sparse matrices");
431 
432  T4 zero, temp;
433  SetComplexZero(zero);
434 
435  if (Trans.Trans())
436  {
437  for (int i = 0; i < na; i++)
438  {
439  temp = zero;
440  for (int j = 0; j < ma; j++)
441  temp += M(j, i) * X(j);
442 
443  Y(i) = temp;
444  }
445  }
446  else
447  {
448  for (int i = 0; i < na; i++)
449  {
450  temp = zero;
451  for (int j = 0; j < ma; j++)
452  temp += conjugate(M(j, i)) * X(j);
453 
454  Y(i) = temp;
455  }
456  }
457  }
458 
459 
460  // MLT //
462 
463 
465  // MLTADD //
466 
467 
468  /*** PETSc matrices ***/
469 
470 
471  template <class T0,
472  class T1, class Prop1, class Allocator1,
473  class T2, class Allocator2,
474  class T3,
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)
480  {
481 #ifdef SELDON_CHECK_DIMENSIONS
482  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
483 #endif
484  if (beta == T3(0))
485  {
486  if (alpha == T0(0))
487  {
488  Y.Zero();
489  return;
490  }
491  else
492  {
493  MatMult(M.GetPetscMatrix(), X.GetPetscVector(), Y.GetPetscVector());
494  if (alpha != T0(1))
495  VecScale(Y.GetPetscVector(), alpha);
496  return;
497  }
498  }
499  if (alpha == T0(1))
500  {
501  if (beta != T3(1))
502  VecScale(Y.GetPetscVector(), beta);
503  MatMultAdd(M.GetPetscMatrix(), X.GetPetscVector(),
504  Y.GetPetscVector(),Y.GetPetscVector());
505  return;
506  }
507  Vector<T2, PETScSeq, Allocator2> tmp;
508  tmp.Copy(Y);
509  MatMult(M.GetPetscMatrix(), X.GetPetscVector(), tmp.GetPetscVector());
510  VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
511  return;
512  }
513 
514 
515  template <class T0,
516  class T1, class Prop1, class Allocator1,
517  class T2, class Allocator2,
518  class T3,
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)
524  {
525 #ifdef SELDON_CHECK_DIMENSIONS
526  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
527 #endif
528  if (beta == T3(0))
529  {
530  if (alpha == T0(0))
531  {
532  Y.Zero();
533  return;
534  }
535  else
536  {
537  MatMult(M.GetPetscMatrix(), X.GetPetscVector(), Y.GetPetscVector());
538  if (alpha != T0(1))
539  VecScale(Y.GetPetscVector(), alpha);
540  return;
541  }
542  }
543  if (alpha == T0(1))
544  {
545  if (beta != T3(1))
546  VecScale(Y.GetPetscVector(), beta);
547  MatMultAdd(M.GetPetscMatrix(), X.GetPetscVector(),
548  Y.GetPetscVector(),Y.GetPetscVector());
549  return;
550  }
551  Vector<T2, PETScPar, Allocator2> tmp;
552  tmp.Copy(Y);
553  MatMult(M.GetPetscMatrix(), X.GetPetscVector(), tmp.GetPetscVector());
554  VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
555  return;
556  }
557 
558 
559  template <class T0,
560  class T1, class Prop1, class Allocator1,
561  class T2, class Allocator2,
562  class T3,
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)
568  {
569 #ifdef SELDON_CHECK_DIMENSIONS
570  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
571 #endif
572 
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));
577  X_Petsc.Flush();
578 
579  if (beta == T3(0))
580  {
581  if (alpha == T0(0))
582  {
583  Y.Zero();
584  return;
585  }
586  else
587  {
588  MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
589  Y.GetPetscVector());
590  if (alpha != T0(1))
591  VecScale(Y.GetPetscVector(), alpha);
592  return;
593  }
594  }
595  if (alpha == T0(1))
596  {
597  if (beta != T3(1))
598  VecScale(Y.GetPetscVector(), beta);
599  MatMultAdd(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
600  Y.GetPetscVector(),Y.GetPetscVector());
601  return;
602  }
603  Vector<T2, PETScSeq, Allocator2> tmp;
604  tmp.Copy(Y);
605  MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
606  tmp.GetPetscVector());
607  VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
608  return;
609  }
610 
611 
612  template <class T0,
613  class T1, class Prop1, class Allocator1,
614  class T2, class Allocator2,
615  class T3,
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)
621  {
622 #ifdef SELDON_CHECK_DIMENSIONS
623  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
624 #endif
625 
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));
631  X_Petsc.Flush();
632 
633  if (beta == T3(0))
634  {
635  if (alpha == T0(0))
636  {
637  Y.Zero();
638  return;
639  }
640  else
641  {
642  MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
643  Y.GetPetscVector());
644  if (alpha != T0(1))
645  VecScale(Y.GetPetscVector(), alpha);
646  return;
647  }
648  }
649  if (alpha == T0(1))
650  {
651  if (beta != T3(1))
652  VecScale(Y.GetPetscVector(), beta);
653  MatMultAdd(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
654  Y.GetPetscVector(),Y.GetPetscVector());
655  return;
656  }
657  Vector<T2, PETScPar, Allocator2> tmp;
658  tmp.Copy(Y);
659  MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
660  tmp.GetPetscVector());
661  VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
662  return;
663  }
664 
665 
666  template <class T0,
667  class T1, class Prop1, class Allocator1,
668  class T2, class Allocator2,
669  class T3,
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)
675  {
676 #ifdef SELDON_CHECK_DIMENSIONS
677  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
678 #endif
679 
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));
685  X_Petsc.Flush();
686 
687  if (beta == T3(0))
688  {
689  if (alpha == T0(0))
690  {
691  Y.Zero();
692  return;
693  }
694  else
695  {
696  MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
697  Y.GetPetscVector());
698  if (alpha != T0(1))
699  VecScale(Y.GetPetscVector(), alpha);
700  return;
701  }
702  }
703  if (alpha == T0(1))
704  {
705  if (beta != T3(1))
706  VecScale(Y.GetPetscVector(), beta);
707  MatMultAdd(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
708  Y.GetPetscVector(),Y.GetPetscVector());
709  return;
710  }
711  Vector<T2, PETScPar, Allocator2> tmp;
712  tmp.Copy(Y);
713  tmp.SetCommunicator(M.GetCommunicator());
714  MatMult(M.GetPetscMatrix(), X_Petsc.GetPetscVector(),
715  tmp.GetPetscVector());
716  VecAXPBY(Y.GetPetscVector(), alpha, beta, tmp.GetPetscVector());
717  return;
718  }
719 
720 
721 
722  /*** Sparse matrices ***/
723 
724 
725  template <class T0,
726  class T1, class Prop1, class Allocator1,
727  class T2, class Storage2, class Allocator2,
728  class T3,
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)
734  {
735  int ma = M.GetM();
736 
737 #ifdef SELDON_CHECK_DIMENSIONS
738  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
739 #endif
740 
741  Mlt(beta, Y);
742 
743  T4 zero, temp;
744  SetComplexZero(zero);
745 
746  long* ptr = M.GetPtr();
747  int* ind = M.GetInd();
748  typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
749  data = M.GetData();
750 
751  for (int i = 0; i < ma; i++)
752  {
753  temp = zero;
754  for (long j = ptr[i]; j < ptr[i+1]; j++)
755  temp += data[j] * X(ind[j]);
756  Y(i) += alpha * temp;
757  }
758  }
759 
760 
761  template <class T0,
762  class T1, class Prop1, class Allocator1,
763  class T2, class Storage2, class Allocator2,
764  class T3,
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)
770  {
771  int ma = M.GetM();
772 
773 #ifdef SELDON_CHECK_DIMENSIONS
774  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
775 #endif
776 
777  Mlt(beta, Y);
778 
779  typename T4::value_type zero;
780  SetComplexZero(zero);
781  typename T4::value_type temp;
782 
783  long* ptr = M.GetPtr();
784  int* ind = M.GetInd();
785  typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
786  data = M.GetData();
787 
788  for (int i = 0; i < ma; i++)
789  {
790  temp = zero;
791  for (long j = ptr[i]; j < ptr[i+1]; j++)
792  temp += data[j] * X(ind[j]);
793  Y(i) += alpha * temp;
794  }
795  }
796 
797 
798  template <class T0,
799  class T1, class Prop1, class Allocator1,
800  class T2, class Storage2, class Allocator2,
801  class T3,
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)
807  {
808 #ifdef SELDON_CHECK_DIMENSIONS
809  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
810 #endif
811 
812  Mlt(beta, Y);
813 
814  long* ptr = M.GetPtr();
815  int* ind = M.GetInd();
816  typename Matrix<T1, Prop1, ColSparse, Allocator1>::pointer
817  data = M.GetData();
818 
819  for (int j = 0; j < M.GetN(); j++)
820  {
821  for (long k = ptr[j]; k < ptr[j+1]; k++)
822  Y(ind[k]) += alpha * data[k] * X(j);
823  }
824  }
825 
826 
827  /*** Symmetric sparse matrices ***/
828 
829 
830  template <class T0,
831  class T1, class Prop1, class Allocator1,
832  class T2, class Storage2, class Allocator2,
833  class T3,
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)
839  {
840  int ma = M.GetM();
841 
842 #ifdef SELDON_CHECK_DIMENSIONS
843  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
844 #endif
845 
846  Mlt(beta, Y);
847 
848  int i; long j;
849  T4 zero;
850  SetComplexZero(zero);
851  T4 temp;
852 
853  long* ptr = M.GetPtr();
854  int* ind = M.GetInd();
855  typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
856  data = M.GetData();
857 
858  for (i = 0; i < ma; i++)
859  {
860  temp = zero;
861  for (j = ptr[i]; j < ptr[i + 1]; j++)
862  temp += data[j] * X(ind[j]);
863  Y(i) += alpha * temp;
864  }
865  for (i = 0; i < ma-1; i++)
866  for (j = ptr[i]; j < ptr[i + 1]; j++)
867  if (ind[j] != i)
868  Y(ind[j]) += alpha * data[j] * X(i);
869  }
870 
871 
872  template <class T0,
873  class T1, class Prop1, class Allocator1,
874  class T2, class Storage2, class Allocator2,
875  class T3,
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)
881  {
882  int ma = M.GetM();
883 
884 #ifdef SELDON_CHECK_DIMENSIONS
885  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
886 #endif
887 
888  Mlt(beta, Y);
889 
890  int i; long j;
891  T4 zero;
892  SetComplexZero(zero);
893  T4 temp;
894 
895  long* ptr = M.GetPtr();
896  int* ind = M.GetInd();
897  typename Matrix<T1, Prop1, ColSymSparse, Allocator1>::pointer
898  data = M.GetData();
899 
900  for (i = 0; i < ma; i++)
901  {
902  temp = zero;
903  for (j = ptr[i]; j < ptr[i + 1]; j++)
904  if (ind[j] != i)
905  temp += data[j] * X(ind[j]);
906 
907  Y(i) += alpha * temp;
908 
909  for (j = ptr[i]; j < ptr[i + 1]; j++)
910  Y(ind[j]) += alpha * data[j] * X(i);
911  }
912  }
913 
914 
915  template <class T0,
916  class T1, class Prop1, class Allocator1,
917  class T2, class Allocator2,
918  class T3,
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)
924  {
925  int ma = M.GetM();
926 
927 #ifdef SELDON_CHECK_DIMENSIONS
928  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
929 #endif
930 
931  Mlt(beta, Y);
932 
933  int i; long j;
934  typename T4::value_type zero;
935  SetComplexZero(zero);
936  typename T4::value_type temp;
937 
938  long* ptr = M.GetPtr();
939  int* ind = M.GetInd();
940  typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
941  data = M.GetData();
942 
943  for (i = 0; i < ma; i++)
944  {
945  temp = zero;
946  for (j = ptr[i]; j < ptr[i + 1]; j++)
947  temp += data[j] * X(ind[j]);
948  Y(i) += alpha * temp;
949  }
950  for (i = 0; i < ma-1; i++)
951  for (j = ptr[i]; j < ptr[i + 1]; j++)
952  if (ind[j] != i)
953  Y(ind[j]) += alpha * data[j] * X(i);
954  }
955 
956 
957  /*** Symmetric complex sparse matrices ***/
958 
959 
960  template <class T0,
961  class T1, class Prop1, class Allocator1,
962  class T2, class Storage2, class Allocator2,
963  class T3,
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)
969  {
970  int ma = M.GetM();
971 
972 #ifdef SELDON_CHECK_DIMENSIONS
973  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
974 #endif
975 
976  Mlt(beta, Y);
977 
978  int i; long j;
979  typename T4::value_type zero;
980  SetComplexZero(zero);
981  typename T4::value_type temp;
982 
983  long* ptr = M.GetPtr();
984  int* ind = M.GetInd();
985  typename Matrix<T1, Prop1, RowSymSparse, Allocator1>::pointer
986  data = M.GetData();
987 
988  for (i = 0; i < ma; i++)
989  {
990  temp = zero;
991  for (j = ptr[i]; j < ptr[i + 1]; j++)
992  temp += data[j] * X(ind[j]);
993  Y(i) += alpha * temp;
994  }
995  for (i = 0; i < ma-1; i++)
996  for (j = ptr[i]; j < ptr[i + 1]; j++)
997  if (ind[j] != i)
998  Y(ind[j]) += alpha * data[j] * X(i);
999  }
1000 
1001 
1002  /*** Sparse matrices, *Trans ***/
1003 
1004 
1005  template <class T0,
1006  class T1, class Prop1, class Allocator1,
1007  class T2, class Storage2, class Allocator2,
1008  class T3,
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)
1015  {
1016  if (Trans.NoTrans())
1017  {
1018  MltAdd(alpha, M, X, beta, Y);
1019  return;
1020  }
1021 
1022  int i; long j;
1023 
1024  int ma = M.GetM();
1025 
1026 #ifdef SELDON_CHECK_DIMENSIONS
1027  CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonTrans, M, X, beta, Y)");
1028 #endif
1029 
1030  Mlt(beta, Y);
1031 
1032  long* ptr = M.GetPtr();
1033  int* ind = M.GetInd();
1034  typename Matrix<T1, Prop1, RowSparse, Allocator1>::pointer
1035  data = M.GetData();
1036 
1037  if (Trans.Trans())
1038  {
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);
1042  }
1043  else
1044  {
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);
1048  }
1049  }
1050 
1051 
1052  template <class T0,
1053  class T1, class Prop1, class Allocator1,
1054  class T2, class Storage2, class Allocator2,
1055  class T3,
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)
1062  {
1063  if (Trans.NoTrans())
1064  {
1065  MltAdd(alpha, M, X, beta, Y);
1066  return;
1067  }
1068 
1069  int i; long j;
1070 
1071 #ifdef SELDON_CHECK_DIMENSIONS
1072  CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonTrans, M, X, beta, Y)");
1073 #endif
1074 
1075  Mlt(beta, Y);
1076 
1077  T4 temp, zero;
1078  SetComplexZero(zero);
1079 
1080  long* ptr = M.GetPtr();
1081  int* ind = M.GetInd();
1082  typename Matrix<T1, Prop1, ColSparse, Allocator1>::pointer
1083  data = M.GetData();
1084 
1085  if (Trans.Trans())
1086  {
1087  for (i = 0; i < M.GetN(); i++)
1088  {
1089  temp = zero;
1090  for (j = ptr[i]; j < ptr[i + 1]; j++)
1091  temp += data[j] * X(ind[j]);
1092 
1093  Y(i) += alpha * temp;
1094  }
1095  }
1096  else
1097  {
1098  for (i = 0; i < M.GetN(); i++)
1099  {
1100  temp = zero;
1101  for (j = ptr[i]; j < ptr[i + 1]; j++)
1102  temp += conjugate(data[j]) * X(ind[j]);
1103 
1104  Y(i) += alpha * temp;
1105  }
1106  }
1107  }
1108 
1109 
1110  /*** Symmetric sparse matrices, *Trans ***/
1111 
1112 
1113  template <class T0,
1114  class T1, class Prop1, class Allocator1,
1115  class T2, class Storage2, class Allocator2,
1116  class T3,
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)
1123  {
1124  if (!Trans.ConjTrans())
1125  {
1126  MltAddVector(alpha, M, X, beta, Y);
1127  return;
1128  }
1129 
1130  int ma = M.GetM();
1131 
1132 #ifdef SELDON_CHECK_DIMENSIONS
1133  CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
1134 #endif
1135 
1136  Mlt(beta, Y);
1137 
1138  int i; long j;
1139  T4 zero, temp;
1140  SetComplexZero(zero);
1141 
1142  long* ptr = M.GetPtr();
1143  int* ind = M.GetInd();
1144  T1* data = M.GetData();
1145 
1146  for (i = 0; i < ma; i++)
1147  {
1148  temp = zero;
1149  for (j = ptr[i]; j < ptr[i + 1]; j++)
1150  temp += conjugate(data[j]) * X(ind[j]);
1151 
1152  Y(i) += alpha * temp;
1153  }
1154  for (i = 0; i < ma - 1; i++)
1155  for (j = ptr[i]; j < ptr[i + 1]; j++)
1156  if (ind[j] != i)
1157  Y(ind[j]) += alpha * conjugate(data[j]) * X(i);
1158  }
1159 
1160 
1161  template <class T0,
1162  class T1, class Prop1, class Allocator1,
1163  class T2, class Storage2, class Allocator2,
1164  class T3,
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)
1171  {
1172  if (!Trans.ConjTrans())
1173  {
1174  MltAddVector(alpha, M, X, beta, Y);
1175  return;
1176  }
1177 
1178  int ma = M.GetM();
1179 
1180 #ifdef SELDON_CHECK_DIMENSIONS
1181  CheckDim(Trans, M, X, Y, "MltAdd(alpha, SeldonConjTrans, M, X, beta, Y)");
1182 #endif
1183 
1184  Mlt(beta, Y);
1185 
1186  int i; long j;
1187  T4 zero, temp;
1188  SetComplexZero(zero);
1189 
1190  long* ptr = M.GetPtr();
1191  int* ind = M.GetInd();
1192  T1* data = M.GetData();
1193 
1194  for (i = 0; i < ma; i++)
1195  {
1196  temp = zero;
1197  for (j = ptr[i]; j < ptr[i + 1]; j++)
1198  temp += conjugate(data[j]) * X(ind[j]);
1199 
1200  Y(i) += alpha * temp;
1201 
1202  for (j = ptr[i]; j < ptr[i + 1]; j++)
1203  if (ind[j] != i)
1204  Y(ind[j]) += alpha * conjugate(data[j]) * X(i);
1205  }
1206  }
1207 
1208 
1209  // MLTADD //
1211 
1212 
1214  // MLTADD //
1215 
1216 
1231  template <class T0,
1232  class T1, class Prop1, class Storage1, class Allocator1,
1233  class T2, class Storage2, class Allocator2,
1234  class T3,
1235  class T4, class Storage4, class Allocator4>
1236  void MltAddVector(const T0& alpha,
1239  const T3& beta,
1241  {
1242  int ma = M.GetM();
1243  int na = M.GetN();
1244 
1245 #ifdef SELDON_CHECK_DIMENSIONS
1246  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
1247 #endif
1248 
1249  // aborting computation if the matrix is sparse
1250  if (Storage1::Sparse)
1251  throw WrongArgument("MltAdd", "This function is intended to dense"
1252  " matrices only and not to sparse matrices");
1253 
1254  Mlt(beta, Y);
1255 
1256  T4 zero;
1257  SetComplexZero(zero);
1258  T4 temp;
1259 
1260  for (int i = 0; i < ma; i++)
1261  {
1262  temp = zero;
1263  for (int j = 0; j < na; j++)
1264  temp += M(i, j) * X(j);
1265  Y(i) += alpha * temp;
1266  }
1267  }
1268 
1269 
1284  template <class T0,
1285  class T1, class Prop1, class Storage1, class Allocator1,
1286  class T2, class Storage2, class Allocator2,
1287  class T3,
1288  class T4, class Allocator4>
1289  void MltAddVector(const T0& alpha,
1292  const T3& beta,
1294  {
1295  int ma = M.GetM();
1296  int na = M.GetN();
1297 
1298 #ifdef SELDON_CHECK_DIMENSIONS
1299  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
1300 #endif
1301 
1302  if (Storage1::Sparse)
1303  throw WrongArgument("MltAdd", "This function is intended to dense"
1304  " matrices only and not to sparse matrices");
1305 
1306  Mlt(beta, Y);
1307 
1308  typename T4::value_type zero;
1309  SetComplexZero(zero);
1310  typename T4::value_type temp;
1311 
1312  for (int i = 0; i < ma; i++)
1313  {
1314  temp = zero;
1315  for (int j = 0; j < na; j++)
1316  temp += M(i, j) * X(j);
1317  Y(i) += alpha * temp;
1318  }
1319  }
1320 
1321 
1336  template <class T0,
1337  class T1, class Prop1, class Allocator1,
1338  class T2, class Allocator2,
1339  class T3,
1340  class T4, class Allocator4>
1341  void MltAddVector(const T0& alpha,
1344  const T3& beta,
1346  {
1347  int ma = M.GetMmatrix();
1348  int na = M.GetNmatrix();
1349 
1350 #ifdef SELDON_CHECK_DIMENSIONS
1351  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
1352 #endif
1353  typedef typename T4::value_type value_type;
1354 
1355  Mlt(value_type(beta), Y);
1356 
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.),
1360  Y.GetVector(i));
1361  }
1362 
1363 
1378  template <class T0,
1379  class T1, class Prop1, class Allocator1,
1380  class T2, class Allocator2,
1381  class T3,
1382  class T4, class Allocator4>
1383  void MltAddVector(const T0& alpha,
1386  const T3& beta,
1388  {
1389  int ma = M.GetMmatrix();
1390  int na = M.GetNmatrix();
1391 
1392 #ifdef SELDON_CHECK_DIMENSIONS
1393  CheckDim(M, X, Y, "MltAdd(alpha, M, X, beta, Y)");
1394 #endif
1395  typedef typename T4::value_type value_type;
1396 
1397  Mlt(value_type(beta), Y);
1398 
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.),
1402  Y.GetVector(i));
1403  }
1404 
1405 
1423  template <class T0,
1424  class T1, class Prop1, class Storage1, class Allocator1,
1425  class T2, class Storage2, class Allocator2,
1426  class T3,
1427  class T4, class Storage4, class Allocator4>
1428  void MltAddVector(const T0& alpha,
1429  const SeldonTranspose& Trans,
1432  const T3& beta,
1434  {
1435  if (Trans.NoTrans())
1436  {
1437  MltAddVector(alpha, M, X, beta, Y);
1438  return;
1439  }
1440 
1441  int ma = M.GetM();
1442  int na = M.GetN();
1443 
1444 #ifdef SELDON_CHECK_DIMENSIONS
1445  CheckDim(Trans, M, X, Y, "MltAdd(alpha, trans, M, X, beta, Y)");
1446 #endif
1447 
1448  if (Storage1::Sparse)
1449  throw WrongArgument("MltAdd", "This function is intended to dense"
1450  " matrices only and not to sparse matrices");
1451 
1452  T3 zero3;
1453  SetComplexZero(zero3);
1454  T4 zero;
1455  SetComplexZero(zero);
1456 
1457  if (beta == zero3)
1458  Y.Zero();
1459  else
1460  Mlt(beta, Y);
1461 
1462  T4 temp;
1463 
1464  if (Trans.Trans())
1465  {
1466  for (int i = 0; i < na; i++)
1467  {
1468  temp = zero;
1469  for (int j = 0; j < ma; j++)
1470  temp += M(j, i) * X(j);
1471  Y(i) += alpha * temp;
1472  }
1473  }
1474  else
1475  {
1476  for (int i = 0; i < na; i++)
1477  {
1478  temp = zero;
1479  for (int j = 0; j < ma; j++)
1480  temp += conjugate(M(j, i)) * X(j);
1481  Y(i) += alpha * temp;
1482  }
1483  }
1484  }
1485 
1486 
1487  // MLTADD //
1489 
1490 
1492  // GAUSS //
1493 
1494 
1496 
1503  template <class T0, class Prop0, class Storage0, class Allocator0,
1504  class T1, class Storage1, class Allocator1>
1507  {
1508  int i, j, k;
1509  T1 r, S;
1510 
1511  int ma = M.GetM();
1512 
1513 #ifdef SELDON_CHECK_DIMENSIONS
1514  int na = M.GetN();
1515  if (na != ma)
1516  throw WrongDim("Gauss(M, X)",
1517  "The matrix must be squared.");
1518 
1519  CheckDim(M, X, "Gauss(M, X)");
1520 #endif
1521 
1522  // aborting computation if the matrix is sparse
1523  if (Storage0::Sparse)
1524  throw WrongArgument("Gauss", "This function is intended to dense"
1525  " matrices only and not to sparse matrices");
1526 
1527  for (k = 0; k < ma - 1; k++)
1528  for (i = k + 1; i < ma; i++)
1529  {
1530  r = M(i, k) / M(k, k);
1531  for (j = k + 1; j < ma; j++)
1532  M(i, j) -= r * M(k, j);
1533  X(i) -= r *= X(k);
1534  }
1535 
1536  X(ma - 1) = X(ma - 1) / M(ma - 1, ma - 1);
1537  for (k = ma - 2; k > -1; k--)
1538  {
1539  S = X(k);
1540  for (j = k + 1; j < ma; j++)
1541  S -= M(k, j) * X(j);
1542  X(k) = S / M(k, k);
1543  }
1544  }
1545 
1546 
1547  // GAUSS //
1549 
1550 
1552  // GAUSS-SEIDEL //
1553 
1554 
1556 
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)
1570  {
1571  int i, j, k;
1572  T1 temp;
1573 
1574  int na = M.GetN();
1575 
1576 #ifdef SELDON_CHECK_DIMENSIONS
1577  int ma = M.GetM();
1578  if (na != ma)
1579  throw WrongDim("GaussSeidel(M, X, Y, iter)",
1580  "The matrix must be squared.");
1581 
1582  CheckDim(M, X, Y, "GaussSeidel(M, X, Y, iter)");
1583 #endif
1584 
1585  // aborting computation if the matrix is sparse
1586  if (Storage0::Sparse)
1587  throw WrongArgument("GaussSeidel", "This function is intended to dense"
1588  " matrices only and not to sparse matrices");
1589 
1590  T1 zero;
1591  SetComplexZero(zero);
1592  if (type_algo%2 == 0)
1593  for (i = 0; i < iter; i++)
1594  for (j = 0; j < na; j++)
1595  {
1596  temp = zero;
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);
1602  }
1603 
1604  if (type_algo%3 == 0)
1605  for (i = 0; i < iter; i++)
1606  for (j = na-1; j >= 0; j--)
1607  {
1608  temp = zero;
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);
1614  }
1615  }
1616 
1617 
1618  // GAUSS-SEIDEL //
1620 
1621 
1623  // S.O.R. METHOD //
1624 
1625 
1627 
1634  template <class T0, class Prop0, class Storage0, class Allocator0,
1635  class T1, class Storage1, class Allocator1,
1636  class T2, class Storage2, class Allocator2,
1637  class T3>
1641  const T3& omega, int iter, int type_ssor)
1642  {
1643  int i, j, k;
1644  T1 temp;
1645  T3 one;
1646 
1647  int na = M.GetN();
1648 
1649 #ifdef SELDON_CHECK_DIMENSIONS
1650  int ma = M.GetM();
1651  if (na != ma)
1652  throw WrongDim("SOR(M, X, Y, omega, iter)",
1653  "The matrix must be squared.");
1654 
1655  CheckDim(M, X, Y, "SOR(M, X, Y, omega, iter)");
1656 #endif
1657 
1658  // aborting computation if the matrix is sparse
1659  if (Storage0::Sparse)
1660  throw WrongArgument("SOR", "This function is intended to dense"
1661  " matrices only and not to sparse matrices");
1662 
1663  SetComplexOne(one);
1664  if (type_ssor%2 == 0)
1665  for (i = 0; i < iter; i++)
1666  for (j = 0; j < na; j++)
1667  {
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);
1674  }
1675 
1676  if (type_ssor%3 == 0)
1677  for (i = 0; i < iter; i++)
1678  for (j = na-1; j >= 0; j--)
1679  {
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);
1686  }
1687  }
1688 
1689 
1691 
1698  template <class T0, class Prop0, class Storage0, class Allocator0,
1699  class T1, class Storage1, class Allocator1,
1700  class T2, class Storage2, class Allocator2,
1701  class T3>
1702  void SorVector(const SeldonTranspose& transM,
1706  const T3& omega, int iter, int type_ssor)
1707  {
1708  if (transM.NoTrans())
1709  return SorVector(M, Y, X, omega, iter, type_ssor);
1710 
1711  int i, j, k;
1712  T1 temp;
1713  T3 one;
1714 
1715  int na = M.GetN();
1716 
1717 #ifdef SELDON_CHECK_DIMENSIONS
1718  int ma = M.GetM();
1719  if (na != ma)
1720  throw WrongDim("SOR(M, X, Y, omega, iter)",
1721  "The matrix must be squared.");
1722 
1723  CheckDim(M, X, Y, "SOR(M, X, Y, omega, iter)");
1724 #endif
1725 
1726  // aborting computation if the matrix is sparse
1727  if (Storage0::Sparse)
1728  throw WrongArgument("SOR", "This function is intended to dense"
1729  " matrices only and not to sparse matrices");
1730 
1731  SetComplexOne(one);
1732  if (type_ssor%2 == 0)
1733  for (i = 0; i < iter; i++)
1734  for (j = 0; j < na; j++)
1735  {
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);
1742  }
1743 
1744  if (type_ssor%3 == 0)
1745  for (i = 0; i < iter; i++)
1746  for (j = na-1; j >= 0; j--)
1747  {
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);
1754  }
1755  }
1756 
1757 
1758  // S.O.R. method //
1760 
1761 
1762 
1764  // SOLVELU //
1765 
1766 
1768 
1780  template <class T0, class Prop0, class Storage0, class Allocator0,
1781  class T1, class Storage1, class Allocator1>
1784  {
1785  int i, k;
1786  T1 temp;
1787 
1788  int ma = M.GetM();
1789 
1790 #ifdef SELDON_CHECK_DIMENSIONS
1791  int na = M.GetN();
1792  if (na != ma)
1793  throw WrongDim("SolveLU(M, Y)",
1794  "The matrix must be squared.");
1795 
1796  CheckDim(M, Y, "SolveLU(M, Y)");
1797 #endif
1798 
1799  // aborting computation if the matrix is sparse
1800  if (Storage0::Sparse)
1801  throw WrongArgument("SolveLU", "This function is intended to dense"
1802  " matrices only and not to sparse matrices");
1803 
1804  // Forward substitution.
1805  for (i = 0; i < ma; i++)
1806  {
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);
1811  }
1812  // Back substitution.
1813  for (i = ma - 2; i > -1; i--)
1814  {
1815  SetComplexZero(temp);
1816  for (k = i + 1; k < ma; k++)
1817  temp += M(i, k) * Y(k);
1818  Y(i) -= temp;
1819  }
1820  }
1821 
1822 
1823  // SOLVELU //
1825 
1826 
1828  // GetAndSolveLU //
1829 
1830 
1832 
1839  template <class T0, class Prop0, class Storage0, class Allocator0,
1840  class T1, class Storage1, class Allocator1>
1843  {
1844  if (Storage0::Sparse)
1845  throw WrongArgument("GetAndSolveLU", "This function is intended to dense"
1846  " matrices only and not to sparse matrices");
1847 
1848 #ifdef SELDON_WITH_LAPACK
1849  Vector<int> P;
1850  GetLU(M, P);
1851  SolveLU(M, P, Y);
1852 #else
1853  GetLU(M);
1854  SolveLU(M, Y);
1855 #endif
1856  }
1857 
1858 
1859  // GetAndSolveLU //
1861 
1862 
1864  // Solve //
1865 
1866 
1868  template <class T0, class Prop0, class Allocator0,
1869  class T1, class Allocator1>
1870  void
1872  const SeldonTranspose& TransA,
1873  const SeldonDiag& DiagA,
1877  {
1878  int ma = A.GetM();
1879 
1880 #ifdef SELDON_CHECK_DIMENSIONS
1881  int na = A.GetN();
1882  if (na != ma)
1883  throw WrongDim("Solve(UpLo, TransA, DiagA, A, X, Y)",
1884  "The matrix must be squared.");
1885 
1886  CheckDim(A, X, "Solve(UpLo, TransA, DiagA, A, X, Y)");
1887  CheckDim(A, Y, "Solve(UpLo, TransA, DiagA, A, X, Y)");
1888 #endif
1889 
1890  Copy(X, Y);
1891 
1892  T0* data = A.GetData();
1893  long* ptr = A.GetPtr();
1894  int* ind = A.GetInd();
1895  T0 zero; SetComplexZero(zero);
1896  T1 val;
1897  if (Uplo.Lower())
1898  {
1899  if (TransA.NoTrans())
1900  {
1901  if (DiagA.NonUnit())
1902  {
1903  for (int i = 0; i < ma; i++)
1904  {
1905  val = Y(i);
1906  long j = ptr[i];
1907  while (ind[j] < i)
1908  {
1909  val -= data[j]*Y(ind[j]);
1910  j++;
1911  }
1912 
1913 #ifdef SELDON_CHECK_BOUNDS
1914  if ( (j >= ptr[i+1]) || (ind[j] != i) || (data[j] == zero))
1915  throw WrongArgument("Solve", "Matrix must contain"
1916  " a non-null diagonal");
1917 #endif
1918 
1919  Y(i) = val/data[j];
1920  }
1921  }
1922  else
1923  {
1924  for (int i = 0; i < ma; i++)
1925  {
1926  val = Y(i);
1927  long j = ptr[i];
1928  while ((j < ptr[i+1]) && (ind[j] < i))
1929  {
1930  val -= data[j]*Y(ind[j]);
1931  j++;
1932  }
1933 
1934  Y(i) = val;
1935  }
1936  }
1937  }
1938  else if (TransA.Trans())
1939  {
1940  if (DiagA.NonUnit())
1941  {
1942  for (int i = ma-1; i >= 0; i--)
1943  {
1944  long j = ptr[i+1]-1;
1945  while (ind[j] > i)
1946  j--;
1947 
1948 #ifdef SELDON_CHECK_BOUNDS
1949  if ( (j < ptr[i]) || (ind[j] != i) || (data[j] == zero))
1950  throw WrongArgument("Solve", "Matrix must contain"
1951  " a non-null diagonal");
1952 #endif
1953 
1954  Y(i) /= data[j];
1955  j--;
1956  while (j >= ptr[i])
1957  {
1958  Y(ind[j]) -= data[j]*Y(i);
1959  j--;
1960  }
1961  }
1962  }
1963  else
1964  {
1965  for (int i = ma-1; i >= 0; i--)
1966  {
1967  long j = ptr[i];
1968  while ( (j < ptr[i+1]) && (ind[j] < i))
1969  {
1970  Y(ind[j]) -= data[j]*Y(i);
1971  j++;
1972  }
1973  }
1974  }
1975  }
1976  else
1977  {
1978  if (DiagA.NonUnit())
1979  {
1980  for (int i = ma-1; i >= 0; i--)
1981  {
1982  long j = ptr[i+1]-1;
1983  while (ind[j] > i)
1984  j--;
1985 
1986 #ifdef SELDON_CHECK_BOUNDS
1987  if ( (j < ptr[i]) || (ind[j] != i) || (data[j] == zero))
1988  throw WrongArgument("Solve", "Matrix must contain"
1989  " a non-null diagonal");
1990 #endif
1991 
1992  Y(i) /= conjugate(data[j]);
1993  j--;
1994  while (j >= ptr[i])
1995  {
1996  Y(ind[j]) -= conjugate(data[j])*Y(i);
1997  j--;
1998  }
1999  }
2000  }
2001  else
2002  {
2003  for (int i = ma-1; i >= 0; i--)
2004  {
2005  long j = ptr[i];
2006  while ((j < ptr[i+1]) && (ind[j] < i))
2007  {
2008  Y(ind[j]) -= conjugate(data[j])*Y(i);
2009  j++;
2010  }
2011  }
2012  }
2013  }
2014  }
2015  else
2016  {
2017  if (TransA.NoTrans())
2018  {
2019  if (DiagA.NonUnit())
2020  {
2021  for (int i = ma-1; i >= 0; i--)
2022  {
2023  val = Y(i);
2024  long j = ptr[i+1]-1;
2025  while (ind[j] > i)
2026  {
2027  val -= data[j]*Y(ind[j]);
2028  j--;
2029  }
2030 
2031 #ifdef SELDON_CHECK_BOUNDS
2032  if ( (j < ptr[i]) || (ind[j] != i) || (data[j] == zero))
2033  throw WrongArgument("Solve", "Matrix must contain"
2034  " a non-null diagonal");
2035 #endif
2036 
2037  Y(i) = val/data[j];
2038  }
2039  }
2040  else
2041  {
2042  for (int i = ma-1; i >= 0; i--)
2043  {
2044  val = Y(i);
2045  long j = ptr[i+1]-1;
2046  while ( (j >= ptr[i]) && (ind[j] > i))
2047  {
2048  val -= data[j]*Y(ind[j]);
2049  j--;
2050  }
2051 
2052  Y(i) = val;
2053  }
2054  }
2055  }
2056  else if (TransA.Trans())
2057  {
2058  if (DiagA.NonUnit())
2059  {
2060  for (int i = 0; i < ma; i++)
2061  {
2062  long j = ptr[i];
2063  while (ind[j] < i)
2064  j++;
2065 
2066 #ifdef SELDON_CHECK_BOUNDS
2067  if ( (j >= ptr[i+1]) || (ind[j] != i) || (data[j] == zero) )
2068  throw WrongArgument("Solve", "Matrix must contain"
2069  " a non-null diagonal");
2070 #endif
2071 
2072  Y(i) /= data[j];
2073  j++;
2074  while (j < ptr[i+1])
2075  {
2076  Y(ind[j]) -= data[j]*Y(i);
2077  j++;
2078  }
2079  }
2080  }
2081  else
2082  {
2083  for (int i = 0; i < ma; i++)
2084  {
2085  long j = ptr[i+1]-1;
2086  while ( (j >= ptr[i]) && (ind[j] > i))
2087  {
2088  Y(ind[j]) -= data[j]*Y(i);
2089  j--;
2090  }
2091  }
2092  }
2093  }
2094  else
2095  {
2096  if (DiagA.NonUnit())
2097  {
2098  for (int i = 0; i < ma; i++)
2099  {
2100  long j = ptr[i];
2101  while (ind[j] < i)
2102  j++;
2103 
2104 #ifdef SELDON_CHECK_BOUNDS
2105  if ( (j >= ptr[i+1]) || (ind[j] != i) || (data[j] == zero) )
2106  throw WrongArgument("Solve", "Matrix must contain"
2107  " a non-null diagonal");
2108 #endif
2109 
2110  Y(i) /= conjugate(data[j]);
2111  j++;
2112  while (j < ptr[i+1])
2113  {
2114  Y(ind[j]) -= conjugate(data[j])*Y(i);
2115  j++;
2116  }
2117  }
2118  }
2119  else
2120  {
2121  for (int i = 0; i < ma; i++)
2122  {
2123  long j = ptr[i+1]-1;
2124  while ( (j >= ptr[i]) && (ind[j] > i))
2125  {
2126  Y(ind[j]) -= conjugate(data[j])*Y(i);
2127  j--;
2128  }
2129  }
2130  }
2131  }
2132  }
2133  }
2134 
2135 
2136  // Solve //
2138 
2139 
2141  // CHECKDIM //
2142 
2143 
2145 
2154  template <class T0, class Prop0, class Storage0, class Allocator0,
2155  class T1, class Storage1, class Allocator1,
2156  class T2, class Storage2, class Allocator2>
2160  string function)
2161  {
2162  if (X.GetM() != M.GetN() || Y.GetM() != M.GetM())
2163  {
2164 
2165 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2166  string Mchar = to_str(&M), Xchar = to_str(&X), Ychar = to_str(&Y);
2167 #else
2168  string Mchar("M"), Xchar("X"), Ychar("Y");
2169 #endif
2170 
2171  throw WrongDim(function,
2172  string("Operation M X + Y -> Y not permitted:")
2173  + string("\n M (") + Mchar + string(") is a ")
2174  + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
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("."));
2180  }
2181  }
2182 
2183 
2185 
2194  template <class T0, class Prop0, class Allocator0,
2195  class T1, class Allocator1,
2196  class T2, class Allocator2>
2200  string function)
2201  {
2202  if (X.GetNvector() != M.GetNmatrix() || Y.GetNvector() != M.GetMmatrix())
2203  {
2204 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2205  string Mchar = to_str(&M), Xchar = to_str(&X), Ychar = to_str(&Y);
2206 #else
2207  string Mchar("M"), Xchar("X"), Ychar("Y");
2208 #endif
2209 
2210  throw WrongDim(function,
2211  string("Operation M X + Y -> Y not permitted:")
2212  + string("\n M (") + Mchar + string(") is a ")
2213  + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
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("."));
2219  }
2220  }
2221 
2222 
2224 
2233  template <class T0, class Prop0, class Allocator0,
2234  class T1, class Allocator1,
2235  class T2, class Allocator2>
2239  string function)
2240  {
2241  if (X.GetNvector() != M.GetNmatrix() || Y.GetNvector() != M.GetMmatrix())
2242  {
2243 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2244  string Mchar = to_str(&M), Xchar = to_str(&X), Ychar = to_str(&Y);
2245 #else
2246  string Mchar("M"), Xchar("X"), Ychar("Y");
2247 #endif
2248 
2249  throw WrongDim(function,
2250  string("Operation M X + Y -> Y not permitted:")
2251  + string("\n M (") + Mchar + string(") is a ")
2252  + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
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("."));
2258  }
2259  }
2260 
2261 
2263 
2272  template <class T0, class Prop0, class Storage0, class Allocator0,
2273  class T1, class Allocator1,
2274  class T2, class Storage2, class Allocator2>
2278  string function)
2279  {
2280  if (X.GetM() != M.GetN() || Y.GetM() != M.GetM())
2281  {
2282 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2283  string Mchar = to_str(&M), Xchar = to_str(&X), Ychar = to_str(&Y);
2284 #else
2285  string Mchar("M"), Xchar("X"), Ychar("Y");
2286 #endif
2287 
2288  throw WrongDim(function,
2289  string("Operation M X + Y -> Y not permitted:")
2290  + string("\n M (") + Mchar + string(") is a ")
2291  + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
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("."));
2297  }
2298  }
2299 
2300 
2302 
2314  template <class T0, class Prop0, class Storage0, class Allocator0,
2315  class T1, class Storage1, class Allocator1,
2316  class T2, class Storage2, class Allocator2>
2317  void CheckDim(const SeldonTranspose& trans,
2321  string function, string op)
2322  {
2323  if (op == "M X + Y -> Y")
2324  if (trans.Trans())
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:");
2328  else
2329  op = string("Operation M X + Y -> Y not permitted:");
2330  else
2331  op = string("Operation ") + op + string(" not permitted:");
2332 
2333  if (X.GetM() != M.GetN(trans) || Y.GetM() != M.GetM(trans))
2334  {
2335 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2336  string Mchar = to_str(&M), Xchar = to_str(&X), Ychar = to_str(&Y);
2337 #else
2338  string Mchar("M"), Xchar("X"), Ychar("Y");
2339 #endif
2340 
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("."));
2348  }
2349  }
2350 
2351 
2353 
2362  template <class T0, class Prop0, class Storage0, class Allocator0,
2363  class T1, class Storage1, class Allocator1>
2366  string function, string op)
2367  {
2368  if (X.GetM() != M.GetN())
2369  {
2370 #ifndef SELDON_WITHOUT_TO_STR_CHECKDIM
2371  string Mchar = to_str(&M), Xchar = to_str(&X);
2372 #else
2373  string Mchar("M"), Xchar("X");
2374 #endif
2375 
2376  throw WrongDim(function, string("Operation ") + op + " not permitted:"
2377  + string("\n M (") + Mchar + string(") is a ")
2378  + to_str(M.GetM()) + string(" x ") + to_str(M.GetN())
2379  + string(" matrix;\n X (") + Xchar
2380  + string(") is vector of length ")
2381  + to_str(X.GetLength()) + string("."));
2382  }
2383  }
2384 
2385 
2386  // CHECKDIM //
2388 
2389 } // namespace Seldon.
2390 
2391 
2392 #endif
Seldon::SeldonTranspose
Definition: MatrixFlag.hxx:32
Seldon::to_str
std::string to_str(const T &input)
Converts most types to string.
Definition: CommonInline.cxx:137
Seldon::Vector
Definition: SeldonHeader.hxx:207
Seldon::GaussSeidel
void GaussSeidel(const Matrix< T0, Prop0, Storage0, Allocator0 > &M, Vector< T2, Storage2, Allocator2 > &Y, const Vector< T1, Storage1, Allocator1 > &X, int iter, int type_algo)
Solve M*Y = X with Gauss-Seidel method.
Definition: Functions_MatVect.cxx:1566
Seldon::Matrix
Definition: SeldonHeader.hxx:226
Seldon::GetAndSolveLU
void GetAndSolveLU(Matrix< T0, Prop0, Storage0, Allocator0 > &M, Vector< T1, Storage1, Allocator1 > &Y)
Solves a linear system using LU factorization.
Definition: Functions_MatVect.cxx:1841
Seldon::SeldonDiag
Definition: MatrixFlag.hxx:86
Seldon::GetLU
void GetLU(Matrix< T0, Prop0, Storage0, Allocator0 > &A)
Returns the LU factorization of a matrix.
Definition: Functions_Matrix.cxx:2073
Seldon::CheckDim
void CheckDim(const Matrix< T0, Prop0, Storage0, Allocator0 > &A, const Matrix< T1, Prop1, Storage1, Allocator1 > &B, const Matrix< T2, Prop2, Storage2, Allocator2 > &C, string function)
Checks the compatibility of the dimensions.
Definition: Functions_Matrix.cxx:2132
Seldon::SolveLuVector
void SolveLuVector(const Matrix< T0, Prop0, Storage0, Allocator0 > &M, Vector< T1, Storage1, Allocator1 > &Y)
Solves a linear system whose matrix has been LU-factorized.
Definition: Functions_MatVect.cxx:1782
Seldon::SolveTriangular
void SolveTriangular(const SeldonUplo &Uplo, const SeldonTranspose &TransA, const SeldonDiag &DiagA, const Matrix< T0, Prop0, RowSparse, Allocator0 > &A, const Vector< T1, VectFull, Allocator1 > &X, Vector< T1, VectFull, Allocator1 > &Y)
solves by triangular upper part or lower part of A
Definition: Functions_MatVect.cxx:1871
Seldon::WrongArgument
Definition: Errors.hxx:76
Seldon::SorVector
void SorVector(const Matrix< T0, Prop0, Storage0, Allocator0 > &M, Vector< T2, Storage2, Allocator2 > &Y, const Vector< T1, Storage1, Allocator1 > &X, const T3 &omega, int iter, int type_ssor)
Solve M Y = X with S.O.R. method.
Definition: Functions_MatVect.cxx:1638
Seldon::SeldonUplo
Definition: MatrixFlag.hxx:129
Seldon::WrongDim
Definition: Errors.hxx:102
Seldon
Seldon namespace.
Definition: Array.cxx:24
Seldon::Gauss
void Gauss(Matrix< T0, Prop0, Storage0, Allocator0 > &M, Vector< T1, Storage1, Allocator1 > &X)
Solves M*Y = X with Gauss method.
Definition: Functions_MatVect.cxx:1505