Relaxation_MatVect.cxx
1 // Copyright (C) 2003-2011 Marc DuruflĂ©
2 // Copyright (C) 2001-2011 Vivien Mallet
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_RELAXATION_MATVECT_CXX
22 
23 /*
24  Functions defined in this file
25 
26  SOR(A, X, B, omega, iter, type_ssor)
27 
28 */
29 
30 namespace Seldon
31 {
32 
34 
41  template <class T0, class Prop0, class Allocator0,
42  class T1, class Storage1, class Allocator1,
43  class T2, class Storage2, class Allocator2, class T3>
47  const T3& omega, int iter, int type_ssor)
48  {
49  T1 temp, zero; T3 one;
50  T0 ajj;
51  SetComplexZero(zero);
52  SetComplexOne(one);
53 
54  int ma = A.GetM();
55 
56 #ifdef SELDON_CHECK_BOUNDS
57  int na = A.GetN();
58  if (na != ma)
59  throw WrongDim("SOR", "Matrix must be squared.");
60 
61  if (ma != X.GetM() || ma != B.GetM())
62  throw WrongDim("SOR", "Matrix and vector dimensions are incompatible.");
63 #endif
64 
65  long* ptr = A.GetPtr();
66  int* ind = A.GetInd();
68  = A.GetData();
69 
70  // Forward sweep.
71  if (type_ssor % 2 == 0)
72  for (int i = 0; i < iter; i++)
73  for (int j = 0; j < ma; j++)
74  {
75  temp = zero;
76  long k = ptr[j];
77  while (ind[k] < j)
78  {
79  temp += data[k] * X(ind[k]);
80  k++;
81  }
82 
83 #ifdef SELDON_CHECK_BOUNDS
84  if ( (k >= ptr[j+1]) || (ind[k] != j) || (data[k] == zero))
85  throw WrongArgument("SOR", "Matrix must contain"
86  " a non-null diagonal");
87 #endif
88 
89  ajj = data[k];
90  k++;
91  while (k < ptr[j+1])
92  {
93  temp += data[k] * X(ind[k]);
94  k++;
95  }
96 
97  X(j) = (one-omega) * X(j) + omega * (B(j) - temp) / ajj;
98  }
99 
100  // Backward sweep.
101  if (type_ssor % 3 == 0)
102  for (int i = 0; i < iter; i++)
103  for (int j = ma-1 ; j >= 0; j--)
104  {
105  temp = zero;
106  long k = ptr[j];
107  while (ind[k] < j)
108  {
109  temp += data[k] * X(ind[k]);
110  k++;
111  }
112 
113  ajj = data[k];
114  k++;
115  while (k < ptr[j+1])
116  {
117  temp += data[k] * X(ind[k]);
118  k++;
119  }
120 
121  X(j) = (one-omega) * X(j) + omega * (B(j) - temp) / ajj;
122  }
123  }
124 
125 
127 
134  template <class T0, class Prop0, class Allocator0,
135  class T1, class Storage1, class Allocator1,
136  class T2, class Storage2, class Allocator2, class T3>
140  const T3& omega,
141  int iter, int type_ssor)
142  {
143  T1 temp, zero; T3 one;
144  SetComplexZero(zero);
145  SetComplexOne(one);
146 
147  int ma = A.GetM();
148 
149 #ifdef SELDON_CHECK_BOUNDS
150  int na = A.GetN();
151  if (na != ma)
152  throw WrongDim("SOR", "Matrix must be squared.");
153 
154  if (ma != X.GetM() || ma != B.GetM())
155  throw WrongDim("SOR", "Matrix and vector dimensions are incompatible.");
156 #endif
157 
158  T0 ajj;
159 
160  // Forward sweep.
161  if (type_ssor % 2 == 0)
162  for (int i = 0; i < iter; i++)
163  for (int j = 0; j < ma; j++)
164  {
165  temp = zero;
166  int k = 0;
167  while (A.Index(j, k) < j)
168  {
169  temp += A.Value(j, k) * X(A.Index(j, k));
170  k++;
171  }
172 
173  ajj = A.Value(j, k);
174 
175 #ifdef SELDON_CHECK_BOUNDS
176  if ((A.Index(j, k) != j) || (ajj == zero))
177  throw WrongArgument("SOR", "Matrix must contain"
178  "a non-null diagonal");
179 #endif
180 
181  k++;
182  while (k < A.GetRowSize(j))
183  {
184  temp += A.Value(j, k) * X(A.Index(j, k));
185  k++;
186  }
187 
188  X(j) = (one-omega) * X(j) + omega * (B(j) - temp) / ajj;
189  }
190 
191  // Backward sweep.
192  if (type_ssor % 3 == 0)
193  for (int i = 0; i < iter; i++)
194  for (int j = ma-1; j >= 0; j--)
195  {
196  temp = zero;
197  int k = 0;
198  while (A.Index(j, k) < j)
199  {
200  temp += A.Value(j, k) * X(A.Index(j, k));
201  k++;
202  }
203 
204  ajj = A.Value(j, k);
205  k++;
206  while (k < A.GetRowSize(j))
207  {
208  temp += A.Value(j, k) * X(A.Index(j, k));
209  k++;
210  }
211 
212  X(j) = (one-omega) * X(j) + omega * (B(j) - temp) / ajj;
213  }
214  }
215 
216 
218 
225  template <class T0, class Prop0, class Allocator0,
226  class T1, class Storage1, class Allocator1,
227  class T2, class Storage2, class Allocator2, class T3>
231  const T3& omega, int iter, int type_ssor)
232  {
233  T1 temp, zero; T3 one;
234  SetComplexZero(zero);
235  SetComplexOne(one);
236 
237  int ma = A.GetM();
238 
239 #ifdef SELDON_CHECK_BOUNDS
240  int na = A.GetN();
241  if (na != ma)
242  throw WrongDim("SOR", "Matrix must be squared.");
243 
244  if (ma != X.GetM() || ma != B.GetM())
245  throw WrongDim("SOR", "Matrix and vector dimensions are incompatible.");
246 #endif
247 
248  long* ptr = A.GetPtr();
249  int* ind = A.GetInd();
250  T0* data = A.GetData();
251 
252  T0 ajj;
253 
254  // Let us consider the following splitting : A = D - L - U
255  // D diagonal of A
256  // L lower part of A
257  // U upper part of A, A is symmetric, so L = U^t
258 
259  // Forward sweep
260  // (D/omega - L) X^{n+1/2} = (U + (1-omega)/omega D) X^n + B
261  T3 coef = (one - omega) / omega;
262  if (type_ssor % 2 == 0)
263  for (int i = 0; i < iter; i++)
264  {
265  // First we do X = (U + (1-omega)/omega D) X + B
266  for (int j = 0; j < ma; j++)
267  {
268  temp = zero;
269 
270 #ifdef SELDON_CHECK_BOUNDS
271  if ( (ptr[j] >= ptr[j+1]) || (ind[ptr[j]] != j) || (data[ptr[j]] == zero))
272  throw WrongArgument("SOR", "Matrix must contain"
273  " a non-null diagonal");
274 #endif
275  ajj = data[ptr[j]];
276 
277  for (long k = ptr[j]+1; k < ptr[j+1]; k++)
278  temp += data[k] * X(ind[k]);
279 
280  X(j) = coef * ajj * X(j) + B(j) - temp;
281  }
282 
283  // Then we solve (D/omega - L) X = X
284  for (int j = 0; j < ma; j++)
285  {
286  X(j) *= omega / data[ptr[j]];
287  for (long k = ptr[j]+1; k < ptr[j+1]; k++)
288  X(ind[k]) -= data[k]*X(j);
289  }
290  }
291 
292 
293  // Backward sweep.
294  // (D/omega - U) X^{n+1} = (L + (1-omega)/omega D) X^{n+1/2} + B
295  if (type_ssor % 3 == 0)
296  for (int i = 0; i < iter; i++)
297  {
298  // First we compute X = (L + (1-omega)/omega D) X + B.
299  for (int j = ma-1; j >= 0; j--)
300  {
301  for (long k = ptr[j]+1; k < ptr[j+1]; k++)
302  X(ind[k]) -= data[k]*X(j);
303 
304  X(j) = B(j) + coef * data[ptr[j]] * X(j);
305  }
306 
307  // Then we solve (D/omega - U) X = X.
308  for (int j = ma-1; j >= 0; j--)
309  {
310  temp = zero;
311  ajj = data[ptr[j]];
312  for (long k = ptr[j]+1; k < ptr[j+1]; k++)
313  temp += data[k]*X(ind[k]);
314 
315  X(j) = (X(j) - temp) * omega / ajj;
316  }
317  }
318  }
319 
320 
322 
329  template <class T0, class Prop0, class Allocator0,
330  class T1, class Storage1, class Allocator1,
331  class T2, class Storage2, class Allocator2, class T3>
335  const T3& omega, int iter, int type_ssor)
336  {
337  T1 temp, zero; T3 one;
338  SetComplexZero(zero);
339  SetComplexOne(one);
340 
341  int ma = A.GetM();
342 
343 #ifdef SELDON_CHECK_BOUNDS
344  int na = A.GetN();
345  if (na != ma)
346  throw WrongDim("SOR", "Matrix must be squared.");
347 
348  if (ma != X.GetM() || ma != B.GetM())
349  throw WrongDim("SOR", "Matrix and vector dimensions are incompatible.");
350 #endif
351 
352  T0 ajj;
353 
354  // Let us consider the following splitting : A = D - L - U
355  // D diagonal of A
356  // L lower part of A
357  // U upper part of A, A is symmetric, so L = U^t
358 
359  // Forward sweep.
360  // (D/omega - L) X^{n+1/2} = (U + (1-omega)/omega D) X^n + B
361  T3 coef = (one - omega) / omega;
362  if (type_ssor % 2 == 0)
363  for (int i = 0; i < iter; i++)
364  {
365  // First we do X = (U + (1-omega)/omega D) X + B.
366  for (int j = 0; j < ma; j++)
367  {
368  temp = zero;
369  ajj = A.Value(j, 0);
370 
371 #ifdef SELDON_CHECK_BOUNDS
372  if ((A.Index(j, 0) != j) || (ajj == zero))
373  throw WrongArgument("SOR", "Matrix must contain"
374  "a non-null diagonal");
375 #endif
376 
377  for (int k = 1; k < A.GetRowSize(j); k++)
378  temp += A.Value(j, k) * X(A.Index(j, k));
379 
380  X(j) = coef * ajj * X(j) + B(j) - temp;
381  }
382 
383  // Then we solve (D/omega - L) X = X.
384  for (int j = 0; j < ma; j++)
385  {
386  X(j) *= omega / A.Value(j, 0);
387  for (int k = 1; k < A.GetRowSize(j); k++)
388  X(A.Index(j, k)) -= A.Value(j, k)*X(j);
389  }
390  }
391 
392 
393  // Backward sweep.
394  // (D/omega - U) X^{n+1} = (L + (1-omega)/omega D) X^{n+1/2} + B
395  if (type_ssor % 3 == 0)
396  for (int i = 0; i < iter; i++)
397  {
398  // First we compute X = (L + (1-omega)/omega D) X + B.
399  for (int j = ma-1; j >= 0; j--)
400  {
401  ajj = A.Value(j, 0);
402  for (int k = 1; k < A.GetRowSize(j); k++)
403  X(A.Index(j, k)) -= A.Value(j, k) * X(j);
404 
405  X(j) = B(j) + coef * ajj * X(j);
406  }
407 
408  // Then we solve (D/omega - U) X = X.
409  for (int j = ma-1; j >= 0; j--)
410  {
411  temp = zero;
412  ajj = A.Value(j, 0);
413  for (int k = 1; k < A.GetRowSize(j); k++)
414  temp += A.Value(j, k)*X(A.Index(j, k));
415 
416  X(j) = (X(j) - temp) * omega / ajj;
417  }
418  }
419  }
420 
421 
423 
430  template <class T0, class Prop0, class Allocator0,
431  class T1, class Storage1, class Allocator1,
432  class T2, class Storage2, class Allocator2, class T3>
436  const T3& omega, int iter, int type_ssor)
437  {
438  T1 zero; T3 one;
439  SetComplexZero(zero);
440  SetComplexOne(one);
441 
442  int ma = A.GetM();
443 
444 #ifdef SELDON_CHECK_BOUNDS
445  int na = A.GetN();
446  if (na != ma)
447  throw WrongDim("SOR", "Matrix must be squared.");
448 
449  if (ma != X.GetM() || ma != B.GetM())
450  throw WrongDim("SOR", "Matrix and vector dimensions are incompatible.");
451 #endif
452 
453  long* ptr = A.GetPtr();
454  int* ind = A.GetInd();
455  T0* data = A.GetData();
456 
457  // Let us consider the following splitting : A = D - L - U
458  // D diagonal of A
459  // L lower part of A
460  // U upper part of A
461 
462  // Forward sweep
463  // (D/omega - L) X^{n+1/2} = (U + (1-omega)/omega D) X^n + B
464  T0 ajj;
465  T3 coef = (one - omega) / omega;
466  if (type_ssor % 2 == 0)
467  for (int i = 0; i < iter; i++)
468  {
469  // First we compute X = (U + (1-omega)/omega D) X + B
470  for (int j = 0; j < ma; j++)
471  {
472  long k = ptr[j];
473  while (ind[k] < j)
474  {
475  X(ind[k]) -= data[k]*X(j);
476  k++;
477  }
478 
479 #ifdef SELDON_CHECK_BOUNDS
480  if ( (k >= ptr[j+1]) || (ind[k] != j) || (data[k] == zero))
481  throw WrongArgument("SOR", "Matrix must contain"
482  " a non-null diagonal");
483 #endif
484 
485  ajj = data[k];
486  X(j) = B(j) + coef * ajj * X(j);
487  }
488 
489  // Then we solve (D/omega - L) X = X
490  for (int j = 0; j < ma; j++)
491  {
492  long k = ptr[j];
493  while (ind[k] < j)
494  k++;
495 
496  ajj = data[k]; k++;
497  X(j) *= omega/ajj;
498  while (k < ptr[j+1])
499  {
500  X(ind[k]) -= data[k]*X(j);
501  k++;
502  }
503  }
504  }
505 
506  // Backward sweep.
507  // (D/omega - U) X^{n+1} = (L + (1-omega)/omega D) X^{n+1/2} + B
508  if (type_ssor % 3 == 0)
509  for (int i = 0; i < iter; i++)
510  {
511  // First we compute X = (L + (1-omega)/omega D) X + B.
512  for (int j = ma-1; j >= 0; j--)
513  {
514  long k = ptr[j+1]-1;
515  while (ind[k] > j)
516  {
517  X(ind[k]) -= data[k]*X(j);
518  k--;
519  }
520 
521 #ifdef SELDON_CHECK_BOUNDS
522  if ( (k < ptr[j]) || (ind[k] != j) || (data[k] == zero) )
523  throw WrongArgument("SOR", "Matrix must contain"
524  "a non-null diagonal");
525 #endif
526 
527  X(j) = B(j) + coef*data[k]*X(j);
528  }
529 
530  // Then we solve (D/omega - U) X = X.
531  for (int j = ma-1; j >= 0; j--)
532  {
533  long k = ptr[j+1]-1;
534  while (ind[k] > j)
535  k--;
536 
537  X(j) *= omega/data[k];
538  k--;
539  while (k >= ptr[j])
540  {
541  X(ind[k]) -= data[k]*X(j);
542  k--;
543  }
544  }
545  }
546  }
547 
548 
550 
557  template <class T0, class Prop0, class Allocator0,
558  class T1, class Storage1, class Allocator1,
559  class T2, class Storage2, class Allocator2, class T3>
563  const T3& omega, int iter, int type_ssor)
564  {
565  T1 zero; T3 one;
566  SetComplexZero(zero);
567  SetComplexOne(one);
568 
569  int ma = A.GetM();
570 
571 #ifdef SELDON_CHECK_BOUNDS
572  int na = A.GetN();
573  if (na != ma)
574  throw WrongDim("SOR", "Matrix must be squared.");
575 
576  if (ma != X.GetM() || ma != B.GetM())
577  throw WrongDim("SOR", "Matrix and vector dimensions are incompatible.");
578 #endif
579 
580  // Let us consider the following splitting : A = D - L - U
581  // D diagonal of A
582  // L lower part of A
583  // U upper part of A
584 
585  // Forward sweep
586  // (D/omega - L) X^{n+1/2} = (U + (1-omega)/omega D) X^n + B
587  T0 ajj;
588  T3 coef = (one - omega) / omega;
589  if (type_ssor % 2 == 0)
590  for (int i = 0; i < iter; i++)
591  {
592  // First we compute X = (U + (1-omega)/omega D) X + B
593  for (int j = 0; j < ma; j++)
594  {
595  int k = 0;
596  while (A.Index(j, k) < j)
597  {
598  X(A.Index(j, k)) -= A.Value(j, k) * X(j);
599  k++;
600  }
601 
602  ajj = A.Value(j, k);
603 
604 #ifdef SELDON_CHECK_BOUNDS
605  if ((A.Index(j, k) != j) || (ajj == zero))
606  throw WrongArgument("SOR", "Matrix must contain"
607  "a non-null diagonal");
608 #endif
609 
610  X(j) = B(j) + coef * ajj * X(j);
611  }
612 
613  // Then we solve (D/omega - L) X = X
614  for (int j = 0; j < ma; j++)
615  {
616  int k = 0;
617  while (A.Index(j, k) < j)
618  k++;
619 
620  ajj = A.Value(j, k); k++;
621  X(j) *= omega/ajj;
622  while (k < A.GetColumnSize(j))
623  {
624  X(A.Index(j, k)) -= A.Value(j, k) * X(j);
625  k++;
626  }
627  }
628  }
629 
630  // Backward sweep.
631  // (D/omega - U) X^{n+1} = (L + (1-omega)/omega D) X^{n+1/2} + B
632  if (type_ssor % 3 == 0)
633  for (int i = 0; i < iter; i++)
634  {
635  // First we compute X = (L + (1-omega)/omega D) X + B.
636  for (int j = ma-1; j >= 0; j--)
637  {
638  int k = A.GetColumnSize(j) - 1;
639  while (A.Index(j, k) > j)
640  {
641  X(A.Index(j, k)) -= A.Value(j, k) * X(j);
642  k--;
643  }
644 
645  X(j) = B(j) + coef*A.Value(j, k)*X(j);
646  }
647 
648  // Then we solve (D/omega - U) X = X.
649  for (int j = ma-1; j >= 0; j--)
650  {
651  int k = A.GetColumnSize(j) - 1;
652  while (A.Index(j, k) > j)
653  k--;
654 
655  X(j) *= omega/A.Value(j, k);
656  k--;
657  while (k >= 0)
658  {
659  X(A.Index(j, k)) -= A.Value(j, k) * X(j);
660  k--;
661  }
662  }
663  }
664  }
665 
666 
668 
675  template <class T0, class Prop0, class Allocator0,
676  class T1, class Storage1, class Allocator1,
677  class T2, class Storage2, class Allocator2, class T3>
681  const T3& omega, int iter, int type_ssor)
682  {
683  T1 temp, zero; T3 one;
684  SetComplexZero(zero);
685  SetComplexOne(one);
686 
687  int ma = A.GetM();
688 
689 #ifdef SELDON_CHECK_BOUNDS
690  int na = A.GetN();
691  if (na != ma)
692  throw WrongDim("SOR", "Matrix must be squared.");
693 
694  if (ma != X.GetM() || ma != B.GetM())
695  throw WrongDim("SOR", "Matrix and vector dimensions are incompatible.");
696 #endif
697 
698  long* ptr = A.GetPtr();
699  int* ind = A.GetInd();
700  T0* data = A.GetData();
701  T0 ajj;
702 
703  // Let us consider the following splitting : A = D - L - U
704  // D diagonal of A
705  // L lower part of A
706  // U upper part of A, A is symmetric, so L = U^t
707 
708  // Forward sweep
709  // (D/omega - L) X^{n+1/2} = (U + (1-omega)/omega D) X^n + B
710  T3 coef = (one - omega) / omega;
711  if (type_ssor % 2 == 0)
712  for (int i = 0; i < iter; i++)
713  {
714  // First we do X = (U + (1-omega)/omega D) X + B
715  for (int j = 0; j < ma; j++)
716  {
717 #ifdef SELDON_CHECK_BOUNDS
718  if ( (ptr[j] >= ptr[j+1]) || (ind[ptr[j+1]-1] != j)
719  || (data[ptr[j+1]-1] == zero) )
720  throw WrongArgument("SOR", "Matrix must contain"
721  "a non-null diagonal");
722 #endif
723 
724  ajj = data[ptr[j+1]-1];
725 
726  for (long k = ptr[j]; k < ptr[j+1]-1; k++)
727  X(ind[k]) -= data[k] * X(j);
728 
729  X(j) = coef * ajj * X(j) + B(j);
730  }
731 
732  // Then we solve (D/omega - L) X = X
733  for (int j = 0; j < ma; j++)
734  {
735  ajj = data[ptr[j+1]-1];
736  for (long k = ptr[j]; k < ptr[j+1]-1; k++)
737  X(j) -= data[k] * X(ind[k]);
738 
739  X(j) *= omega / ajj;
740  }
741  }
742 
743 
744  // Backward sweep.
745  // (D/omega - U) X^{n+1} = (L + (1-omega)/omega D) X^{n+1/2} + B
746  if (type_ssor % 3 == 0)
747  for (int i = 0; i < iter; i++)
748  {
749  // First we compute X = (L + (1-omega)/omega D) X + B.
750  for (int j = ma-1; j >= 0; j--)
751  {
752  temp = zero;
753  ajj = data[ptr[j+1]-1];
754  for (long k = ptr[j]; k < ptr[j+1]-1; k++)
755  temp -= data[k] * X(ind[k]);
756 
757  X(j) = B(j) + coef * ajj * X(j) + temp;
758  }
759 
760  // Then we solve (D/omega - U) X = X.
761  for (int j = ma-1; j >= 0; j--)
762  {
763  temp = zero;
764  ajj = data[ptr[j+1]-1];
765  X(j) *= omega / ajj;
766  for (long k = ptr[j]; k < ptr[j+1]-1; k++)
767  X(ind[k]) -= data[k] * X(j);
768  }
769  }
770  }
771 
772 
774 
781  template <class T0, class Prop0, class Allocator0,
782  class T1, class Storage1, class Allocator1,
783  class T2, class Storage2, class Allocator2, class T3>
787  const T3& omega, int iter, int type_ssor)
788  {
789  T1 temp, zero; T3 one;
790  SetComplexZero(zero);
791  SetComplexOne(one);
792 
793  int ma = A.GetM();
794 
795 #ifdef SELDON_CHECK_BOUNDS
796  int na = A.GetN();
797  if (na != ma)
798  throw WrongDim("SOR", "Matrix must be squared.");
799 
800  if (ma != X.GetM() || ma != B.GetM())
801  throw WrongDim("SOR", "Matrix and vector dimensions are incompatible.");
802 #endif
803 
804  T0 ajj;
805 
806  // Let us consider the following splitting : A = D - L - U
807  // D diagonal of A
808  // L lower part of A
809  // U upper part of A, A is symmetric, so L = U^t
810 
811  // Forward sweep
812  // (D/omega - L) X^{n+1/2} = (U + (1-omega)/omega D) X^n + B
813  T3 coef = (one - omega) / omega;
814  if (type_ssor % 2 == 0)
815  for (int i = 0; i < iter; i++)
816  {
817  // First we do X = (U + (1-omega)/omega D) X + B
818  for (int j = 0; j < ma; j++)
819  {
820  int kmax = A.GetColumnSize(j)-1;
821  ajj = A.Value(j, kmax);
822 
823 #ifdef SELDON_CHECK_BOUNDS
824  if ((A.Index(j, kmax) != j) || (ajj == zero))
825  throw WrongArgument("SOR", "Matrix must contain"
826  "a non-null diagonal");
827 #endif
828 
829  for (int k = 0; k < kmax; k++)
830  X(A.Index(j, k)) -= A.Value(j, k) * X(j);
831 
832  X(j) = coef * ajj * X(j) + B(j);
833  }
834 
835  // Then we solve (D/omega - L) X = X
836  for (int j = 0; j < ma; j++)
837  {
838  int kmax = A.GetColumnSize(j)-1;
839  ajj = A.Value(j, kmax);
840  for (int k = 0; k < kmax; k++)
841  X(j) -= A.Value(j, k) * X(A.Index(j, k));
842 
843  X(j) *= omega / ajj;
844  }
845  }
846 
847 
848  // Backward sweep.
849  // (D/omega - U) X^{n+1} = (L + (1-omega)/omega D) X^{n+1/2} + B
850  if (type_ssor % 3 == 0)
851  for (int i = 0; i < iter; i++)
852  {
853  // First we compute X = (L + (1-omega)/omega D) X + B.
854  for (int j = ma-1; j >= 0; j--)
855  {
856  temp = zero;
857  int kmax = A.GetColumnSize(j)-1;
858  ajj = A.Value(j, kmax);
859  for (int k = 0; k < kmax; k++)
860  temp -= A.Value(j, k) * X(A.Index(j, k));
861 
862  X(j) = B(j) + coef * ajj * X(j) + temp;
863  }
864 
865  // Then we solve (D/omega - U) X = X.
866  for (int j = ma-1; j >= 0; j--)
867  {
868  temp = zero;
869  int kmax = A.GetColumnSize(j)-1;
870  ajj = A.Value(j, kmax);
871  X(j) *= omega / ajj;
872  for (int k = 0; k < kmax; k++)
873  X(A.Index(j, k)) -= A.Value(j, k) * X(j);
874  }
875  }
876  }
877 
878 
879  /*********************************
880  * S.O.R with transpose matrices *
881  *********************************/
882 
883 
884  template <class T0, class Prop0, class Allocator0,
885  class T1, class Storage1, class Allocator1,
886  class T2, class Storage2, class Allocator2, class T3>
887  void SorVector(const SeldonTranspose& transM,
888  const Matrix<T0, Prop0, RowSparse, Allocator0>& A,
889  Vector<T2, Storage2, Allocator2>& X,
890  const Vector<T1, Storage1, Allocator1>& B,
891  const T3& omega, int iter, int type_ssor)
892  {
893  if (transM.NoTrans())
894  return SorVector(A, X, B, omega, iter, type_ssor);
895 
896  Matrix<T0, Prop0, ColSparse, Allocator0> Ac;
897  Ac.SetData(A.GetN(), A.GetM(), A.GetDataSize(),
898  A.GetData(), A.GetPtr(), A.GetInd());
899 
900  SorVector(Ac, X, B, omega, iter, type_ssor);
901  Ac.Nullify();
902  }
903 
904 
905  template <class T0, class Prop0, class Allocator0,
906  class T1, class Storage1, class Allocator1,
907  class T2, class Storage2, class Allocator2, class T3>
908  void SorVector(const SeldonTranspose& transM,
909  const Matrix<T0, Prop0, ColSparse, Allocator0>& A,
910  Vector<T2, Storage2, Allocator2>& X,
911  const Vector<T1, Storage1, Allocator1>& B,
912  const T3& omega, int iter, int type_ssor)
913  {
914  if (transM.NoTrans())
915  return SorVector(A, X, B, omega, iter, type_ssor);
916 
917  Matrix<T0, Prop0, RowSparse, Allocator0> Ac;
918  Ac.SetData(A.GetN(), A.GetM(), A.GetDataSize(),
919  A.GetData(), A.GetPtr(), A.GetInd());
920 
921  SorVector(Ac, X, B, omega, iter, type_ssor);
922  Ac.Nullify();
923  }
924 
925 
926  template <class T0, class Prop0, class Allocator0,
927  class T1, class Storage1, class Allocator1,
928  class T2, class Storage2, class Allocator2, class T3>
929  void SorVector(const SeldonTranspose& transM,
930  const Matrix<T0, Prop0, RowSymSparse, Allocator0>& A,
931  Vector<T2, Storage2, Allocator2>& X,
932  const Vector<T1, Storage1, Allocator1>& B,
933  const T3& omega, int iter, int type_ssor)
934  {
935  SorVector(A, X, B, omega, iter, type_ssor);
936  }
937 
938 
939  template <class T0, class Prop0, class Allocator0,
940  class T1, class Storage1, class Allocator1,
941  class T2, class Storage2, class Allocator2, class T3>
942  void SorVector(const SeldonTranspose& transM,
943  const Matrix<T0, Prop0, ColSymSparse, Allocator0>& A,
944  Vector<T2, Storage2, Allocator2>& X,
945  const Vector<T1, Storage1, Allocator1>& B,
946  const T3& omega, int iter, int type_ssor)
947  {
948  SorVector(A, X, B, omega, iter, type_ssor);
949  }
950 
951 
952  template <class T0, class Prop0, class Allocator0,
953  class T1, class Storage1, class Allocator1,
954  class T2, class Storage2, class Allocator2, class T3>
955  void SorVector(const SeldonTranspose& transM,
956  const Matrix<T0, Prop0, ArrayRowSparse, Allocator0>& A,
957  Vector<T2, Storage2, Allocator2>& X,
958  const Vector<T1, Storage1, Allocator1>& B,
959  const T3& omega, int iter, int type_ssor)
960  {
961  if (transM.NoTrans())
962  return SorVector(A, X, B, omega, iter, type_ssor);
963 
964  Matrix<T0, Prop0, ArrayColSparse, Allocator0> Ac;
965  Ac.SetData(A.GetN(), A.GetM(), A.GetData());
966 
967  SorVector(Ac, X, B, omega, iter, type_ssor);
968  Ac.Nullify();
969  }
970 
971 
972  template <class T0, class Prop0, class Allocator0,
973  class T1, class Storage1, class Allocator1,
974  class T2, class Storage2, class Allocator2, class T3>
975  void SorVector(const SeldonTranspose& transM,
976  const Matrix<T0, Prop0, ArrayColSparse, Allocator0>& A,
977  Vector<T2, Storage2, Allocator2>& X,
978  const Vector<T1, Storage1, Allocator1>& B,
979  const T3& omega, int iter, int type_ssor)
980  {
981  if (transM.NoTrans())
982  return SorVector(A, X, B, omega, iter, type_ssor);
983 
984  Matrix<T0, Prop0, ArrayRowSparse, Allocator0> Ac;
985  Ac.SetData(A.GetN(), A.GetM(), A.GetData());
986 
987  SorVector(Ac, X, B, omega, iter, type_ssor);
988  Ac.Nullify();
989  }
990 
991 
992  template <class T0, class Prop0, class Allocator0,
993  class T1, class Storage1, class Allocator1,
994  class T2, class Storage2, class Allocator2, class T3>
995  void SorVector(const SeldonTranspose& transM,
996  const Matrix<T0, Prop0, ArrayRowSymSparse, Allocator0>& A,
997  Vector<T2, Storage2, Allocator2>& X,
998  const Vector<T1, Storage1, Allocator1>& B,
999  const T3& omega, int iter, int type_ssor)
1000  {
1001  SorVector(A, X, B, omega, iter, type_ssor);
1002  }
1003 
1004 
1005  template <class T0, class Prop0, class Allocator0,
1006  class T1, class Storage1, class Allocator1,
1007  class T2, class Storage2, class Allocator2, class T3>
1008  void SorVector(const SeldonTranspose& transM,
1009  const Matrix<T0, Prop0, ArrayColSymSparse, Allocator0>& A,
1010  Vector<T2, Storage2, Allocator2>& X,
1011  const Vector<T1, Storage1, Allocator1>& B,
1012  const T3& omega, int iter, int type_ssor)
1013  {
1014  SorVector(A, X, B, omega, iter, type_ssor);
1015  }
1016 
1017 } // end namespace
1018 
1019 #define SELDON_FILE_RELAXATION_MATVECT_CXX
1020 #endif
Seldon::Vector
Definition: SeldonHeader.hxx:207
Seldon::Matrix
Definition: SeldonHeader.hxx:226
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::WrongDim
Definition: Errors.hxx:102
Seldon
Seldon namespace.
Definition: Array.cxx:24