SPI
SLEPc PETSc Interface is used for rapid development and intuitive matrix operations similar to MatLab or NumPy style of operations
SPIVec.cpp
Go to the documentation of this file.
1 #include "SPIVec.hpp"
2 // use 1 to use the GPU and 0 or anything else to only use CPU and MPI. Be sure this matches what is in SPIMat.cpp
3 #define USE_GPU 0
4 
5 namespace SPI{
6 
7  // constructors
10  std::string _name
11  ){name=_name; }
14  const SPIVec &A,
15  std::string _name
16  ){
17  name=_name;
18  (*this) = A;
19  }
22  const PetscInt _rows,
23  const std::string _name
24  ){
25  //this->Init(_rows,_name);
26  this->name=_name;
27  this->rows=_rows;
28  //PetscInt _rows2 = this->rows;
29  //SPI::printf("_rows at initialization %D",_rows);
30  //SPI::printf(" rows at initialization %D",_rows2);
31  //std::cout<<" rows at initialization "<<this->rows<<std::endl;
32  ierr = VecCreate(PETSC_COMM_WORLD,&vec);CHKERRXX(ierr);
33  ierr = VecSetSizes(vec,PETSC_DECIDE,_rows);CHKERRXX(ierr);
34 #if USE_GPU == 1
35  ierr = VecSetType(vec,VECMPICUDA);CHKERRXX(ierr);
36 #else
37  ierr = VecSetType(vec,VECMPI);CHKERRXX(ierr);
38 #endif
39  flag_init=PETSC_TRUE;
40  }
41 
42  // Initialize vector
44  PetscInt SPIVec::Init(
45  PetscInt _rows,
46  const std::string _name
47  ){
48  this->name=_name;
49  rows=_rows;
50  SPI::printf("_rows at initialization %D",_rows);
51  SPI::printf("rows at initialization %D",this->rows);
52  ierr = VecCreate(PETSC_COMM_WORLD,&vec);CHKERRQ(ierr);
53  ierr = VecSetSizes(vec,PETSC_DECIDE,_rows);CHKERRQ(ierr);
54 #if USE_GPU == 1
55  ierr = VecSetType(vec,VECMPICUDA);CHKERRQ(ierr);
56 #else
57  ierr = VecSetType(vec,VECMPI);CHKERRQ(ierr);
58 #endif
59  flag_init=PETSC_TRUE;
60  return 0;
61  }
62 
64  PetscInt SPIVec::set(
65  const PetscInt _row,
66  const PetscScalar v
67  ){
68  PetscInt low,high;
69  VecGetOwnershipRange(vec,&low,&high);
70  if ((low <= _row) && (_row < high)){
71  ierr = VecSetValue(vec,_row,v,INSERT_VALUES);CHKERRQ(ierr);
72  }
73  return 0;
74  }
76  PetscInt SPIVec::set(
77  const PetscScalar v
78  ){
79  ierr = VecSet(vec,v); CHKERRQ(ierr);
80  return 0;
81  }
83  PetscInt SPIVec::add(
84  PetscInt _row,
85  const PetscScalar v
86  ){
87  PetscInt low,high;
88  VecGetOwnershipRange(vec,&low,&high);
89  if ((low <= _row) && (_row < high)){
90  ierr = VecSetValue(vec,_row,v,ADD_VALUES);CHKERRQ(ierr);
91  }
92  return 0;
93  }
94  // get size of vector
96  PetscInt SPIVec::size(){
97  PetscInt n;
98  ierr = VecGetSize(vec,&n);CHKERRXX(ierr);
99  rows=n; // update rows
100  return n;
101  }
102 
103  // overloaded operators, get
105  PetscScalar SPIVec::operator()(
106  PetscInt _row,
107  PetscBool global
108  )const{
109  PetscScalar v,v_global=0.;
110  PetscInt low,high;
111  PetscErrorCode ierr2;
112  ierr2 = VecGetOwnershipRange(vec,&low, &high);CHKERRXX(ierr2);
113  if ((low<=_row) && (_row<high)){
114  ierr2 = VecGetValues(vec,1,&_row,&v);CHKERRXX(ierr2);
115  }
116  if (global){
117  MPIU_Allreduce(&v,&v_global,1,MPIU_SCALAR,MPIU_SUM,PETSC_COMM_WORLD);
118  }
119  else{
120  v_global=v; // return local value
121  }
122  return v_global;
123  }
125  PetscScalar SPIVec::operator()(
126  PetscInt _row,
127  PetscBool global
128  ){
129  PetscScalar v,v_global=0.;
130  PetscInt low,high;
131  ierr = VecGetOwnershipRange(vec,&low, &high);CHKERRXX(ierr);
132  if ((low<=_row) && (_row<high)){
133  ierr = VecGetValues(vec,1,&_row,&v);CHKERRXX(ierr);
134  }
135  if (global){
136  MPIU_Allreduce(&v,&v_global,1,MPIU_SCALAR,MPIU_SUM,PETSC_COMM_WORLD);
137  }
138  else{
139  v_global=v; // return local value
140  }
141  return v_global;
142  }
143  // overloaded operator, set
146  PetscInt _row,
147  const PetscScalar v
148  ){
149  PetscInt low,high;
150  VecGetOwnershipRange(vec,&low,&high);
151  if ((low <= _row) && (_row < high)){
152  ierr = VecSetValue(vec,_row,v,INSERT_VALUES);CHKERRQ(ierr);
153  }
154  //(*this)(); // assemble after every insertion
155  return 0;
156  }
158  PetscInt SPIVec::operator()(PetscInt _row, const double v){
159  ierr = (*this)(_row,(PetscScalar)(v+0.0*PETSC_i));CHKERRQ(ierr);
160  return 0;
161  }
163  PetscInt SPIVec::operator()(PetscInt _row, const int v){
164  ierr = (*this)(_row,(PetscScalar)((double)v+0.0*PETSC_i));CHKERRQ(ierr);
165  return 0;
166  }
167 
168  // overloaded operator, assemble
171  ierr = VecAssemblyBegin(vec);CHKERRXX(ierr);
172  ierr = VecAssemblyEnd(vec);CHKERRXX(ierr);
173  return (*this);
174  }
175  // overloaded operator, VecAXPY
178  const SPIVec &X
179  ){
180  ierr = VecAXPY(this->vec,1.,X.vec);CHKERRXX(ierr);
181  return *this;
182  }
185  const PetscScalar a,
186  const SPIVec &X
187  ){
188  ierr = VecAXPY(this->vec,a,X.vec);CHKERRXX(ierr);
189  return (*this);
190  }
191  // overloaded operator, VecAXPY
194  const SPIVec &X
195  ){
196  SPIVec A;
197  A=*this;
198  ierr = VecAXPY(A.vec,1.,X.vec);CHKERRXX(ierr);
199 #if USE_GPU == 1
200  ierr = VecSetType(A.vec,VECMPICUDA);CHKERRXX(ierr);
201 #else
202  ierr = VecSetType(A.vec,VECMPI);CHKERRXX(ierr);
203 #endif
204  return A;
205  }
208  const PetscScalar a
209  ){ // Y + a operation
210  SPIVec A;
211  A=(*this);
212  A += a*ones(rows);
213  return A;
214  }
217  const double a
218  ){ // Y + a operation
219  SPIVec A;
220  A=(*this);
221  A += a*ones(rows);
222  return A;
223  }
226  const PetscScalar a
227  ){ // Y - a operation
228  SPIVec A;
229  A=(*this);
230  A -= a*ones(rows);
231  return A;
232  }
235  const PetscInt a
236  ){ // Y - a operation
237  SPIVec A;
238  A=(*this);
239  A -= a*ones(rows);
240  return A;
241  }
242  // overloaded operator, VecAXPY
245  const SPIVec &X
246  ){
247  ierr = VecAXPY(this->vec,-1.,X.vec);CHKERRXX(ierr);
248  return *this;
249  }
250  // overloaded operator, VecAXPY
253  const SPIVec &X
254  ){
255  SPIVec A;
256  A=*this;
257  ierr = VecAXPY(A.vec,-1.,X.vec);CHKERRXX(ierr);
258 #if USE_GPU == 1
259  ierr = VecSetType(A.vec,VECMPICUDA);CHKERRXX(ierr);
260 #else
261  ierr = VecSetType(A.vec,VECMPI);CHKERRXX(ierr);
262 #endif
263  return A;
264  }
267  return -1.*(*this);
268  }
269  // overload operator, scale with scalar
272  const PetscScalar a
273  ){
274  SPIVec A;
275  A=(*this);
276  ierr = VecScale(A.vec,a);CHKERRXX(ierr);
277  return A;
278  }
280  SPIVec SPIVec::operator*(const double a){
281  PetscScalar as=a;
282  SPIVec A;
283  A=*this;
284  ierr = VecScale(A.vec,as);CHKERRXX(ierr);
285  return A;
286  }
287  // overload operator, scale with scalar
290  const PetscScalar a
291  ){
292  ierr = VecScale(this->vec,a);CHKERRXX(ierr);
293  return *this;
294  }
297  const double a
298  ){
299  ierr = VecScale(this->vec,(PetscScalar)(a+0.*PETSC_i));CHKERRXX(ierr);
300  return *this;
301  }
304  const SPIVec &a
305  ){
306  ierr = VecPointwiseMult(vec,a.vec,(*this).vec);CHKERRXX(ierr);
307  return *this;
308  }
309  // overload operator, pointwise multiply
312  const SPIVec& X
313  ){
314  SPIVec C;
315  C.rows=rows;
316  C=(*this);
317  ierr = VecPointwiseMult(C.vec,X.vec,(*this).vec);CHKERRXX(ierr);
318  // ierr = VecSetType(C.vec,VECMPI);CHKERRXX(ierr);
319  return C;
320  }
321  // overload operator, pointwise divide
324  const PetscScalar a
325  ){
326  SPIVec A;
327  A=(*this);
328  ierr = VecScale(A.vec,1./a);CHKERRXX(ierr);
329  return A;
330  }
332  SPIVec SPIVec::operator/(const double a){
333  PetscScalar as=a;
334  SPIVec A;
335  A=*this;
336  ierr = VecScale(A.vec,1./as);CHKERRXX(ierr);
337  return A;
338  }
341  const SPIVec X
342  ){
343  SPIVec Z(X.rows);
344  ierr = VecPointwiseDivide(Z.vec,this->vec,X.vec);CHKERRXX(ierr);
345  return Z;
346  }
347  // overload operator, scale with scalar
350  const PetscScalar a
351  ){
352  ierr = VecScale(this->vec,1./a);CHKERRXX(ierr);
353  return *this;
354  }
355  // ^ operator
358  const PetscScalar p
359  ){
360  return pow(*this,p);
361  }
364  const double p
365  ){
366  return pow(*this,(PetscScalar)p);
367  }
370  const int p
371  ){
372  return pow(*this,(PetscScalar)p);
373  }
376  SPIVec p
377  ){
378  return pow(*this,p);
379  }
380  // overload operator, copy and initialize
383  if(flag_init){
384  if(X.rows==this->rows){
385  ierr = VecCopy(X.vec,vec);CHKERRXX(ierr); // use copy if size matches
386  }
387  else{
388  this->~SPIVec(); // destroy and recreate from scratch
389  this->rows=X.rows;
390  ierr = VecDuplicate(X.vec,&vec); CHKERRXX(ierr);
391  ierr = VecCopy(X.vec,vec); CHKERRXX(ierr);
392  }
393  }
394  else{
395  this->rows=X.rows;
396  ierr = VecDuplicate(X.vec,&vec); CHKERRXX(ierr);
397  ierr = VecCopy(X.vec,vec); CHKERRXX(ierr);
398  flag_init=PETSC_TRUE;
399  }
400  //ierr = VecSetType(vec,VECMPI);CHKERRXX(ierr);
401  return (*this);
402  }
405  const SPIVec &x2
406  ){
407  PetscBool iftrue;
408  ierr = VecEqual(vec,x2.vec,&iftrue); CHKERRXX(ierr);
409  return iftrue;
410 
411  }
412 
413 
414  // overload % for inner product
415  //SPIVec operator%(SPIVec A){
416  //return *this;
417  //}
420  ierr = VecConjugate(vec);CHKERRXX(ierr);
421  return (*this);
422  }
423 
425  PetscScalar SPIVec::max(){
426  PetscInt argmax;
427  PetscReal max=0.;
428  PetscScalar maxscalar;
429  ierr = VecMax(this->vec,&argmax,&max);CHKERRXX(ierr);
430  maxscalar = (*this)(argmax,PETSC_TRUE);
431  //PetscScalar maxscalar_global = 0.;
432  //MPIU_Allreduce(&maxscalar,&maxscalar_global,1,MPIU_SCALAR,MPIU_SUM,PETSC_COMM_WORLD);
433 
434  return maxscalar;
435  }
437  PetscInt SPIVec::argmax(){
438  PetscInt argmax;
439  PetscReal max=0.;
440  //PetscScalar maxscalar;
441  ierr = VecMax(this->vec,&argmax,&max);CHKERRXX(ierr);
442  //maxscalar = (*this)(argmax,PETSC_TRUE);
443  //PetscScalar maxscalar_global = 0.;
444  //MPIU_Allreduce(&maxscalar,&maxscalar_global,1,MPIU_SCALAR,MPIU_SUM,PETSC_COMM_WORLD);
445 
446  return argmax;
447  }
450  ierr = VecRealPart(vec); CHKERRXX(ierr);
451  return (*this);
452  }
455  ierr = VecImaginaryPart(vec); CHKERRXX(ierr);
456  return (*this);
457  }
459  PetscScalar SPIVec::dot(
460  SPIVec y
461  ){
462  PetscScalar val;
463  ierr = VecDot(vec,y.vec,&val); CHKERRXX(ierr);
464  return val;
465  }
466 
467 
468  // print vector to screen
470  PetscInt SPIVec::print(){
471  (*this)();// assemble
472  printf("\n---------------- "+this->name+"---start------");
473  //PetscPrintf(PETSC_COMM_WORLD,("\n---------------- "+name+"---start------\n").c_str());
474  //SPI::printf("shape = %d x 1",this->rows);
475  SPI::printf("shape = "+std::to_string(this->rows)+" x 1");
476  ierr = VecView(vec,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
477  //PetscPrintf(PETSC_COMM_WORLD,("---------------- "+name+"---done-------\n\n").c_str());
478  printf("---------------- "+this->name+"---done-------\n");
479  return 0;
480  }
481 
484  if(flag_init){
485  flag_init=PETSC_FALSE;
486  ierr = VecDestroy(&vec);CHKERRXX(ierr);
487  }
488  //else{
489  //(*this)=zeros(1);
490  //ierr = VecDestroy(&vec);CHKERRXX(ierr);
491 
492  //}
493  }
494 
495  // overload operator, scale with scalar
498  const PetscScalar a,
499  const SPIVec &Y
500  ){
501  SPIVec B(Y.rows);
502  SPIVec A(ones(Y.rows)*a);
503  //B=Y;
504  //B.ierr = VecScale(B.vec,a);CHKERRXX(B.ierr);
505  B.ierr = VecPointwiseDivide(B.vec,A.vec,Y.vec);CHKERRXX(B.ierr);
506  return B;
507  }
508 
511  const PetscScalar a,
512  const SPIVec &Y
513  ){
514  SPIVec B;
515  B=Y;
516  B.ierr = VecScale(B.vec,a);CHKERRXX(B.ierr);
517  return B;
518  }
519 
522  const PetscScalar a,
523  const SPIVec &Y
524  ){
525  SPIVec B;
526  B = Y;
527  B += a*ones(B.rows);
528  return B;
529  }
530 
533  const PetscScalar a,
534  const SPIVec &Y
535  ){
536  SPIVec B;
537  B = -1.*Y;
538  B += a*ones(B.rows);
539  return B;
540  }
541 
543  PetscInt save(
544  const SPIVec &A,
545  const std::string filename
546  ){ // save A to hdf5 to filename as variable A.name
547  PetscErrorCode ierr;
548  ierr = PetscObjectSetName((PetscObject)A.vec, A.name.c_str());CHKERRQ(ierr);
549  PetscViewer viewer;
550  std::ifstream f(filename.c_str());
551  if(f.good()){// if filename exists, then append
552  ierr = PetscViewerHDF5Open(PETSC_COMM_WORLD, filename.c_str(), FILE_MODE_APPEND, &viewer); CHKERRQ(ierr);
553  }
554  else{ // if not, then write a new file
555  ierr = PetscViewerHDF5Open(PETSC_COMM_WORLD, filename.c_str(), FILE_MODE_WRITE, &viewer); CHKERRQ(ierr);
556  }
557  ierr = VecView(A.vec,viewer); CHKERRQ(ierr);
558  ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
559  return 0;
560  }
562  PetscInt save(
563  std::vector<PetscScalar> A,
564  std::string variablename,
565  std::string filename
566  ){
567  PetscInt n=A.size();
568  SPIVec Avec(n,variablename);
569  for(PetscInt i=0; i<n; i++){
570  Avec(i,A[i]);
571  }
572  save(Avec,filename);
573  return 0;
574  }
576  PetscInt save(
577  std::vector<SPIVec> A,
578  std::string variablename,
579  std::string filename
580  ){
581  PetscInt n=A.size();
582  std::string sep="_";
583  for(PetscInt i=0; i<n; i++){
584  A[i].name = variablename+sep+std::to_string(i);
585  save(A[i],filename);
586  }
587  return 0;
588  }
589 
591  PetscInt load(
592  SPIVec &A,
593  const std::string filename
594  ){
595  A.ierr = PetscObjectSetName((PetscObject)A.vec, A.name.c_str());CHKERRQ(A.ierr);
596  PetscViewer viewer;
597  //std::ifstream f(filename.c_str());
598  A.ierr = PetscViewerHDF5Open(PETSC_COMM_WORLD, filename.c_str(), FILE_MODE_READ, &viewer); CHKERRQ(A.ierr);
599  A.ierr = VecLoad(A.vec,viewer); CHKERRQ(A.ierr);
600  A.ierr = PetscViewerDestroy(&viewer); CHKERRQ(A.ierr);
601  return 0;
602  }
603 
606  const PetscInt rows
607  ){
608  SPIVec A(rows);
609  A.ierr = VecSet(A.vec,1.);CHKERRXX(A.ierr);
610  return A;
611  }
612 
615  const PetscInt rows
616  ){
617  SPIVec A(rows);
618  A.ierr = VecSet(A.vec,0.);CHKERRXX(A.ierr);
619  return A;
620  }
623  const SPIVec &A
624  ){
625  SPIVec B;
626  B=A;
627  B.ierr = VecConjugate(B.vec);CHKERRXX(B.ierr);
628  return B;
629  }
632  const SPIVec &A
633  ){
634  SPIVec B(A);
635  return B.real();
636  }
639  const SPIVec &A
640  ){
641  SPIVec B(A);
642  return B.imag();
643  }
646  const PetscScalar begin,
647  const PetscScalar end,
648  const PetscInt _rows
649  ){ // return linspace of number of rows equally spaced points between begin and end
650  SPIVec y(_rows);
651  //PetscInt _rows2 = y.rows;
652  //SPI::printf("y.rows in linspace = %D",_rows2);
653  PetscScalar step = (end-begin)/((PetscScalar)(_rows-1));
654  PetscScalar value=begin;
655  //PetscInt i=0;
656  for (PetscInt i=0; i<_rows; ++i){
657  y(i,value);
658  value += step;
659  }
660  y();
661  //_rows2 = y.rows;
662  //SPI::printf("y.rows in linspace = %D",_rows2);
663  //SPI::printf("_rows in linspace = %D",_rows);
664  return y;
665  }
668  const PetscScalar begin,
669  const PetscScalar end,
670  const PetscScalar stepsize
671  ){ // return linspace of number of rows equally spaced points between begin and end
672  PetscInt _rows=ceil(PetscRealPart((end-begin)/stepsize));
673  SPIVec y(_rows);
674  //PetscScalar step = (end-begin)/((PetscScalar)(_rows-1));
675  PetscScalar value=begin;
676  //PetscInt i=0;
677  for (PetscInt i=0; i<_rows; ++i){
678  y(i,value);
679  value += stepsize;
680  }
681  y();
682  return y;
683  }
685  const PetscScalar end
686  ){ // return linspace of number of rows equally spaced points between begin and end
687  PetscScalar begin=0.;
688  return arange(begin,end);
689  }
690 
692  template <class T>
694  T (*f)(T const&),
695  const SPIVec &A
696  ){
697  SPIVec out(A);
698  for (PetscInt i=0; i<out.rows; ++i){
699  out(i,(*f)(out(i))); // TODO speed up by getting all values at once on local processor and looping through those
700  }
701  out();
702  return out;
703  }
704 
706  SPIVec sin(const SPIVec &A){ return _Function_on_each_element(&std::sin<PetscReal>, A); }
708  SPIVec cos(const SPIVec &A){ return _Function_on_each_element(&std::cos<PetscReal>, A); }
710  SPIVec tan(const SPIVec &A){ return _Function_on_each_element(&std::tan<PetscReal>, A); }
712  SPIVec exp(const SPIVec &A){
713  //return _Function_on_each_element(&std::exp<PetscReal>, A);
714  SPIVec B(A);
715  B.ierr = VecExp(B.vec); CHKERRXX(B.ierr);
716  return B;
717  }
719  SPIVec log(const SPIVec &A){ return _Function_on_each_element(&std::log<PetscReal>, A); }
721  SPIVec log10(const SPIVec &A){ return _Function_on_each_element(&std::log10<PetscReal>, A); }
723  SPIVec sinh(const SPIVec &A){ return _Function_on_each_element(&std::sinh<PetscReal>, A); }
725  SPIVec cosh(const SPIVec &A){ return _Function_on_each_element(&std::cosh<PetscReal>, A); }
727  SPIVec tanh(const SPIVec &A){ return _Function_on_each_element(&std::tanh<PetscReal>, A); }
729  SPIVec asin(const SPIVec &A){ return _Function_on_each_element(&std::asin<PetscReal>, A); }
731  SPIVec acos(const SPIVec &A){ return _Function_on_each_element(&std::acos<PetscReal>, A); }
733  SPIVec atan(const SPIVec &A){ return _Function_on_each_element(&std::atan<PetscReal>, A); }
735  SPIVec asinh(const SPIVec &A){ return _Function_on_each_element(&std::asinh<PetscReal>, A); }
737  SPIVec acosh(const SPIVec &A){ return _Function_on_each_element(&std::acosh<PetscReal>, A); }
739  SPIVec atanh(const SPIVec &A){ return _Function_on_each_element(&std::atanh<PetscReal>, A); }
741  SPIVec sqrt(const SPIVec &A){ return _Function_on_each_element(&std::sqrt<PetscReal>, A); }
743  SPIVec erf(const SPIVec &A){
744  SPIVec out(A);
745  for (PetscInt i=0; i<out.rows; ++i){
746  out(i,std::erf((double)(PetscRealPart(out(i))))); // TODO speed up by getting all values at once on local processor and looping through those
747  }
748  out();
749  return out;
750  }
752  SPIVec erfc(const SPIVec &A){
753  SPIVec out(A);
754  for (PetscInt i=0; i<out.rows; ++i){
755  out(i,std::erfc((double)(PetscRealPart(out(i))))); // TODO speed up by getting all values at once on local processor and looping through those
756  }
757  out();
758  return out;
759  }
761  template <class T>
763  T (*f)(T const&, T const&),
764  const SPIVec &A,
765  SPIVec &B
766  ){
767  SPIVec out(A);
768  for (PetscInt i=0; i<out.rows; ++i){
769  out(i,(*f)(out(i),B(i))); // TODO speed up by getting all values at once on local processor and looping through those
770  }
771  out();
772  return out;
773  }
775  SPIVec pow(const SPIVec &A,SPIVec &B){ return _Function_on_each_element(&std::pow<PetscReal>, A,B); }
778  const SPIVec &A,
779  PetscScalar b
780  ){
781  SPIVec B(A);
782  B.ierr = VecPow(B.vec,b);CHKERRXX(B.ierr);
783  return B;
784 
785  }
786 
788  PetscScalar dot(
789  SPIVec x,
790  SPIVec y
791  ){
792  PetscScalar innerproduct;
793  x.ierr = VecDot(x.vec,y.vec,&innerproduct); CHKERRXX(x.ierr);
794  return innerproduct;
795  }
796 
798  SPIVec abs(const SPIVec &A){
799  SPIVec B(A);
800  VecAbs(B.vec);
801  return B;
802  }
803 
805  PetscScalar sum(
806  SPIVec x1
807  ){
808  PetscScalar sum;
809  x1.ierr = VecSum(x1.vec,&sum); CHKERRXX(x1.ierr);
810  return sum;
811  }
813  PetscScalar integrate_coeffs(
814  const SPIVec &a
815  ){
816  PetscInt n=a.rows;
817  PetscInt N=n-1;
818  SPIVec d(n+1,"d");
819  PetscScalar value=0.0,d0=0.0;
820  for(PetscInt i=1; i<=N+1; ++i){
821  if(i==1){
822  value=0.5*(2.0*a(i-1,PETSC_TRUE)-a(i+1,PETSC_TRUE));
823  }
824  else if(i==N+1){
825  value = 0.5/((PetscScalar)i)*(2.0*a(i-1,PETSC_TRUE));
826  }
827  else if(i==N){
828  value = 0.5/((PetscScalar)i)*(1.0*a(i-1,PETSC_TRUE));
829  }
830  else{
831  value = 0.5/((PetscScalar)i)*(1.0*a(i-1,PETSC_TRUE) - a(i+1,PETSC_TRUE));
832  }
833  d(i,value);
834  if((i%2)==0){ // even
835  d0 -= value;
836  }
837  else{ // odd
838  d0 += value;
839  }
840  }
841  d(0,d0);
842  d(); // assemble
843  return sum(d);
844  }
846  PetscScalar integrate_coeffs(
847  const SPIVec &a,
848  const SPIVec &y
849  ){
850  PetscScalar ai=y(0,PETSC_TRUE);
851  PetscScalar bi=y(y.rows-1,PETSC_TRUE);
852  PetscScalar mul = (bi-ai)/2.0;
853  return mul*integrate_coeffs(a);
854  }
855 
856 
857 
859  PetscReal L2(
860  SPIVec x1,
861  const SPIVec x2,
862  NormType type
863  ){
864  PetscReal error;
865  VecNorm((x1-x2).vec,type,&error);
866  return error;
867  }
868 
869 
871  PetscReal L2(
872  const SPIVec x1,
873  NormType type
874  ){
875  PetscReal error;
876  VecNorm(x1.vec,type,&error);
877  return error;
878  }
879 
882  SPIVec x
883  ){
884  SPIVec x0(x.rows-1), x1(x.rows-1);
885  // set x0=x[i] and x1=x[i+1]
886  for (PetscInt i=0; i<x.rows-1; ++i){
887  x0(i,x(i,PETSC_TRUE));
888  x1(i,x(i+1,PETSC_TRUE));
889  }
890  // assemble
891  x0();
892  x1();
893  // return difference x[i+1]-x[i]
894  return x1-x0;
895  }
896 
898  PetscScalar trapz(
899  SPIVec y
900  ){
901  SPIVec y0(y.rows-1), y1(y.rows-1);
902  // set y0=y[i] and y1=y[i+1]
903  for (PetscInt i=0; i<y.rows-1; ++i){
904  y0(i,y(i,PETSC_TRUE));
905  y1(i,y(i+1,PETSC_TRUE));
906  }
907  // assemble
908  y0();
909  y1();
910  // return trapezoidal rule sum((y[i+1]+y[i])/2.
911  return sum((y1+y0)/2.);
912  }
913 
915  PetscScalar trapz(
916  SPIVec y,
917  SPIVec x
918  ){
919  SPIVec y0(y.rows-1), y1(y.rows-1);
920  // set y0=y[i] and y1=y[i+1]
921  for (PetscInt i=0; i<y.rows-1; ++i){
922  y0(i,y(i,PETSC_TRUE));
923  y1(i,y(i+1,PETSC_TRUE));
924  }
925  // assemble
926  y0();
927  y1();
928  // return trapezoidal rule sum((y[i+1]+y[i])/2. * diff(x))
929  return sum((y1+y0)/2. * diff(x));
930  }
932  PetscInt draw(
933  const SPIVec &x
934  ){
935  PetscViewer viewer;
936  PetscErrorCode ierr;
937  ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,NULL,x.name.c_str(),PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&viewer);CHKERRQ(ierr);
938  ierr = VecView(x.vec,viewer);CHKERRQ(ierr);
939  SPI::printf(" draw(SPIVec) with title=%s, hit Enter to continue",x.name.c_str());
940  std::cin.ignore();
941 
942  ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
943  return 0;
944  }
945 
946 }
947 
948 
SPI::SPIVec::SPIVec
SPIVec(std::string _name="SPIVec")
constructor with no arguments (no initialization)
Definition: SPIVec.cpp:9
SPI::sin
SPIMat sin(const SPIMat &A)
take the sin of each element in a matrix
Definition: SPIMat.cpp:2025
SPI::real
SPIVec real(const SPIVec &A)
return the real part of the vector
Definition: SPIVec.cpp:631
SPI::SPIVec::operator()
SPIVec & operator()()
Definition: SPIVec.cpp:170
SPI::atanh
SPIVec atanh(const SPIVec &A)
take the atanh of each element in a vector
Definition: SPIVec.cpp:739
SPI::SPIVec::real
SPIVec & real()
take the real part of the vector
Definition: SPIVec.cpp:449
SPI::operator-
SPIVec operator-(const PetscScalar a, const SPIVec &A)
Definition: SPIVec.cpp:532
SPI::erf
SPIVec erf(const SPIVec &A)
take the erf of each element in a vector
Definition: SPIVec.cpp:743
SPI::SPIVec::operator==
PetscBool operator==(const SPIVec &x2)
== VecEqual test if this==x2
Definition: SPIVec.cpp:404
SPI::acosh
SPIVec acosh(const SPIVec &A)
take the acosh of each element in a vector
Definition: SPIVec.cpp:737
SPI::arange
SPIVec arange(const PetscScalar begin, const PetscScalar end, const PetscScalar stepsize=1)
return a range of number of equally spaced points between begin and end by step size step
Definition: SPIVec.cpp:667
SPI::SPIVec::operator=
SPIVec & operator=(const SPIVec &X)
Definition: SPIVec.cpp:382
SPI::SPIVec
Definition: SPIVec.hpp:13
SPI::printf
PetscInt printf(std::string msg,...)
Definition: SPIprint.cpp:5
SPI::SPIVec::flag_init
PetscBool flag_init
flag if it has been initialized
Definition: SPIVec.hpp:25
SPI
Definition: SPIbaseflow.hpp:16
SPI::sum
PetscScalar sum(SPIVec x)
take the sum of a vector
Definition: SPIVec.cpp:805
SPI::SPIVec::operator*
SPIVec operator*(const PetscScalar a)
Definition: SPIVec.cpp:271
SPI::conj
SPIVec conj(const SPIVec &A)
Definition: SPIVec.cpp:622
SPI::SPIVec::operator*=
SPIVec & operator*=(const PetscScalar a)
Definition: SPIVec.cpp:289
SPI::ones
SPIVec ones(const PetscInt rows)
Definition: SPIVec.cpp:605
SPI::save
PetscInt save(const SPIMat &A, const std::string filename)
save matrix to filename in binary format (see Petsc documentation for format ) Format is (from Petsc ...
Definition: SPIMat.cpp:1924
SPI::cosh
SPIVec cosh(const SPIVec &A)
take the cosh of each element in a vector
Definition: SPIVec.cpp:725
SPI::L2
PetscReal L2(SPIVec x1, const SPIVec x2, NormType type=NORM_2)
calculate the norm of the difference between and vectors.
Definition: SPIVec.cpp:859
SPI::diff
SPIVec diff(SPIVec x1)
diff of the vector (see numpy.diff)
Definition: SPIVec.cpp:881
SPI::SPIVec::operator^
SPIVec operator^(const PetscScalar p)
pow operation pow(this,p)
Definition: SPIVec.cpp:357
SPI::SPIVec::operator/=
SPIVec & operator/=(const PetscScalar a)
Definition: SPIVec.cpp:349
SPI::log
SPIVec log(const SPIVec &A)
take the log (natural log) of each element in a vector
Definition: SPIVec.cpp:719
SPI::SPIVec::print
PetscInt print()
Definition: SPIVec.cpp:470
SPI::asinh
SPIVec asinh(const SPIVec &A)
take the asinh of each element in a vector
Definition: SPIVec.cpp:735
SPI::SPIVec::operator-
SPIVec operator-() const
Definition: SPIVec.cpp:266
SPI::linspace
SPIVec linspace(const PetscScalar begin, const PetscScalar end, const PetscInt rows)
return linspace of number of rows equally spaced points between begin and end
Definition: SPIVec.cpp:645
SPI::_Function_on_each_element
SPIMat _Function_on_each_element(T(*f)(T const &), const SPIMat &A)
take the function of each element in a matrix, e.g. (*f)(A(i,j)) for each i,j
Definition: SPIMat.cpp:2011
SPI::SPIVec::name
std::string name
Vec name (important for hdf5 i/o)
Definition: SPIVec.hpp:26
SPI::log10
SPIVec log10(const SPIVec &A)
take the log10 of each element in a vector
Definition: SPIVec.cpp:721
SPI::draw
PetscInt draw(const SPIMat &A)
draw nonzero structure of matrix
Definition: SPIMat.cpp:1994
SPI::imag
SPIVec imag(const SPIVec &A)
return the imaginary part of the vector
Definition: SPIVec.cpp:638
SPI::dot
PetscScalar dot(SPIVec x, SPIVec y)
take the inner product of the two vectors (i.e. y^H x) where ^H is the complex conjugate transpose
Definition: SPIVec.cpp:788
SPI::exp
SPIVec exp(const SPIVec &A)
take the exp of each element in a vector
Definition: SPIVec.cpp:712
SPI::tan
SPIMat tan(const SPIMat &A)
take the tan of each element in a matrix
Definition: SPIMat.cpp:2031
SPI::SPIVec::set
PetscInt set(const PetscInt _row, const PetscScalar v)
Definition: SPIVec.cpp:64
SPI::trapz
PetscScalar trapz(const SPIVec y)
trapezoidal integration of y with unity coordinate spacing,
Definition: SPIVec.cpp:898
SPI::SPIVec::operator+
SPIVec operator+(const SPIVec &X)
Definition: SPIVec.cpp:193
SPI::SPIVec::size
PetscInt size()
Definition: SPIVec.cpp:96
SPI::abs
SPIMat abs(const SPIMat &A)
take the abs of each element in a matrix
Definition: SPIMat.cpp:2045
SPI::SPIVec::operator-=
SPIVec & operator-=(const SPIVec &X)
Definition: SPIVec.cpp:244
SPI::integrate_coeffs
PetscScalar integrate_coeffs(const SPIVec &a)
integrate a vector of chebyshev Coefficients on a grid
Definition: SPIVec.cpp:813
SPI::SPIVec::ierr
PetscErrorCode ierr
ierr for various routines and operators
Definition: SPIVec.hpp:22
SPI::SPIVec::operator/
SPIVec operator/(const PetscScalar a)
Definition: SPIVec.cpp:323
SPIVec.hpp
SPI::SPIVec::axpy
SPIVec & axpy(const PetscScalar a, const SPIVec &X)
Definition: SPIVec.cpp:184
SPI::atan
SPIVec atan(const SPIVec &A)
take the atan of each element in a vector
Definition: SPIVec.cpp:733
SPI::sqrt
SPIVec sqrt(const SPIVec &A)
take the atanh of each element in a vector
Definition: SPIVec.cpp:741
SPI::SPIVec::~SPIVec
~SPIVec()
Definition: SPIVec.cpp:483
SPI::erfc
SPIVec erfc(const SPIVec &A)
take the erfc(z) = 1-erf(z) of each element in a vector
Definition: SPIVec.cpp:752
SPI::load
PetscInt load(SPIMat &A, const std::string filename)
load matrix from filename from binary format (works with save(SPIMat,std::string) function
Definition: SPIMat.cpp:1966
SPI::asin
SPIVec asin(const SPIVec &A)
take the asin of each element in a vector
Definition: SPIVec.cpp:729
SPI::pow
SPIVec pow(const SPIVec &A, SPIVec &B)
take the pow of each element in the vectors
Definition: SPIVec.cpp:775
SPI::SPIVec::operator+=
SPIVec & operator+=(const SPIVec &X)
Definition: SPIVec.cpp:177
SPI::tanh
SPIVec tanh(const SPIVec &A)
take the tanh of each element in a vector
Definition: SPIVec.cpp:727
SPI::SPIVec::argmax
PetscInt argmax()
Definition: SPIVec.cpp:437
SPI::sinh
SPIVec sinh(const SPIVec &A)
take the sinh of each element in a vector
Definition: SPIVec.cpp:723
SPI::acos
SPIMat acos(const SPIMat &A)
take the arccos of each element in a matrix
Definition: SPIMat.cpp:2029
SPI::SPIVec::conj
SPIVec & conj()
Definition: SPIVec.cpp:419
SPI::SPIVec::Init
PetscInt Init(const PetscInt _rows, const std::string name="SPIVec")
initialize the vector of size _rows
Definition: SPIVec.cpp:44
SPI::SPIVec::rows
PetscInt rows
number of rows in vec
Definition: SPIVec.hpp:14
SPI::SPIVec::dot
PetscScalar dot(SPIVec y)
take the inner product of two vectors
Definition: SPIVec.cpp:459
SPI::operator*
SPIMat operator*(const PetscScalar a, const SPIMat A)
a*A operation to be equivalent to A*a
Definition: SPIMat.cpp:517
SPI::SPIVec::imag
SPIVec & imag()
take the imaginary part of the vector
Definition: SPIVec.cpp:454
SPI::operator+
SPIVec operator+(const PetscScalar a, const SPIVec &A)
Definition: SPIVec.cpp:521
SPI::cos
SPIMat cos(const SPIMat &A)
take the cos of each element in a matrix
Definition: SPIMat.cpp:2027
SPI::SPIVec::add
PetscInt add(PetscInt _row, const PetscScalar v)
Definition: SPIVec.cpp:83
SPI::operator/
SPIVec operator/(const SPIVec &b, const SPIMat &A)
Solve linear system, Ax=b using b/A notation.
Definition: SPIMat.cpp:535
SPI::SPIVec::vec
Vec vec
petsc Vec data
Definition: SPIVec.hpp:21
SPI::SPIVec::max
PetscScalar max()
Definition: SPIVec.cpp:425
SPI::zeros
SPIMat zeros(const PetscInt m, const PetscInt n)
create, form, and return zeros matrix of size mxn
Definition: SPIMat.cpp:708