1 #define lapack_complex_double std::complex<double> 171 #define lapack_complex_float std::complex<float> 175 #ifndef _STL_VECTOR_H 178 #ifndef _GLIBCXX_VALARRAY 181 #ifndef _GLIBCXX_IOSTREAM 184 #if !defined _GLIBCXX_CMATH || !defined _GLIBCXX_MATH_H 187 #ifndef _GLIBCXX_COMPLEX 190 #ifndef _GLIBCXX_NUMERIC_LIMITS 193 #ifndef _GLIBCXX_ALGORITHM 197 #include <mkl_dfti.h> 200 #include <eigen3/Eigen/Eigen> 207 void feastinit_(
int *feastparam);
210 void zfeast_gegv_(
int *
N, std::complex<double> *A,
int *LDA,
211 std::complex<double> *B,
int *LDB,
int *feastparam,
212 double *epsout,
int *loop,
double *Emid,
double *r,
int *M0,
213 std::complex<double> *lambda, std::complex<double> *q,
214 int *mode,
double *res,
int *info);
223 #ifdef SIS_USE_LAPACK 225 void dgeev_(
char *jobvl,
char *jobvr,
int *n,
double *a,
int *lda,
double *wr,
226 double *wi,
double *vl,
int *ldvl,
double *vr,
int *ldvr,
227 double *work,
int *lwork,
double *rwork,
int *info);
230 void dggev_(
char *jobvl,
char *jobvr,
int *n,
double *a,
int *lda,
double *b,
231 int *ldb,
double *alphar,
double *alphai,
double *beta,
double *vl,
232 int *ldvl,
double *vr,
int *ldvr,
double *wkopt,
int *lwork,
233 double *rwork,
int *info);
236 void zgeev_(
char *jobvl,
char *jobvr,
int *n, std::complex<double> *a,
int *lda,
237 std::complex<double> *w, std::complex<double> *vl,
int *ldvl,
238 std::complex<double> *vr,
int *ldvr, std::complex<double> *work,
239 int *lwork,
double *rwork,
int *info);
242 void zggev_(
char *jobvl,
char *jobvr,
int *n, std::complex<double> *a,
int *lda,
243 std::complex<double> *b,
int *ldb, std::complex<double> *alpha,
244 std::complex<double> *beta, std::complex<double> *vl,
int *ldvl,
245 std::complex<double> *vr,
int *ldvr, std::complex<double> *wkopt,
246 int *lwork,
double *rwork,
int *info);
264 std::valarray<std::complex<T> >
dou2com(
const std::valarray<T> &a,
265 const std::valarray<T> &b) {
266 std::valarray<std::complex<T> > temp;
268 temp.resize(a.size());
269 for (
int i = 0; i < a.size(); i++) {
270 temp[i] = std::complex<T>(a[i], b[i]);
280 template <
class T> valarray<T>
real(
const valarray<complex<T> > &in) {
283 temp.resize(in.size());
284 for (
int i = 0; i < temp.size(); i++) {
285 temp[i] =
real(in[i]);
291 template <
class T> valarray<T>
imag(
const valarray<complex<T> > &in) {
293 temp.resize(in.size());
294 for (
int i = 0; i < temp.size(); i++) {
295 temp[i] =
imag(in[i]);
302 std::valarray<std::complex<T> >
operator*(std::complex<T> left,
303 std::valarray<T> right) {
304 std::valarray<T> re(right.size()), im(right.size());
305 re =
real(left) * right;
306 im =
imag(left) * right;
312 std::valarray<std::complex<T> >
operator*(
const std::valarray<T> &left,
313 const std::complex<T> &right) {
314 std::valarray<T> re(left.size()), im(left.size());
315 re = left *
real(right);
316 im = left *
imag(right);
322 std::valarray<std::complex<T> >
operator+(std::complex<T> left,
323 std::valarray<T> right) {
324 std::valarray<T> re(right.size()), im(right.size());
325 re =
real(left) + right;
333 std::valarray<std::complex<T> >
operator+(
const std::valarray<T> &left,
334 std::complex<T> right) {
335 std::valarray<T> re(left.size()), im(left.size());
336 re.resize(left.size());
337 im.resize(left.size());
338 re = left +
real(right);
344 std::valarray<std::complex<T> >
operator-(std::complex<T> left,
345 std::valarray<T> right) {
346 std::valarray<T> re(right.size()), im(right.size());
347 re.resize(right.size());
348 im.resize(right.size());
349 re =
real(left) - right;
356 std::valarray<std::complex<T> >
operator-(
const std::valarray<T> &left,
357 const std::complex<T> &right) {
358 std::valarray<T> re(left.size()), im(left.size());
359 re = left -
real(right);
366 std::valarray<std::complex<T> >
367 operator*(T left, std::valarray<std::complex<T> > right) {
368 std::valarray<T> re(right.size()), im(right.size());
369 im = left *
imag(right);
370 re = left *
real(right);
376 std::valarray<std::complex<T> >
377 operator*(
const std::valarray<std::complex<T> > &left,
const T &right) {
378 std::valarray<T> re(left.size()), im(left.size());
379 re =
real(left) * right;
380 im =
imag(left) * right;
386 std::valarray<std::complex<T> >
387 operator+(T left, std::valarray<std::complex<T> > right) {
388 std::valarray<T> re(right.size()), im(right.size());
389 re = left +
real(right);
396 std::valarray<std::complex<T> >
397 operator+(
const std::valarray<std::complex<T> > &left,
const T &right) {
398 std::valarray<T> re(left.size()), im(left.size());
399 re =
real(left) + right;
405 std::valarray<std::complex<T> >
406 operator-(T left, std::valarray<std::complex<T> > right) {
407 std::valarray<T> re(right.size()), im(right.size());
408 re = left -
real(right);
415 std::valarray<std::complex<T> >
416 operator-(
const std::valarray<std::complex<T> > &left,
const T &right) {
417 std::valarray<T> re(left.size()), im(left.size());
418 re =
real(left) - right;
425 std::valarray<std::complex<T> >
427 const std::valarray<T> &right) {
428 std::valarray<T> re(right.size()), im(right.size());
429 re =
real(left) * right;
430 im =
imag(left) * right;
436 std::valarray<std::complex<T> >
438 const std::valarray<std::complex<T> > &right) {
439 std::valarray<T> re(left.size()), im(left.size());
440 re = left *
real(right);
441 im = left *
real(right);
453 valarray<complex<T> >
pow(valarray<complex<T> > base, T power) {
454 complex<T> power_ = complex<T>(power, 0.0);
455 valarray<complex<T> > out =
pow(base, power_);
464 #define PI 3.141592653589793 466 #define SIS_SINGULAR 1 468 #define SIS_SVD_LEFT 1 469 #define SIS_SVD_RIGHT 2 470 #define SIS_PHYS_SPACE 1 471 #define SIS_CHEB_SPACE 0 479 std::complex<double> center(0.0, 0.0);
480 double radius = 10.0;
482 void feast_init() { feastinit_(feastparam); }
485 std::cout <<
"Error: Problem with size of system N" <<
'\n';
486 }
else if (info == 201) {
487 std::cout <<
"Error: Problem with subspace M0" <<
'\n';
488 }
else if (info == 200) {
489 std::cout <<
"Error: Problem with Emin, Emax, Emid, r" <<
'\n';
490 }
else if (info == 6) {
491 std::cout <<
"Warning: FEAST converges but subspace is not bi-orthogonal" 493 }
else if (info == 5) {
494 std::cout <<
"Warning: Only stochastic estimation of #eigenvalues returned " 497 }
else if (info == 4) {
498 std::cout <<
"Warning: Only the subspace has been returned using fpm(14)=1" 500 }
else if (info == 3) {
501 std::cout <<
"Warning: Size of the subspace M0 is too small (M0<=M)" 503 }
else if (info == 2) {
504 std::cout <<
"Warning: No Convergence (#iteration loops>fpm(4))" <<
'\n';
505 }
else if (info == 1) {
506 std::cout <<
"Warning: No Eigenvalue found in the search interval" <<
'\n';
507 }
else if (info == 0) {
508 std::cout <<
"Error: Successful exit" <<
'\n';
509 }
else if (info == -1) {
510 std::cout <<
"Error: Internal error for allocation memory" <<
'\n';
511 }
else if (info == -2) {
512 std::cout <<
"Error: Internal error of the inner system solver in FEAST " 513 "predefined interfaces" 515 }
else if (info == -3) {
516 std::cout <<
"Error: Internal error of the reduced eigenvalue solver. " 517 <<
"Possible cause for Hermitian problem: matrix B may not be " 521 std::cout <<
"Error: Problem with " << info - 100
522 <<
"th parameter of feast parameter" <<
'\n';
535 #define SIS_TYPE double 540 std::valarray<SIS_TYPE>
y(
N + 1);
541 Eigen::Matrix<std::complex<SIS_TYPE>, Eigen::Dynamic, Eigen::Dynamic>
ycEigen;
542 Eigen::Matrix<SIS_TYPE, Eigen::Dynamic, Eigen::Dynamic>
yEigen;
544 template <
class T> std::valarray<std::complex<T> >
fft(std::valarray<T> in1) {
547 std::valarray<std::complex<T> > out(n);
548 std::valarray<T> zvec(n);
550 out[0] = std::complex<T>(in1[0], 0.0);
551 DFTI_DESCRIPTOR_HANDLE descriptor;
554 status = DftiCreateDescriptor(&descriptor, DFTI_DOUBLE, DFTI_REAL, 1,
557 status = DftiSetValue(descriptor, DFTI_PLACEMENT,
559 status = DftiSetValue(descriptor, DFTI_CONJUGATE_EVEN_STORAGE,
560 DFTI_COMPLEX_COMPLEX);
563 status = DftiCommitDescriptor(descriptor);
565 status = DftiComputeForward(descriptor, &in1[0],
568 status = DftiFreeDescriptor(&descriptor);
570 for (
int j = 0; j < n / 2; j++)
571 out[n / 2 + j] =
std::conj(out[n / 2 - j]);
577 std::valarray<std::complex<T> >
fft(std::slice_array<T> in1) {
578 return fft(std::valarray<T>(in1));
582 std::valarray<T>
ifft_cs(std::valarray<std::complex<T> > in)
587 std::valarray<T> out(2 * n);
588 out[0] =
real(in[0]);
589 std::valarray<std::complex<T> > in1(std::complex<T>(0.0, 0.0), n + 1);
590 in1[std::slice(0, n, 1)] = in;
591 DFTI_DESCRIPTOR_HANDLE descriptor;
594 status = DftiCreateDescriptor(&descriptor, DFTI_DOUBLE, DFTI_REAL, 1,
597 status = DftiSetValue(descriptor, DFTI_PLACEMENT,
599 status = DftiSetValue(descriptor, DFTI_CONJUGATE_EVEN_STORAGE,
600 DFTI_COMPLEX_COMPLEX);
602 status = DftiCommitDescriptor(descriptor);
604 status = DftiComputeBackward(descriptor, &in1[0],
607 status = DftiFreeDescriptor(&descriptor);
609 out = out / T(2 * n);
614 std::valarray<T>
ifft_cs(std::slice_array<std::complex<T> > in) {
615 return ifft_cs(std::valarray<std::complex<T> >(in));
617 template <
class T> std::valarray<T>
dct(
const std::valarray<T> &x) {
620 std::valarray<T>
y(2 * n), v(n);
621 std::valarray<std::complex<T> > V(n);
622 for (
int i = 0; i < n; i++)
625 for (
int i = n; i < 2 * n; i++)
626 y[i] = x[2 * n - i - 1];
628 for (
int i = 0; i < n; i++)
631 return 2.0 *
real(std::valarray<std::complex<T> >(
half_shift * V)) / T(n);
634 template <
class T> std::valarray<T>
dct(
const std::slice_array<T> &x) {
635 return dct(std::valarray<T>(x));
638 template <
class T> std::valarray<T>
idct(
const std::valarray<T> &u) {
641 std::valarray<T> temp_u(n + 1);
642 std::valarray<T> x(n), v(n);
644 temp_u[std::slice(0, n, 1)] = u;
645 std::valarray<std::complex<T> > V(n);
646 for (
int i = 0; i < n; i++) {
648 std::complex<T>(temp_u[i], 0.0) - std::complex<T>(0.0, temp_u[n - i]);
652 v =
ifft_cs(std::valarray<std::complex<T> >(V[std::slice(0, n / 2, 1)]));
654 for (
int i = 0; i < (n + 1) / 2; i++)
656 for (
int i = (n + 1) / 2; i < n; i++)
657 x[2 * n - 2 * i - 1] = v[i];
661 template <
class T> std::valarray<T>
idct(
const std::slice_array<T> &u) {
662 return idct(std::valarray<T>(u));
666 std::valarray<std::complex<T> >
dct(
const std::valarray<std::complex<T> > &in) {
667 int n = in.size() - 1;
668 std::valarray<T> inr(n + 1), ini(n + 1);
677 std::valarray<std::complex<T> >
678 dct(
const std::slice_array<std::complex<T> > &in) {
679 return dct(std::valarray<std::complex<T> >(in));
683 std::valarray<std::complex<T> >
684 idct(
const std::valarray<std::complex<T> > &in) {
685 int n = in.size() - 1;
687 std::valarray<T> inr(in.size()), ini(in.size());
696 std::valarray<std::complex<T> >
697 idct(
const std::slice_array<std::complex<T> > &in) {
698 return idct(std::valarray<std::complex<T> >(in));
708 std::valarray<std::complex<T> >
fft2(std::valarray<T> in1,
int Nx,
int Nz) {
710 std::valarray<std::complex<T> > result(Nx * (Nz / 2 + 1)), out(Nx * Nz / 2);
711 result[0] = std::complex<T>(in1[0], 0.0);
712 DFTI_DESCRIPTOR_HANDLE descriptor;
715 DFTI_DESCRIPTOR_HANDLE hand = 0;
719 status = DftiCreateDescriptor(&hand, DFTI_DOUBLE, DFTI_REAL, 2, n);
720 status = DftiSetValue(hand, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
722 DftiSetValue(hand, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
727 status = DftiSetValue(hand, DFTI_INPUT_STRIDES, rs);
732 status = DftiSetValue(hand, DFTI_OUTPUT_STRIDES, cs);
733 status = DftiCommitDescriptor(hand);
734 status = DftiComputeForward(hand, &in1[0], &result[0]);
735 DftiFreeDescriptor(&hand);
736 for (
int j = 0; j < Nx; j++) {
737 for (
int k = 0; k < Nz / 2; k++) {
738 out[j * (Nz / 2) + k] = result[j * (Nz / 2 + 1) + k];
744 for (
int k = 0; k < Nz / 2; k++) {
745 out[j * (Nz / 2) + k] = 0.0;
765 std::valarray<T>
ifft2_cs(std::valarray<std::complex<T> > in1,
int Nx,
int Nz) {
767 std::valarray<std::complex<T> > in(Nx * (Nz / 2 + 1));
768 std::valarray<T> out(Nx * Nz);
769 in = std::complex<T>(0.0, 0.0);
770 for (
int j = 0; j < Nx; j++) {
771 for (
int k = 0; k < Nz / 2; k++) {
772 in[j * (Nz / 2 + 1) + k] = in1[j * (Nz / 2) + k];
786 DFTI_DESCRIPTOR_HANDLE hand = 0;
790 status = DftiCreateDescriptor(&hand, DFTI_DOUBLE, DFTI_REAL, 2, n);
791 status = DftiSetValue(hand, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
793 DftiSetValue(hand, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
798 status = DftiSetValue(hand, DFTI_INPUT_STRIDES, cs);
803 status = DftiSetValue(hand, DFTI_OUTPUT_STRIDES, rs);
804 status = DftiCommitDescriptor(hand);
805 status = DftiComputeBackward(hand, &in[0], &out[0]);
806 DftiFreeDescriptor(&hand);
807 out = out / double(Nx * Nz);
818 std::valarray<std::complex<T> >
fft2(std::slice_array<T> in1,
int Nx,
int Nz) {
819 return fft2(std::valarray<T>(in1), Nx, Nz);
823 std::valarray<T>
ifft2_cs(std::slice_array<std::complex<T> > in,
int Nx,
825 return ifft2_cs(std::valarray<std::complex<T> >(in), Nx, Nz);
861 std::valarray<std::complex<T> >
dealias_prod_2D(std::valarray<std::complex<T> > a, std::valarray<std::complex<T> > b,
int Nx,
int Nz){
862 std::valarray<std::complex<T> > tempa(0.0,(3*Nx/2) * (3*(Nz/2)/2)), tempb(0.0,(3*Nx/2) * (3*(Nz/2)/2));
865 for (
int i = 0; i< Nx/2; i++) {
866 tempa[std::slice(i*3*Nz/4,Nz/2,1)] = a[std::slice(i*Nz/2,Nz/2,1)];
867 tempa[std::slice(i*3*Nz/4 + Nx*3*Nz/4 ,Nz/2,1)] = a[std::slice(i*Nz/2+Nx*Nz/4,Nz/2,1)];
868 tempb[std::slice(i*3*Nz/4,Nz/2,1)] = b[std::slice(i*Nz/2,Nz/2,1)];
869 tempb[std::slice(i*3*Nz/4 + Nx*3*Nz/4 ,Nz/2,1)] = b[std::slice(i*Nz/2+Nx*Nz/4,Nz/2,1)];
873 std::valarray<T> tempar((3*(Nx)/2) * (3*(Nz)/2));
874 std::valarray<T> tempbr((3*(Nx)/2) * (3*(Nz)/2));
880 tempar = tempar * tempbr;
886 for (
int i = 0; i< Nx/2; i++){
887 a[std::slice(i*Nz/2,Nz/2,1)] = tempa[std::slice(i*3*Nz/4,Nz/2,1)];
888 a[std::slice(i*Nz/2+Nx*Nz/4,Nz/2,1)] = tempa[std::slice(i*3*Nz/4 + Nx*3*Nz/4 ,Nz/2,1)];
891 a = a*std::complex<T>(9.0/4.0,0.0);
901 size(
const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> &in) {
902 return std::complex<T>(in.rows(), in.cols());
907 size(
const Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> &in) {
908 return std::complex<T>(in.rows(), in.cols());
912 template <
class T>
void disp(std::valarray<T> in) {
913 for (
int i = 0; i < in.size(); i++) {
914 std::cout << in[i] <<
"\n";
922 for (
int i = 0; i <
N + 1; i++)
923 in[i] = cos(M_PI * (i + 0.5) / (
N + 1.0));
929 template <
class T>
void setChebPts(std::valarray<std::complex<T> > &in) {
931 for (
int i = 0; i <
N + 1; i++)
932 in[i] = std::complex<T>(cos(
PI * (i + 0.5) / (
N + 1.0)), 0.0);
938 template <
class T>
void setChebPts(Eigen::Array<T, Eigen::Dynamic, 1> &in) {
940 for (
int i = 0; i <
N + 1; i++)
941 in[i] = cos(
PI * (i + 0.5) / (
N + 1.0));
948 void setChebPts(Eigen::Array<std::complex<T>, Eigen::Dynamic, 1> &in) {
950 for (
int i = 0; i <
N + 1; i++)
951 in[i] = std::complex<T>(cos(
PI * (i + 0.5) / (
N + 1.0)), 0.0);
955 std::complex<SIS_TYPE>
ii;
956 ii = std::complex<SIS_TYPE>(0.0, 1.0);
965 for (
int i = 0; i <
N + 1; i++) {
967 exp(-
ii * std::complex<SIS_TYPE>(M_PI * i / (2.0 * (
N + 1)), 0.0));
969 exp(
ii * std::complex<SIS_TYPE>(M_PI * i / (2.0 * (
N + 1)), 0.0));
972 for (
int i = 0; i <
N + 1; i++) {
986 Eigen::Matrix<T, Eigen::Dynamic, 1>
987 diff(
const Eigen::Matrix<T, Eigen::Dynamic, 1> &u) {
988 int n = u.size() - 1;
989 Eigen::Matrix<T, Eigen::Dynamic, 1> du(n + 1);
990 du[n - 1] = 2.0 * n * u[n];
993 for (
int i = 1; i < (n + 1) / 2; i++) {
994 du[n - (2 * i + 1)] =
995 du[n - (2 * i - 1)] + 2.0 * (n - 2 * i) * u[n - 2 * i];
998 for (
int i = 1; i < (n + 1) / 2; i++) {
1000 du[n - 2 * (i - 1)] + 2.0 * (n - (2 * i - 1)) * u[n + 1 - 2 * i];
1007 template <
class T> std::valarray<T>
diff(
const std::valarray<T> &u) {
1008 int n = u.size() - 1;
1009 std::valarray<T> du(n + 1);
1010 du[n - 1] = 2.0 * n * u[n];
1013 for (
int i = 1; i < (n + 1) / 2; i++) {
1014 du[n - (2 * i + 1)] =
1015 du[n - (2 * i - 1)] + 2.0 * (n - 2 * i) * u[n - 2 * i];
1018 for (
int i = 1; i < (n + 1) / 2; i++) {
1020 du[n - 2 * (i - 1)] + 2.0 * (n - (2 * i - 1)) * u[n + 1 - 2 * i];
1030 Eigen::Matrix<T, Eigen::Dynamic, 1>
1031 integ(
const Eigen::Matrix<T, Eigen::Dynamic, 1> &u) {
1032 int n = u.size() - 1;
1034 Eigen::Matrix<T, Eigen::Dynamic, 1> I1v(u.size());
1035 I1v.setConstant(0.0);
1040 Eigen::Matrix<T, Eigen::Dynamic, 1> uodd(nodd), ueve(neve);
1041 uodd.setConstant(0.0);
1042 ueve.setConstant(0.0);
1043 for (i = 0; i < neve; i++)
1046 for (i = 0; i < nodd; i++)
1047 uodd[i] = u[2 * i + 1];
1049 I1v[0] = uodd[0] / 4.0;
1051 for (i = 1; i < neve; i++)
1052 I1v[2 * i] = (uodd[i - 1] - uodd[i]) / (4.0 * i);
1054 for (i = 0; i < nodd - 1; i++)
1055 I1v[2 * i + 1] = (ueve[i] - ueve[i + 1]) / (4 * i + 2.0);
1057 I1v[2 * i + 1] = ueve[i] / (4.0 * i + 2.0);
1066 template <
class T> std::valarray<T>
integ(
const std::valarray<T> &u) {
1067 int n = u.size() - 1;
1069 std::valarray<T> I1v(u.size());
1075 std::valarray<T> uodd(nodd), ueve(neve);
1078 for (i = 0; i < neve; i++)
1081 for (i = 0; i < nodd; i++)
1082 uodd[i] = u[2 * i + 1];
1084 I1v[0] = uodd[0] / 4.0;
1086 for (i = 1; i < neve; i++)
1087 I1v[2 * i] = (uodd[i - 1] - uodd[i]) / (4.0 * i);
1089 for (i = 0; i < nodd - 1; i++)
1090 I1v[2 * i + 1] = (ueve[i] - ueve[i + 1]) / (4 * i + 2.0);
1092 I1v[2 * i + 1] = ueve[i] / (4.0 * i + 2.0);
1098 Eigen::Array<T, Eigen::Dynamic, 1>
1099 integ(
const Eigen::Array<T, Eigen::Dynamic, 1> &u) {
1100 int n = u.size() - 1;
1102 Eigen::Matrix<T, Eigen::Dynamic, 1> I1v(u.size());
1103 I1v.setConstant(0.0);
1108 Eigen::Matrix<T, Eigen::Dynamic, 1> uodd(nodd), ueve(neve);
1109 uodd.setConstant(0.0);
1110 ueve.setConstant(0.0);
1111 for (i = 0; i < neve; i++)
1114 for (i = 0; i < nodd; i++)
1115 uodd[i] = u[2 * i + 1];
1117 I1v[0] = uodd[0] / 4.0;
1119 for (i = 1; i < neve; i++)
1120 I1v[2 * i] = (uodd[i - 1] - uodd[i]) / (4.0 * i);
1122 for (i = 0; i < nodd - 1; i++)
1123 I1v[2 * i + 1] = (ueve[i] - ueve[i + 1]) / (4 * i + 2.0);
1125 I1v[2 * i + 1] = ueve[i] / (4.0 * i + 2.0);
1132 Eigen::Array<std::complex<T>, Eigen::Dynamic, 1>
1133 dou2com(
const Eigen::Array<T, Eigen::Dynamic, 1> &a,
1134 const Eigen::Array<T, Eigen::Dynamic, 1> &b) {
1135 Eigen::Array<std::complex<T>, Eigen::Dynamic, 1> temp;
1136 temp.resize(a.size());
1137 for (
int i = 0; i < a.size(); i++) {
1138 temp[i] = std::complex<T>(a[i], b[i]);
1163 for (
int i = 0; i <
N + 1; i++)
1164 v[i] = cos(
PI * (i + 0.5) / (
N + 1.0));
1168 if (in.size() !=
N + 1) {
1169 std::cout <<
"Input size for Chebfun has to be sis::N +1. If you set " 1170 "sis::N = 11, then value input valarray size must be N+1.\n " 1178 Chebfun(
const Eigen::Array<T, Eigen::Dynamic, Eigen::Dynamic> &in) {
1181 v.resize(in.size());
1182 if (in.size() !=
N + 1) {
1183 std::cout <<
"Input size for Chebfun has to be sis::N +1. If you set " 1184 "sis::N = 11, then value input valarray size must be N+1.\n " 1188 for (
int i = 0; i < in.size(); i++) {
1221 std::valarray<T>
y(2 * n), vd(n);
1222 std::valarray<std::complex<T> > V(n);
1223 for (
int i = 0; i < n; i++)
1225 for (
int i = n; i < 2 * n; i++)
1226 y[i] =
v[2 * n - i - 1];
1228 for (
int i = 0; i < n; i++)
1231 DFTI_DESCRIPTOR_HANDLE descriptor;
1234 status = DftiCreateDescriptor(&descriptor, DFTI_DOUBLE, DFTI_REAL, 1, n);
1236 status = DftiSetValue(descriptor, DFTI_PLACEMENT,
1238 status = DftiSetValue(descriptor, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
1240 status = DftiCommitDescriptor(descriptor);
1241 status = DftiComputeForward(descriptor, &vd[0], &V[0]);
1242 status = DftiFreeDescriptor(&descriptor);
1243 for (
int j = 0; j < n / 2; j++)
1249 std::cout <<
"In Cheb-space. Can't move to Cheb-space\n";
1260 std::valarray<T> temp_u(n + 1);
1261 std::valarray<T> x(n), vd(n);
1264 temp_u[std::slice(0, n, 1)] =
v;
1265 std::valarray<std::complex<T> > V(n);
1266 for (
int i = 0; i < n; i++)
1269 std::complex<T>(temp_u[i], 0.0) - std::complex<T>(0.0, temp_u[n - i]);
1273 std::valarray<std::complex<T> > in1(std::complex<T>(0.0, 0.0), n / 2 + 1);
1274 in1[std::slice(0, n / 2, 1)] = V[std::slice(0, n / 2, 1)];
1276 DFTI_DESCRIPTOR_HANDLE descriptor;
1279 status = DftiCreateDescriptor(&descriptor, DFTI_DOUBLE, DFTI_REAL, 1, n);
1280 status = DftiSetValue(descriptor, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
1281 status = DftiSetValue(descriptor, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
1282 status = DftiCommitDescriptor(descriptor);
1283 status = DftiComputeBackward(descriptor, &in1[0], &vd[0]);
1284 status = DftiFreeDescriptor(&descriptor);
1285 for (
int i = 0; i < (n + 1) / 2; i++)
1287 for (
int i = (n + 1) / 2; i < n; i++)
1288 v[2 * n - 2 * i - 1] = vd[i];
1290 std::cout <<
"In Physical-space. Can't move to Physical-space\n";
1297 Eigen::Array<T, Eigen::Dynamic, 1>
ev() {
1298 Eigen::Array<T, Eigen::Dynamic, 1> temp;
1299 temp.resize(
v.size());
1300 for (
int i = 0; i <
v.size(); i++) {
1309 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
MultMat() {
1311 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> toep(
N + 1,
N + 1),
1313 toep.setConstant(0.0);
1314 hank.setConstant(0.0);
1318 Eigen::Array<T, Eigen::Dynamic, 1> v_arr;
1319 v_arr.resize(
v.size());
1320 for (
int i = 0; i <
v.size(); i++) {
1323 Eigen::Matrix<T, Eigen::Dynamic, 1> vec(
N + 1);
1324 vec.setConstant(0.0);
1325 vec.block(0, 0,
N + 1, 1) = v_arr.matrix();
1326 for (
int i = 0; i <
N + 1; i++) {
1327 toep.block(i, i, 1,
N + 1 - i) =
1328 vec.block(0, 0,
N + 1 - i, 1).transpose();
1331 toep = toep.eval() + toep.transpose().eval();
1332 toep.diagonal() = (toep.diagonal() / 2.0).eval();
1334 hank.setConstant(0.0);
1335 for (
int i = 1; i <
N + 1; i++) {
1336 hank.block(i, 0, 1,
N - i) = vec.block(i, 0,
N - i, 1).transpose();
1339 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
1340 out = 0.5 * (toep + hank);
1341 return out.transpose();
1361 void operator=(
const Eigen::Matrix<T, Eigen::Dynamic, 1> &right) {
1362 for (
int i = 0; i <
N + 1; i++) {
1374 v[0] += 2.0 * right;
1403 if (a > 1 || a < -1) {
1404 std::cout <<
"Error: Cannot evaluate a Chebfun outside the domain" 1408 std::valarray<T> k(
N + 1);
1409 for (
int i = 0; i <
N + 1; i++) {
1412 k = cos(k * acos(a));
1457 T ans = (temp.operator()(1) - temp.operator()(-1)) / 2.0;
1462 if (abs(
v[
N - 1] +
v[
N]) / 2 < abs(std::numeric_limits<T>::epsilon())) {
1469 if (abs(
v[
N / 2] +
v[
N / 2 + 1]) / 2 <
1470 abs(std::numeric_limits<T>::epsilon())) {
1495 std::valarray<std::complex<T> >
v;
1502 for (
int i = 0; i <
N + 1; i++) {
1503 v[i] = cos(
PI * (i + 0.5) / (
N + 1.0));
1507 Chebfun(
const std::valarray<std::complex<T> > &in) {
1508 if (in.size() !=
N + 1) {
1509 std::cout <<
"Input size for Chebfun has to be sis::N +1. If you set " 1510 "sis::N = 11, then value input valarray size must be N+1.\n " 1518 Chebfun(
const Eigen::Array<std::complex<T>, Eigen::Dynamic, 1> &in) {
1519 v.resize(in.size());
1520 if (in.size() !=
N + 1) {
1521 std::cout <<
"Input size for Chebfun has to be sis::N +1. If you set " 1522 "sis::N = 11, then value input valarray size must be N+1.\n " 1526 for (
int i = 0; i < in.size(); i++) {
1533 Chebfun(
const Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> &in) {
1535 if (in.size() !=
N + 1) {
1536 std::cout <<
"Input size for Chebfun has to be sis::N +1. If you set " 1537 "sis::N = 11, then value input valarray size must be N+1.\n " 1541 for (
int i = 0; i < in.size(); i++) {
1559 std::valarray<T> vr(
v.size()), vi(
v.size());
1563 std::valarray<T>
y(2 * n), vd(n);
1564 std::valarray<std::complex<T> > V(n);
1565 for (
int i = 0; i < n; i++)
1567 for (
int i = n; i < 2 * n; i++)
1568 y[i] = vr[2 * n - i - 1];
1570 for (
int i = 0; i < n; i++)
1573 DFTI_DESCRIPTOR_HANDLE descriptor;
1576 status = DftiCreateDescriptor(&descriptor, DFTI_DOUBLE, DFTI_REAL, 1, n);
1578 status = DftiSetValue(descriptor, DFTI_PLACEMENT,
1580 status = DftiSetValue(descriptor, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
1582 status = DftiCommitDescriptor(descriptor);
1583 status = DftiComputeForward(descriptor, &vd[0], &V[0]);
1585 for (
int j = 0; j < n / 2; j++)
1589 for (
int i = 0; i < n; i++)
1591 for (
int i = n; i < 2 * n; i++)
1592 y[i] = vi[2 * n - i - 1];
1594 for (
int i = 0; i < n; i++)
1598 status = DftiComputeForward(descriptor, &vd[0], &V[0]);
1599 status = DftiFreeDescriptor(&descriptor);
1600 for (
int j = 0; j < n / 2; j++)
1607 std::cout <<
"In Cheb-space. Can't move to Cheb-space\n";
1619 std::valarray<T> vr(
v.size()), vi(
v.size());
1623 std::valarray<T> temp_u(n + 1);
1624 std::valarray<T> x(n), vd(n);
1627 temp_u[std::slice(0, n, 1)] = vr;
1628 std::valarray<std::complex<T> > V(n);
1629 for (
int i = 0; i < n; i++)
1632 std::complex<T>(temp_u[i], 0.0) - std::complex<T>(0.0, temp_u[n - i]);
1637 std::valarray<std::complex<T> > in1(std::complex<T>(0.0, 0.0), n / 2 + 1);
1638 in1[std::slice(0, n / 2, 1)] = V[std::slice(0, n / 2, 1)];
1640 DFTI_DESCRIPTOR_HANDLE descriptor;
1643 status = DftiCreateDescriptor(&descriptor, DFTI_DOUBLE, DFTI_REAL, 1,
1646 status = DftiSetValue(descriptor, DFTI_PLACEMENT,
1648 status = DftiSetValue(descriptor, DFTI_CONJUGATE_EVEN_STORAGE,
1649 DFTI_COMPLEX_COMPLEX);
1651 status = DftiCommitDescriptor(descriptor);
1653 status = DftiComputeBackward(descriptor, &in1[0],
1659 for (
int i = 0; i < (n + 1) / 2; i++)
1661 for (
int i = (n + 1) / 2; i < n; i++)
1662 vr[2 * n - 2 * i - 1] = vd[i];
1667 temp_u[std::slice(0, n, 1)] = vi;
1668 for (
int i = 0; i < n; i++)
1671 std::complex<T>(temp_u[i], 0.0) - std::complex<T>(0.0, temp_u[n - i]);
1676 in1 = std::complex<T>(0.0, 0.0);
1677 in1[std::slice(0, n / 2, 1)] = V[std::slice(0, n / 2, 1)];
1689 status = DftiComputeBackward(descriptor, &in1[0],
1692 status = DftiFreeDescriptor(&descriptor);
1695 for (
int i = 0; i < (n + 1) / 2; i++)
1697 for (
int i = (n + 1) / 2; i < n; i++)
1698 vi[2 * n - 2 * i - 1] = vd[i];
1704 std::cout <<
"In Physical-space. Can't move to Physical-space\n";
1711 Eigen::Array<T, Eigen::Dynamic, 1>
evr() {
1712 Eigen::Array<T, Eigen::Dynamic, 1> temp;
1713 temp.resize(
v.size());
1714 for (
int i = 0; i <
v.size(); i++) {
1721 Eigen::Array<T, Eigen::Dynamic, 1>
evi() {
1722 Eigen::Array<T, Eigen::Dynamic, 1> temp;
1723 temp.resize(
v.size());
1724 for (
int i = 0; i <
v.size(); i++) {
1731 Eigen::Array<std::complex<T>, Eigen::Dynamic, 1>
evc() {
1732 Eigen::Array<std::complex<T>, Eigen::Dynamic, 1> temp;
1733 temp.resize(
v.size());
1734 for (
int i = 0; i <
v.size(); i++) {
1742 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
MultMat() {
1744 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> toep(
N + 1,
1747 toep.setConstant(0.0);
1748 hank.setConstant(0.0);
1752 Eigen::Array<T, Eigen::Dynamic, 1> vr_arr, vi_arr;
1753 vr_arr.resize(
v.size());
1754 vi_arr.resize(
v.size());
1755 for (
int i = 0; i <
v.size(); i++) {
1759 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> vec(
N + 1);
1760 vec.setConstant(0.0);
1761 vec.block(0, 0,
N + 1, 1) =
dou2com(vr_arr, vi_arr).matrix();
1763 for (
int i = 0; i <
N + 1; i++) {
1764 toep.block(i, i, 1,
N + 1 - i) =
1765 vec.block(0, 0,
N + 1 - i, 1).transpose();
1768 toep = toep.eval() + toep.transpose().eval();
1769 toep.diagonal() = (toep.diagonal() / 2.0).eval();
1771 hank.setConstant(0.0);
1772 for (
int i = 1; i <
N + 1; i++) {
1773 hank.block(i, 0, 1,
N - i) = vec.block(i, 0,
N - i, 1).transpose();
1778 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> out;
1779 out = std::complex<double>(0.5, 0.0) * (toep + hank);
1783 return out.transpose();
1794 v.resize(in.
v.size());
1795 for (
int i = 0; i <
v.size(); i++)
1804 v = std::complex<T>(0.0, 0.0);
1813 operator=(
const Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> &right) {
1814 v.resize(right.size());
1815 for (
int i = 0; i < right.size(); i++) {
1821 void operator=(
const std::valarray<std::complex<T> > &right) {
v = right; }
1823 v = std::complex<T>(right, 0.0);
1846 for (
int i = 0; i <
v.size(); i++)
1851 for (
int i = 0; i <
v.size(); i++)
1856 for (
int i = 0; i <
v.size(); i++)
1866 v[0] += 2.0 * right;
1880 if (a > 1.0 || a < -1.0) {
1881 std::cout <<
"Error: Cannot evaluate a Chebfun outside the domain" 1885 std::valarray<std::complex<T> > k(
N + 1);
1886 for (
int i = 0; i <
N + 1; i++) {
1887 k[i] = std::complex<T>(i, 0.0);
1889 k = cos(k * acos(std::complex<T>(a, 0.0)));
1890 k[0] = std::complex<T>(0.5, 0.0) * k[0];
1946 T ans = (temp.operator()(1) - temp.operator()(-1)) / 2.0;
1971 return diff(in, n - 1);
1974 return diff(in, n - 1);
1981 std::ostream &operator<<(std::ostream &stream, Chebfun<T> a) {
1982 std::valarray<T>
y(
N + 1);
1983 for (
int i = 0; i <
N + 1; i++) {
1984 y[i] = std::cos(
PI * (i + 0.5) / (
N + 1.0));
1986 stream <<
"A Chebfun in ";
1988 stream <<
"Chebyshev-space. Values of coefficients are: \n";
1989 for (
int i = 0; i < a.v.size(); i++) {
1990 stream << a.v[i] <<
"\n";
1993 stream <<
"physical-space. Values at set points are: \n";
1994 stream <<
"y\t\t f(y)\n";
1995 for (
int i = 0; i <
N + 1; i++) {
1996 stream <<
y[i] <<
"\t\t" << a.v[i] <<
"\n";
2036 for (
int i = 0; i <
r *
c; i++) {
2046 for (
int i = 0; i <
r *
c; i++) {
2056 Eigen::Dynamic> &in) {
2058 if (in.rows() !=
r * (
N + 1) || in.cols() !=
c) {
2060 <<
"Error in assigning a ChebfunMat through an Eigen Matrix. In line " 2061 << __LINE__ <<
". Exiting ..." <<
'\n';
2064 for (
int i = 0; i <
r; i++) {
2065 for (
int j = 0; j <
c; j++) {
2094 for (
int i = 0; i <
r; i++){
2095 for (
int j = 0; j <
c; j++){
2105 for (
int i = 0; i <
r; i++){
2106 for (
int j = 0; j <
c; j++){
2117 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >
2119 if (p <=1 && p >= -1 ){
2120 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic > temp(
r,
c);
2121 for (
int i = 0 ; i <
r; i ++){
2122 for (
int j = 0; j <
c; j++){
2128 std::cout <<
"Point of evaluation not in [-1,1]. In " << __LINE__
2138 for (
int i = 0; i <
N + 1; i++) {
2183 for (
int i = 0; i <
N + 1; i++) {
2207 for (
int i = 0; i <
r; i++) {
2208 for (
int j = 0; j <
c; j++) {
2217 for (
int i = 0; i <
r; i++) {
2218 for (
int j = 0; j <
c; j++) {
2219 out(j, i) =
conj(
operator()(i, j));
2226 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
2228 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out(
2232 for (
int i = 0; i <
r; i++) {
2233 for (
int j = 0; j <
c; j++) {
2236 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> temp;
2237 out.block(i * (
N + 1), j,
N + 1, 1) =
2243 out.block(i * (
N + 1), j,
N + 1, 1) =
operator()(i, j).ev();
2284 for (
int i = 0; i <
r *
c; i++) {
2292 for (
int i = 0; i <
r *
c; i++) {
2294 ChebfunVec[i].dct_flag = in.ChebfunVec[i].dct_flag;
2304 for (
int i = 0; i <
r *
c; i++) {
2331 for (
int i = 0; i <
r; i++){
2332 for (
int j = 0; j <
c; j++){
2342 for (
int i = 0; i <
r; i++){
2343 for (
int j = 0; j <
c; j++){
2360 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic >
2362 if (p <=1 && p >= -1 ){
2363 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic > temp(
r,
c);
2364 for (
int i = 0 ; i <
r; i ++){
2365 for (
int j = 0; j <
c; j++){
2371 std::cout <<
"Point of evaluation not in [-1,1]. In " << __LINE__
2380 operator<<(Eigen::Array<std::complex<T>, Eigen::Dynamic, 1> b) {
2381 for (
int i = 0; i <
N + 1; i++) {
2400 for (
int i = 0; i <
N + 1; i++)
2435 Eigen::Array<std::complex<T>, Eigen::Dynamic, 1> b) {
2436 for (
int i = 0; i <
N + 1; i++) {
2451 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
2453 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> out(
2457 for (
int i = 0; i <
r; i++) {
2458 for (
int j = 0; j <
c; j++) {
2461 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> temp;
2462 out.block(i * (
N + 1), j,
N + 1, 1) =
2468 out.block(i * (
N + 1), j,
N + 1, 1) =
operator()(i, j).evc();
2481 void operator=(
const Eigen::Matrix<std::complex<T>, Eigen::Dynamic,
2482 Eigen::Dynamic> &in) {
2484 if (in.rows() !=
r * (
N + 1) || in.cols() !=
c) {
2486 <<
"Error in assigning a ChebfunMat through an Eigen Matrix. In line " 2487 << __LINE__ <<
". Exiting ..." <<
'\n';
2490 for (
int i = 0; i <
r; i++) {
2491 for (
int j = 0; j <
c; j++) {
2499 for (
int i = 0; i <
r; i++) {
2500 for (
int j = 0; j <
c; j++) {
2508 for (
int i = 0; i <
r; i++) {
2509 for (
int j = 0; j <
c; j++) {
2518 for (
int i = 0; i <
r; i++) {
2519 for (
int j = 0; j <
c; j++) {
2520 out(j, i) =
conj(
operator()(i, j));
2535 for (
int i = 0; i < in.
r; i++) {
2536 for (
int j = 0; j < in.
c; j++) {
2537 out(i, j) =
conj(in(i, j));
2549 for (
int i = 0; i < in.
r; i++) {
2550 for (
int j = 0; j < in.
c; j++) {
2551 out(i, j) =
diff(in(i, j), n);
2568 Eigen::Matrix<T, Eigen::Dynamic, 1>
2668 for (
int i = 0; i <
n + 1; i ++){
2672 for (
int i = 0; i <
n + 1; i ++){
2695 void operator=(
const Eigen::Array<T, Eigen::Dynamic, 1> &in) {
2723 for (
int i = 0; i < out.
n + 1; i++) {
2743 coef.resize(n_ + 1);
2775 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1>
2819 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1>
2869 out.
v = std::complex<T>(0.0, 0.0);
2872 for (
int i = 0; i <
n + 1; i ++){
2876 for (
int i = 0; i <
n + 1; i ++){
2907 void operator=(
const Eigen::Array<std::complex<T>, Eigen::Dynamic, 1> &in) {
2952 for (
int i = 0; i < out.
n + 1; i++) {
2965 for (
int i = 0; i < out.
n + 1; i++) {
2978 for (
int i = 0; i < out.
n + 1; i++) {
3028 for (
int i = 0; i < out.
n + 1; i++) {
3047 coef.resize(n_ + 1);
3076 for (
int i = 0; i <
n + 1; i++)
3091 for (
int i = 0; i <
n + 1; i++)
3111 return diff(out, n - 1);
3117 for (
int i = 1; i < out.
n; i++) {
3120 return diff(out, n - 1);
3148 void compute(Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> in) {
3149 std::vector<T> temp;
3150 temp.reserve(in.rows());
3151 for (
int i = 0; i < in.rows(); i++) {
3152 temp.push_back(std::abs(in[i]));
3154 if (floor(
N / 2) <
N / 2) {
3168 if (tempfun.
L2norm() < 1e-11) {
3171 if (std::isnan(tempfun.
L2norm())) {
3175 minVal = (temp[
N] + temp[
N - 1]) / 2.0;
3183 void compute(Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> in,
int c) {
3185 std::vector<T> temp;
3186 temp.reserve(
N + 1);
3189 std::vector<std::vector<double> > L2norms;
3190 double ave_L2norm = 0.0;
3192 for (
int i = 0; i < c; i++) {
3193 Eigen::Matrix<T, Eigen::Dynamic, 1> tempMatr, tempMati;
3194 tempMatr = in.block(i * (
N + 1), 0,
N + 1, 1).real();
3195 tempMati = in.block(i * (
N + 1), 0,
N + 1, 1).imag();
3196 for (
int j = 0; j <
N + 1; j++) {
3197 tempfuns(i, 0).v[j] = std::complex<T>(tempMatr[j], tempMati[j]);
3200 L2norms[i].resize(2);
3201 L2norms[i][0] = (tempfuns(i, 0).L2norm());
3203 ave_L2norm += L2norms[i][0];
3208 std::sort(L2norms.begin(), L2norms.end());
3209 ave_L2norm = ave_L2norm / double(c);
3211 if (ave_L2norm > 1e-11) {
3212 for (
int i =
int(L2norms[c - 1][1]) * (
N + 1);
3213 i < int(L2norms[c - 1][1] + 1) * (
N + 1); i++) {
3214 temp.push_back(std::abs(in[i]));
3217 if (floor(
N / 2) <
N / 2) {
3233 if (std::isnan(ave_L2norm)) {
3238 minVal = (temp[
N] + temp[
N - 1]) / 2.0;
3263 #ifdef SIS_USE_LAPACK 3264 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> alpha, beta;
3282 int total_of_all_orders = 0;
3283 int total_boundary_conditions = 0;
3284 if (Lmat.
r != Lmat.
c) {
3285 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 3289 if (Mmat.
r != Mmat.
c) {
3290 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 3294 if (Mmat.
c != Lmat.
c) {
3295 std::cout <<
"Both matrices have to be of same size. Exiting ..." <<
'\n';
3298 int r = Lmat.
r, c = Lmat.
c;
3302 std::vector<int> highest_each_columnL, highest_each_columnM,
3303 highest_each_column;
3304 highest_each_columnL.resize(c);
3305 highest_each_columnM.resize(c);
3306 highest_each_column.resize(c);
3308 std::vector<int> temp_vec_int;
3309 temp_vec_int.resize(r);
3310 for (
int j = 0; j < c; j++) {
3311 for (
int i = 0; i < r; i++) {
3312 temp_vec_int[i] = Lmat(i, j).n;
3314 highest_each_columnL[j] =
3315 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
3317 for (
int j = 0; j < c; j++) {
3318 for (
int i = 0; i < r; i++) {
3319 temp_vec_int[i] = Mmat(i, j).n;
3321 highest_each_columnM[j] =
3322 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
3324 for (
int i = 0; i < c; i++) {
3325 total_of_all_orders += (highest_each_columnL[i] > highest_each_columnM[i])
3326 ? highest_each_columnL[i]
3327 : highest_each_columnM[i];
3328 highest_each_column[i] =
3329 (highest_each_columnL[i] > highest_each_columnM[i])
3330 ? highest_each_columnL[i]
3331 : highest_each_columnM[i];
3333 total_boundary_conditions = Lbc.m;
3338 if (total_of_all_orders != total_boundary_conditions) {
3339 std::cout <<
"The problem is ill-posed, the total of the highest " 3341 "dependent variables has to be equal to the total number of " 3342 "boundary conditions specified." 3344 "Total no. of boundary conditions: " 3345 << total_boundary_conditions
3347 "Total of all orders: " 3348 << total_of_all_orders <<
"\n Exiting ...\n";
3352 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterL(
3353 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
3355 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterM(
3356 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
3358 masterL.setConstant(0.0);
3359 masterM.setConstant(0.0);
3361 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> subs_mat;
3362 subs_mat.resize(total_boundary_conditions, (
N + 1) * c);
3363 subs_mat.setConstant(0.0);
3364 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> mat_temp(
3365 total_boundary_conditions, total_boundary_conditions),
3366 constraints(total_boundary_conditions,
3367 c * (
N + 1) + total_of_all_orders);
3369 mat_temp.setConstant(0.0);
3370 int row_counter = 0, col_counter = 0;
3372 for (
int i = 0; i < Lbc.m; i++) {
3373 for (
int j = 0; j < Lbc.n; j++) {
3374 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> temp =
3375 Lbc(i, j, highest_each_column[j]);
3376 constraints.block(i, col_counter, 1, temp.cols()) = temp;
3377 col_counter += temp.cols();
3382 Eigen::ColPivHouseholderQR<
3383 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
3385 qr.compute(constraints);
3386 if (qr.rank() != constraints.rows()) {
3387 std::cout <<
"The boundary conditions supplied are not " 3388 <<
" linearly independent." <<
'\n';
3389 std::cout <<
"qr.rank = " << qr.rank()
3390 <<
", no. bcs: " << total_boundary_conditions <<
". Exiting ..." 3396 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> P;
3397 P = qr.colsPermutation();
3399 constraints = constraints * P;
3400 mat_temp = constraints.block(0, 0, constraints.rows(), constraints.rows());
3402 Eigen::ColPivHouseholderQR<
3403 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
3404 consSolver(mat_temp);
3405 subs_mat = -consSolver.inverse() *
3406 constraints.block(0, constraints.rows(), constraints.rows(),
3407 constraints.cols() - constraints.rows());
3411 int master_row_counter = 0;
3412 int master_col_counter = 0;
3413 for (
int j = 0; j < c; j++) {
3414 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
3415 ? highest_each_columnL[j]
3416 : highest_each_columnM[j];
3418 for (
int i = 0; i < r; i++) {
3419 int diffn = n - Lmat(i, j).n;
3420 if (Lmat(i, j).NCC == 0) {
3421 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
3422 masterL.block(master_row_counter, master_col_counter,
N + 1,
3424 Lmat(i, j).coef[k] *
3425 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
3428 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
3429 masterL.block(master_row_counter, master_col_counter,
N + 1,
3431 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
3432 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
3435 diffn = n - Mmat(i, j).n;
3436 if (Mmat(i, j).NCC == 0) {
3437 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
3438 masterM.block(master_row_counter, master_col_counter,
N + 1,
3440 Mmat(i, j).coef[k] *
3441 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
3444 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
3445 masterM.block(master_row_counter, master_col_counter,
N + 1,
3447 Mmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
3448 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
3451 master_row_counter +=
N + 1;
3453 master_row_counter = 0;
3454 master_col_counter +=
N + 1 + n;
3457 masterL = masterL * P;
3458 masterM = masterM * P;
3460 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterL2, masterM2;
3463 masterL.block(0, constraints.rows(), c * (
N + 1), c * (
N + 1)) +
3464 (masterL.block(0, 0, c * (
N + 1), constraints.rows()) * subs_mat);
3466 masterM.block(0, constraints.rows(), c * (
N + 1), c * (
N + 1)) +
3467 (masterM.block(0, 0, c * (
N + 1), constraints.rows()) * subs_mat);
3468 #ifndef SIS_USE_LAPACK 3469 Eigen::ColPivHouseholderQR<
3470 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
3472 Eigen::EigenSolver<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > eigs;
3473 bool Is_M_Invertible;
3474 if (solver.isInvertible()) {
3477 Is_M_Invertible =
true;
3478 eigs.compute(solver.inverse() * masterL2);
3483 Is_M_Invertible =
false;
3484 solver.compute(masterL2);
3485 eigs.compute(solver.inverse() * masterM2);
3490 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
3491 evecMat_master(c * (
N + 1), c * (
N + 1));
3492 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
3493 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
3494 subs_mat * eigs.eigenvectors();
3495 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
3496 c * (
N + 1) + total_boundary_conditions, c * (
N + 1));
3497 evecMat << fir_n_mat, eigs.eigenvectors();
3500 evecMat = P * evecMat;
3503 for (
int i = 0; i < c; i++) {
3504 int n = (highest_each_columnL[i] > highest_each_columnM[i])
3505 ? highest_each_columnL[i]
3506 : highest_each_columnM[i];
3508 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1)) =
3509 Mat.
mats2[n] * evecMat.block(row_counter, 0,
N + 1 + n, c * (
N + 1));
3510 row_counter +=
N + 1 + n;
3512 std::vector<std::vector<T> > eigenval_trunc_sorter;
3514 eigenval_trunc_sorter.resize(c * (
N + 1));
3515 for (
int i = 0; i < c * (
N + 1); i++) {
3516 eigenval_trunc_sorter[i].resize(2);
3519 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1));
3520 MPcount.setConstant(0);
3521 std::vector<EigenSorter<T> > sorter;
3522 sorter.resize(c * (
N + 1));
3523 for (
int i = 0; i < c * (
N + 1); i++) {
3524 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
3525 if (!Is_M_Invertible) {
3528 if (abs(eigs.eigenvalues()[i]) < 1e-11) {
3529 sorter[i].numMp =
N + 1;
3530 sorter[i].Mp =
false;
3531 sorter[i].minVal = 1e11;
3535 if (sorter[i].Mp ==
true) {
3539 int MPcount_sum = MPcount.sum();
3541 for (
int i = 0; i < num_vals; i++) {
3545 if (MPcount_sum >= num_vals) {
3546 for (
int i = 0; i < c * (
N + 1); i++) {
3547 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
3548 eigenval_trunc_sorter[i][1] = i;
3552 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
3553 for (
int i = 0; i < num_vals; i++) {
3554 if (Is_M_Invertible) {
3555 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
3558 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
3561 for (
int j = 0; j < c; j++) {
3562 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
3563 ? highest_each_columnL[j]
3564 : highest_each_columnM[j];
3566 temp_vec.resize(
N + 1 + n, 1);
3567 for (
int i = 0; i < num_vals; i++) {
3569 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
3573 std::cout <<
"Last " << num_vals - MPcount_sum
3574 <<
" eigenvectors are not resolved to machine precision." 3576 for (
int i = 0; i < c * (
N + 1); i++) {
3577 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
3578 eigenval_trunc_sorter[i][1] = i;
3580 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
3581 for (
int i = 0; i < MPcount_sum; i++) {
3582 if (Is_M_Invertible) {
3583 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
3586 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
3589 for (
int j = 0; j < c; j++) {
3590 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
3591 ? highest_each_columnL[j]
3592 : highest_each_columnM[j];
3593 temp_vec.resize(
N + 1 + n, 1);
3594 for (
int i = 0; i < MPcount_sum; i++) {
3596 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
3600 std::vector<std::vector<T> > eigenval_trunc_sorter2;
3601 eigenval_trunc_sorter2.resize(c * (
N + 1) - MPcount_sum);
3602 for (
int i = MPcount_sum; i < c * (
N + 1); i++) {
3603 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
3604 eigenval_trunc_sorter2[i - MPcount_sum][0] =
3605 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
3606 eigenval_trunc_sorter2[i - MPcount_sum][1] =
3607 eigenval_trunc_sorter[i][1];
3609 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
3610 for (
int i = MPcount_sum; i < num_vals; i++) {
3611 if (Is_M_Invertible) {
3613 eigenval_trunc_sorter2[i - MPcount_sum][1])];
3616 1.0 / eigs.eigenvalues()[int(
3617 eigenval_trunc_sorter2[i - MPcount_sum][1])];
3620 for (
int j = 0; j < c; j++) {
3621 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
3622 ? highest_each_columnL[j]
3623 : highest_each_columnM[j];
3625 temp_vec.resize(
N + 1 + n, 1);
3626 for (
int i = MPcount_sum; i < num_vals; i++) {
3628 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
3634 std::cout <<
"Using lapack routine..." <<
'\n';
3637 std::complex<double> wkopt;
3638 std::complex<double> *work;
3639 alpha.resize(masterL2.rows(), 1);
3640 beta.resize(masterL2.rows(), 1);
3642 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL2_,
3643 masterM2_, vl(masterL2.rows(), masterL2.rows()),
3644 vr(masterL2.rows(), masterL2.rows()),
3645 eigenvalues_temp(masterL2.rows(), 1), alpha_temp(masterL2.rows(), 1),
3646 beta_temp(masterL2.rows(), 1);
3648 masterL2_ = masterL2;
3649 masterM2_ = masterM2;
3651 int ldL = masterL2.outerStride();
3652 int ldM = masterM2.outerStride();
3653 int ldvl = vl.outerStride();
3654 int ldvr = vr.outerStride();
3655 int sizeL = masterL2.rows();
3657 double rwork[8 * sizeL];
3660 zggev_(&jobvl, &jobvr, &sizeL, masterL2_.data(), &ldL, masterM2_.data(),
3661 &ldM, alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl,
3662 vr.data(), &ldvr, &wkopt, &lwork, rwork, &info);
3665 lwork = (int)
real(wkopt);
3666 work = (std::complex<double> *)malloc(lwork *
sizeof(std::complex<double>));
3669 zggev_(&jobvl, &jobvr, &sizeL, masterL2_.data(), &ldL, masterM2_.data(),
3670 &ldM, alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl,
3671 vr.data(), &ldvr, work, &lwork, rwork, &info);
3676 eigenvalues_temp = alpha_temp.array() / beta_temp.array();
3678 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
3679 evecMat_master(c * (
N + 1), c * (
N + 1));
3680 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
3681 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
3683 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
3684 c * (
N + 1) + total_boundary_conditions, c * (
N + 1));
3685 evecMat << fir_n_mat, vr;
3687 evecMat = P * evecMat;
3690 for (
int i = 0; i < c; i++) {
3691 int n = (highest_each_columnL[i] > highest_each_columnM[i])
3692 ? highest_each_columnL[i]
3693 : highest_each_columnM[i];
3695 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1)) =
3696 Mat.
mats2[n] * evecMat.block(row_counter, 0,
N + 1 + n, c * (
N + 1));
3697 row_counter +=
N + 1 + n;
3699 std::vector<std::vector<T> > eigenval_trunc_sorter;
3701 eigenval_trunc_sorter.resize(c * (
N + 1));
3702 for (
int i = 0; i < c * (
N + 1); i++) {
3703 eigenval_trunc_sorter[i].resize(2);
3706 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1));
3707 MPcount.setConstant(0);
3708 std::vector<EigenSorter<T> > sorter;
3709 sorter.resize(c * (
N + 1));
3710 for (
int i = 0; i < c * (
N + 1); i++) {
3711 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
3713 if (sorter[i].Mp ==
true) {
3717 if (num_vals > masterL2.rows()) {
3718 std::cout <<
"Only " << masterL.rows()
3719 <<
" eigenvalues can be calculated." 3720 <<
"Storing only that many." <<
'\n';
3721 num_vals = masterL2.rows();
3724 int MPcount_sum = MPcount.sum();
3726 for (
int i = 0; i < num_vals; i++) {
3730 beta.resize(num_vals);
3731 alpha.resize(num_vals);
3732 if (MPcount_sum >= num_vals) {
3733 for (
int i = 0; i < c * (
N + 1); i++) {
3734 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
3735 eigenval_trunc_sorter[i][1] = i;
3739 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
3740 for (
int i = 0; i < num_vals; i++) {
3741 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
3742 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
3743 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
3745 for (
int j = 0; j < c; j++) {
3746 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
3747 ? highest_each_columnL[j]
3748 : highest_each_columnM[j];
3750 temp_vec.resize(
N + 1 + n, 1);
3751 for (
int i = 0; i < num_vals; i++) {
3753 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
3758 std::cout <<
"Last " << num_vals - MPcount_sum
3759 <<
" eigenvectors are not resolved to machine precision." 3761 for (
int i = 0; i < c * (
N + 1); i++) {
3762 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
3763 eigenval_trunc_sorter[i][1] = i;
3765 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
3766 for (
int i = 0; i < MPcount_sum; i++) {
3767 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
3768 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
3769 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
3771 for (
int j = 0; j < c; j++) {
3772 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
3773 ? highest_each_columnL[j]
3774 : highest_each_columnM[j];
3775 temp_vec.resize(
N + 1 + n, 1);
3776 for (
int i = 0; i < MPcount_sum; i++) {
3778 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
3783 std::vector<std::vector<T> > eigenval_trunc_sorter2;
3784 eigenval_trunc_sorter2.resize(c * (
N + 1) - MPcount_sum);
3785 for (
int i = MPcount_sum; i < c * (
N + 1); i++) {
3786 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
3787 eigenval_trunc_sorter2[i - MPcount_sum][0] =
3788 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
3789 eigenval_trunc_sorter2[i - MPcount_sum][1] =
3790 eigenval_trunc_sorter[i][1];
3792 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
3793 for (
int i = MPcount_sum; i < num_vals; i++) {
3795 int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
3797 alpha_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
3798 beta[i] = beta_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
3800 for (
int j = 0; j < c; j++) {
3801 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
3802 ? highest_each_columnL[j]
3803 : highest_each_columnM[j];
3805 temp_vec.resize(
N + 1 + n, 1);
3806 for (
int i = MPcount_sum; i < num_vals; i++) {
3808 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
3836 int total_of_all_orders = 0;
3837 int total_boundary_conditions = 0;
3838 if (Lmat.
r != Lmat.
c) {
3839 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 3843 if (Mmat.
r != Mmat.
c) {
3844 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 3848 if (Mmat.
c != Lmat.
c) {
3849 std::cout <<
"Both matrices have to be of same size. Exiting ..." <<
'\n';
3852 int r = Lmat.
r, c = Lmat.
c;
3856 std::vector<int> highest_each_columnL, highest_each_columnM,
3857 highest_each_column, num_bc_each_var;
3858 highest_each_columnL.resize(c);
3859 highest_each_columnM.resize(c);
3860 highest_each_column.resize(c);
3861 num_bc_each_var.resize(c);
3862 std::vector<int> temp_vec_int;
3863 temp_vec_int.resize(r);
3864 for (
int j = 0; j < c; j++) {
3865 for (
int i = 0; i < r; i++) {
3866 temp_vec_int[i] = Lmat(i, j).n;
3868 highest_each_columnL[j] =
3869 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
3871 for (
int j = 0; j < c; j++) {
3872 for (
int i = 0; i < r; i++) {
3873 temp_vec_int[i] = Mmat(i, j).n;
3875 highest_each_columnM[j] =
3876 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
3878 for (
int i = 0; i < c; i++) {
3879 total_of_all_orders += (highest_each_columnL[i] > highest_each_columnM[i])
3880 ? highest_each_columnL[i]
3881 : highest_each_columnM[i];
3882 highest_each_column[i] =
3883 (highest_each_columnL[i] > highest_each_columnM[i])
3884 ? highest_each_columnL[i]
3885 : highest_each_columnM[i];
3887 for (
int i = 0; i < c; i++) {
3888 total_boundary_conditions += Lmat.BcVec[i].nbc();
3889 num_bc_each_var[i] = Lmat.BcVec[i].nbc();
3892 if (Lbc.m != Mbc.m) {
3893 std::cout <<
"The Lbc and Mbc have to be of same dimensions" <<
'\n' 3894 <<
"Exiting in " << __LINE__ <<
"...\n";
3901 if (total_of_all_orders != (total_boundary_conditions + Lbc.m)) {
3902 std::cout <<
"The problem is ill-posed, the total of the highest " 3904 "dependent variables has to be equal to the total number of " 3905 "boundary conditions plus number of constraints specified." 3907 "Total no. of boundary conditions: " 3908 << total_boundary_conditions
3910 "Total of all orders: " 3911 << total_of_all_orders <<
"\n Number of Constraints : " << Lbc.m
3912 <<
"\n Exiting in " << __LINE__ <<
" ...\n ";
3916 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterL(
3917 r * (
N + 1) + Lbc.m, c * (
N + 1) + Lbc.m);
3919 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterM(
3920 r * (
N + 1) + Lbc.m, c * (
N + 1) + Lbc.m);
3922 masterL.setConstant(0.0);
3923 masterM.setConstant(0.0);
3925 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> subs_mat;
3927 subs_mat.resize(total_boundary_conditions, (
N + 1) * c + Lbc.m);
3929 subs_mat.setConstant(0.0);
3930 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> mat_temp(
3931 total_boundary_conditions, total_boundary_conditions);
3932 mat_temp.setConstant(0.0);
3933 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> subs_mat_col_mul(
3934 c * (
N + 1), total_boundary_conditions);
3935 subs_mat_col_mul.setConstant(0.0);
3936 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> subs_mat_col_mul2(
3937 c * (
N + 1), total_boundary_conditions);
3938 subs_mat_col_mul2.setConstant(0.0);
3939 int subs_mat_row_counter = 0;
3940 int subs_mat_col_counter = 0;
3941 int row_counter = 0, col_counter = 0;
3942 for (
int j = 0; j < c; j++) {
3944 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
3945 ? highest_each_columnL[j]
3946 : highest_each_columnM[j];
3952 std::vector<Eigen::Matrix<T, 1, Eigen::Dynamic> > lbc_vecs(
3953 Lmat.BcVec[j].nl, Eigen::Matrix<T, 1, Eigen::Dynamic>(
N + 1 + 2 * n));
3954 std::vector<Eigen::Matrix<T, 1, Eigen::Dynamic> > rbc_vecs(
3955 Lmat.BcVec[j].nr, Eigen::Matrix<T, 1, Eigen::Dynamic>(
N + 1 + 2 * n));
3956 std::vector<Eigen::Matrix<T, 1, Eigen::Dynamic> > lbc_con_vecs(
3957 Lmat.BcVec[j].nl, Eigen::Matrix<T, 1, Eigen::Dynamic>(n));
3958 std::vector<Eigen::Matrix<T, 1, Eigen::Dynamic> > rbc_con_vecs(
3959 Lmat.BcVec[j].nr, Eigen::Matrix<T, 1, Eigen::Dynamic>(n));
3960 Eigen::Matrix<T, 1, Eigen::Dynamic> ones(
N + 1 + 2 * n);
3961 Eigen::Matrix<T, 1, Eigen::Dynamic> onem(
N + 1 + 2 * n);
3962 Eigen::Matrix<T, 1, Eigen::Dynamic> onesn(n);
3963 Eigen::Matrix<T, 1, Eigen::Dynamic> onemn(n);
3965 ones.setConstant(1.0);
3966 onesn.setConstant(1.0);
3967 onem.setConstant(1.0);
3968 onemn.setConstant(1.0);
3970 for (
int k = 1; k <
N + 1 + 2 * n; k = k + 2) {
3973 for (
int k = 1; k < n; k = k + 2) {
3983 for (
int k = 0; k < Lmat.BcVec[j].nl; k++) {
3984 lbc_vecs[k].resize(
N + 1 + 2 * n);
3985 lbc_vecs[k].setConstant(0.0);
3986 for (
int l = 0; l < Lmat.BcVec[j].ord + 1; l++) {
3987 lbc_vecs[k] += Lmat.BcVec[j].coefl(k, l) *
3988 (onem * Mat.
mats[l + (n - Lmat.BcVec[j].ord)]);
3992 for (
int k = 0; k < Lmat.BcVec[j].nr; k++) {
3993 rbc_vecs[k].
resize(
N + 1 + 2 * n);
3994 rbc_vecs[k].setConstant(0.0);
3995 for (
int l = 0; l < Lmat.BcVec[j].ord + 1; l++) {
3996 rbc_vecs[k] += Lmat.BcVec[j].coefr(k, l) *
3997 (ones * Mat.
mats[l + (n - Lmat.BcVec[j].ord)]);
4000 for (
int k = 0; k < Lmat.BcVec[j].nl; k++) {
4002 for (
int l = 0; l < Lmat.BcVec[j].ord + 1; l++) {
4003 if (l + n - Lmat.BcVec[j].ord - 1 > -1) {
4005 Lmat.BcVec[j].coefl(k, l) *
4006 (onemn * Mat.
con_mats[l + n - Lmat.BcVec[j].ord - 1]);
4010 for (
int k = 0; k < Lmat.BcVec[j].nr; k++) {
4012 for (
int l = 0; l < Lmat.BcVec[j].ord + 1; l++) {
4013 if (l + n - Lmat.BcVec[j].ord - 1 > -1) {
4015 Lmat.BcVec[j].coefr(k, l) *
4016 (onesn * Mat.
con_mats[l + n - Lmat.BcVec[j].ord - 1]);
4021 for (
int k = 0; k < Lmat.BcVec[j].nl; k++) {
4022 mat_temp.block(row_counter, col_counter, 1,
4023 Lmat.BcVec[j].nl + Lmat.BcVec[j].nr) =
4024 lbc_vecs[k].head(Lmat.BcVec[j].nl + Lmat.BcVec[j].nr);
4027 for (
int k = Lmat.BcVec[j].nl; k < Lmat.BcVec[j].nl + Lmat.BcVec[j].nr;
4029 mat_temp.block(row_counter, col_counter, 1,
4030 Lmat.BcVec[j].nl + Lmat.BcVec[j].nr) =
4031 rbc_vecs[k - Lmat.BcVec[j].nl].head(Lmat.BcVec[j].nl +
4035 col_counter = col_counter + Lmat.BcVec[j].nbc();
4036 for (
int k = 0; k < Lmat.BcVec[j].nl; k++) {
4037 subs_mat.block(subs_mat_row_counter, subs_mat_col_counter, 1,
4038 (
N + 1 - Lmat.BcVec[j].nbc())) =
4039 lbc_vecs[k].block(0, Lmat.BcVec[j].nbc(), 1,
4040 N + 1 - Lmat.BcVec[j].nbc());
4041 subs_mat.block(subs_mat_row_counter,
4042 subs_mat_col_counter + (
N + 1 - Lmat.BcVec[j].nbc()), 1,
4043 n) = lbc_con_vecs[k];
4044 subs_mat_row_counter++;
4047 for (
int k = Lmat.BcVec[j].nl; k < Lmat.BcVec[j].nbc(); k++) {
4048 subs_mat.block(subs_mat_row_counter, subs_mat_col_counter, 1,
4049 (
N + 1 - Lmat.BcVec[j].nbc())) =
4050 rbc_vecs[k - Lmat.BcVec[j].nl].block(0, Lmat.BcVec[j].nbc(), 1,
4051 N + 1 - Lmat.BcVec[j].nbc());
4052 subs_mat.block(subs_mat_row_counter,
4053 subs_mat_col_counter + (
N + 1 - Lmat.BcVec[j].nbc()), 1,
4054 n) = rbc_con_vecs[k - Lmat.BcVec[j].nl];
4055 subs_mat_row_counter++;
4057 subs_mat_col_counter += (
N + 1 + n - Lmat.BcVec[j].nbc());
4059 if (mat_temp.rows() != 0 || mat_temp.cols() != 0) {
4060 Eigen::ColPivHouseholderQR<
4061 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
4062 consSolver(mat_temp);
4063 if (!consSolver.isInvertible()) {
4064 std::cout <<
"the matrix is not invertible." <<
'\n';
4067 subs_mat = -consSolver.inverse() * subs_mat.eval();
4071 int master_row_counter = 0;
4072 int master_col_counter = 0;
4073 subs_mat_row_counter = 0;
4074 subs_mat_col_counter = 0;
4075 for (
int j = 0; j < c; j++) {
4076 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
4077 ? highest_each_columnL[j]
4078 : highest_each_columnM[j];
4080 for (
int i = 0; i < r; i++) {
4082 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> solver_matL(
4083 N + 1,
N + 1 + n - Lmat.BcVec[j].nbc());
4084 solver_matL.setConstant(0.0);
4085 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> solver_matM(
4086 N + 1,
N + 1 + n - Lmat.BcVec[j].nbc());
4087 solver_matM.setConstant(0.0);
4088 int diffn = n - Lmat(i, j).n;
4089 if (Lmat(i, j).NCC == 0) {
4090 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
4091 solver_matL.block(0, 0,
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc()) +=
4092 Lmat(i, j).coef[k] *
4093 (Mat.
mats2[k + diffn].block(0, Lmat.BcVec[j].nbc(),
N + 1,
4094 N + 1 + n - Lmat.BcVec[j].nbc()));
4095 subs_mat_col_mul.block(i * (
N + 1), subs_mat_col_counter,
N + 1,
4096 Lmat.BcVec[j].nbc()) +=
4097 Lmat(i, j).coef[k] *
4098 (Mat.
mats2[k + diffn].block(0, 0,
N + 1, Lmat.BcVec[j].nbc()));
4101 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
4102 solver_matL.block(0, 0,
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc()) +=
4103 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
4104 (Mat.
mats2[k + diffn].block(0, Lmat.BcVec[j].nbc(),
N + 1,
4105 N + 1 + n - Lmat.BcVec[j].nbc()));
4106 subs_mat_col_mul.block(i * (
N + 1), subs_mat_col_counter,
N + 1,
4107 Lmat.BcVec[j].nbc()) +=
4108 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
4109 (Mat.
mats2[k + diffn].block(0, 0,
N + 1, Lmat.BcVec[j].nbc()));
4112 diffn = n - Mmat(i, j).n;
4113 if (Mmat(i, j).NCC == 0) {
4114 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
4115 solver_matM.block(0, 0,
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc()) +=
4116 Mmat(i, j).coef[k] *
4117 (Mat.
mats2[k + diffn].block(0, Lmat.BcVec[j].nbc(),
N + 1,
4118 N + 1 + n - Lmat.BcVec[j].nbc()));
4119 subs_mat_col_mul2.block(i * (
N + 1), subs_mat_col_counter,
N + 1,
4120 Lmat.BcVec[j].nbc()) +=
4121 Mmat(i, j).coef[k] *
4122 (Mat.
mats2[k + diffn].block(0, 0,
N + 1, Lmat.BcVec[j].nbc()));
4125 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
4126 solver_matM.block(0, 0,
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc()) +=
4127 Mmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
4128 (Mat.
mats2[k + diffn].block(0, Lmat.BcVec[j].nbc(),
N + 1,
4129 N + 1 + n - Lmat.BcVec[j].nbc()));
4130 subs_mat_col_mul2.block(i * (
N + 1), subs_mat_col_counter,
N + 1,
4131 Lmat.BcVec[j].nbc()) +=
4132 Mmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
4133 (Mat.
mats2[k + diffn].block(0, 0,
N + 1, Lmat.BcVec[j].nbc()));
4136 subs_mat_row_counter +=
N + 1 + n - Lmat.BcVec[j].nbc();
4137 masterL.block(i * (
N + 1), master_col_counter,
N + 1,
4138 N + 1 + n - Lmat.BcVec[j].nbc()) = solver_matL;
4139 masterM.block(i * (
N + 1), master_col_counter,
N + 1,
4140 N + 1 + n - Lmat.BcVec[j].nbc()) = solver_matM;
4142 subs_mat_col_counter += Lmat.BcVec[j].nbc();
4143 subs_mat_row_counter = 0;
4144 master_row_counter = 0;
4145 master_col_counter +=
N + 1 + n - Lmat.BcVec[j].nbc();
4147 if (mat_temp.rows() != 0 || mat_temp.cols() != 0) {
4148 masterL.block(0, 0, c * (
N + 1), c * (
N + 1) + Lbc.m) +=
4149 masterL.block(0, 0, c * (
N + 1), c * (
N + 1) + Lbc.m).eval() +
4150 (subs_mat_col_mul * subs_mat);
4151 masterM.block(0, 0, c * (
N + 1), c * (
N + 1) + Lbc.m) +=
4152 masterM.block(0, 0, c * (
N + 1), c * (
N + 1) + Lbc.m).eval() +
4153 (subs_mat_col_mul2 * subs_mat);
4157 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> constraints_bigL(
4158 Lbc.m, c * (
N + 1) + Lbc.m),
4159 constraints_smallL(Lbc.m, total_boundary_conditions),
4160 constraints_bigM(Lbc.m, c * (
N + 1) + Lbc.m),
4161 constraints_smallM(Lbc.m, total_boundary_conditions);
4162 constraints_bigL.setConstant(0.0);
4163 constraints_smallL.setConstant(0.0);
4164 constraints_bigM.setConstant(0.0);
4165 constraints_smallM.setConstant(0.0);
4168 int col_counter2 = 0;
4169 int row_counter2 = 0;
4170 for (
int i = 0; i < Lbc.m; i++) {
4171 for (
int j = 0; j < Lbc.n; j++) {
4172 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> temp =
4173 Lbc(i, j, highest_each_column[j]);
4175 constraints_bigL.block(i, col_counter, 1,
4176 N + 1 + highest_each_column[j] -
4177 num_bc_each_var[j]) =
4178 temp.block(0, num_bc_each_var[j], 1,
4179 N + 1 + highest_each_column[j] - num_bc_each_var[j]);
4181 constraints_smallL.block(i, col_counter2, 1, num_bc_each_var[j]) =
4182 temp.block(0, 0, 1, num_bc_each_var[j]);
4186 temp = Mbc(i, j, highest_each_column[j]);
4188 constraints_bigM.block(i, col_counter, 1,
4189 N + 1 + highest_each_column[j] -
4190 num_bc_each_var[j]) =
4191 temp.block(0, num_bc_each_var[j], 1,
4192 N + 1 + highest_each_column[j] - num_bc_each_var[j]);
4194 constraints_smallM.block(i, col_counter2, 1, num_bc_each_var[j]) =
4195 temp.block(0, 0, 1, num_bc_each_var[j]);
4196 col_counter +=
N + 1 + highest_each_column[j] - num_bc_each_var[j];
4197 col_counter2 += num_bc_each_var[j];
4202 if (mat_temp.rows() != 0 || mat_temp.cols() != 0) {
4203 masterL.block(c * (
N + 1), 0, Lbc.m, c * (
N + 1) + Lbc.m) =
4204 constraints_bigL + constraints_smallL * subs_mat;
4205 masterM.block(c * (
N + 1), 0, Lbc.m, c * (
N + 1) + Lbc.m) =
4206 constraints_bigM + constraints_smallM * subs_mat;
4208 masterL.block(c * (
N + 1), 0, Lbc.m, c * (
N + 1) + Lbc.m) =
4210 masterM.block(c * (
N + 1), 0, Lbc.m, c * (
N + 1) + Lbc.m) =
4214 #ifndef SIS_USE_LAPACK 4215 Eigen::ColPivHouseholderQR<
4216 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
4218 Eigen::ComplexEigenSolver<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
4220 bool Is_M_Invertible;
4221 if (solver.isInvertible()) {
4222 Is_M_Invertible =
true;
4223 eigs.compute(solver.inverse() * masterL);
4226 Is_M_Invertible =
false;
4227 solver.compute(masterL);
4228 eigs.compute(solver.inverse() * masterM);
4233 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
4234 evecMat_master(c * (
N + 1) + Lbc.m, c * (
N + 1) + Lbc.m);
4235 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
4236 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat,
4238 if (subs_mat.size() > 0) {
4239 fir_n_mat = subs_mat * eigs.eigenvectors();
4241 full_mat.resize(c * (
N + 1) + Lbc.m + fir_n_mat.rows(),
4242 c * (
N + 1) + Lbc.m);
4248 for (
int i = 0; i < c; i++) {
4249 int n = (highest_each_columnL[i] > highest_each_columnM[i])
4250 ? highest_each_columnL[i]
4251 : highest_each_columnM[i];
4252 if (subs_mat.size() > 0) {
4253 full_mat.block(row_counter, 0, num_bc_each_var[i],
4254 c * (
N + 1) + Lbc.m) =
4255 fir_n_mat.block(col_counter, 0, num_bc_each_var[i],
4256 c * (
N + 1) + Lbc.m);
4258 row_counter += num_bc_each_var[i];
4259 col_counter += num_bc_each_var[i];
4261 full_mat.block(row_counter, 0,
N + 1 + n - num_bc_each_var[i],
4262 c * (
N + 1) + Lbc.m) =
4263 eigs.eigenvectors().block(row_counter2, 0,
4264 N + 1 + n - num_bc_each_var[i],
4265 c * (
N + 1) + Lbc.m);
4266 row_counter +=
N + 1 + n - num_bc_each_var[i];
4267 row_counter2 +=
N + 1 + n - num_bc_each_var[i];
4271 for (
int i = 0; i < c; i++) {
4272 int n = (highest_each_columnL[i] > highest_each_columnM[i])
4273 ? highest_each_columnL[i]
4274 : highest_each_columnM[i];
4276 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1) + Lbc.m) =
4278 full_mat.block(row_counter, 0,
N + 1 + n, c * (
N + 1) + Lbc.m);
4279 row_counter +=
N + 1 + n;
4282 std::vector<std::vector<T> > eigenval_trunc_sorter;
4284 eigenval_trunc_sorter.resize(c * (
N + 1) + Lbc.m);
4285 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
4286 eigenval_trunc_sorter[i].resize(2);
4289 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1) + Lbc.m);
4290 MPcount.setConstant(0);
4291 std::vector<EigenSorter<T> > sorter;
4292 sorter.resize(c * (
N + 1) + Lbc.m);
4293 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
4294 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
4295 if (!Is_M_Invertible) {
4298 if (abs(eigs.eigenvalues()[i]) < 1e-11) {
4299 sorter[i].numMp =
N + 1;
4300 sorter[i].Mp =
false;
4301 sorter[i].minVal = 1e11;
4305 if (sorter[i].Mp ==
true) {
4309 int MPcount_sum = MPcount.sum();
4311 for (
int i = 0; i < num_vals; i++) {
4315 if (MPcount_sum >= num_vals) {
4316 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
4317 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
4318 eigenval_trunc_sorter[i][1] = i;
4322 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
4323 for (
int i = 0; i < num_vals; i++) {
4324 if (Is_M_Invertible) {
4325 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
4328 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
4331 for (
int j = 0; j < c; j++) {
4332 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
4333 ? highest_each_columnL[j]
4334 : highest_each_columnM[j];
4336 temp_vec.resize(
N + 1 + n, 1);
4337 for (
int i = 0; i < num_vals; i++) {
4339 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
4344 std::cout <<
"Last " << num_vals - MPcount_sum
4345 <<
" eigenvectors are not resolved to machine precision." 4347 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
4348 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
4349 eigenval_trunc_sorter[i][1] = i;
4351 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
4352 for (
int i = 0; i < MPcount_sum; i++) {
4353 if (Is_M_Invertible) {
4354 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
4357 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
4360 for (
int j = 0; j < c; j++) {
4361 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
4362 ? highest_each_columnL[j]
4363 : highest_each_columnM[j];
4364 temp_vec.resize(
N + 1 + n, 1);
4365 for (
int i = 0; i < MPcount_sum; i++) {
4367 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
4372 std::vector<std::vector<T> > eigenval_trunc_sorter2;
4373 eigenval_trunc_sorter2.resize(c * (
N + 1) + Lbc.m - MPcount_sum);
4374 for (
int i = MPcount_sum; i < c * (
N + 1) + Lbc.m; i++) {
4375 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
4376 eigenval_trunc_sorter2[i - MPcount_sum][0] =
4377 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
4378 eigenval_trunc_sorter2[i - MPcount_sum][1] =
4379 eigenval_trunc_sorter[i][1];
4381 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
4382 for (
int i = MPcount_sum; i < num_vals; i++) {
4383 if (Is_M_Invertible) {
4385 eigenval_trunc_sorter2[i - MPcount_sum][1])];
4388 1.0 / eigs.eigenvalues()[int(
4389 eigenval_trunc_sorter2[i - MPcount_sum][1])];
4392 for (
int j = 0; j < c; j++) {
4393 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
4394 ? highest_each_columnL[j]
4395 : highest_each_columnM[j];
4397 temp_vec.resize(
N + 1 + n, 1);
4398 for (
int i = MPcount_sum; i < num_vals; i++) {
4400 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
4410 std::complex<double> wkopt;
4411 std::complex<double> *work;
4412 alpha.resize(masterL.rows(), 1);
4413 beta.resize(masterL.rows(), 1);
4415 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL_,
4416 masterM_, vl(masterL.rows(), masterL.rows()),
4417 vr(masterL.rows(), masterL.rows()), eigenvalues_temp(masterL.rows(), 1),
4418 alpha_temp(masterL.rows(), 1), beta_temp(masterL.rows(), 1);
4422 int ldL = masterL.outerStride();
4423 int ldM = masterM.outerStride();
4424 int ldvl = vl.outerStride();
4425 int ldvr = vr.outerStride();
4426 int sizeL = masterL.rows();
4428 double rwork[8 * sizeL];
4431 zggev_(&jobvl, &jobvr, &sizeL, masterL_.data(), &ldL, masterM_.data(), &ldM,
4432 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
4433 &ldvr, &wkopt, &lwork, rwork, &info);
4436 lwork = (int)
real(wkopt);
4437 work = (std::complex<double> *)malloc(lwork *
sizeof(std::complex<double>));
4440 zggev_(&jobvl, &jobvr, &sizeL, masterL_.data(), &ldL, masterM_.data(), &ldM,
4441 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
4442 &ldvr, work, &lwork, rwork, &info);
4447 eigenvalues_temp = alpha_temp.array() / beta_temp.array();
4449 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
4450 evecMat_master(c * (
N + 1), c * (
N + 1) + Lbc.m);
4451 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
4452 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
4456 for (
int i = 0; i < c; i++) {
4457 int n = (highest_each_columnL[i] > highest_each_columnM[i])
4458 ? highest_each_columnL[i]
4459 : highest_each_columnM[i];
4464 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
4465 N + 1 + n, c * (
N + 1) + Lbc.m);
4466 evecMat.setConstant(0.0);
4467 evecMat.block(num_bc_each_var[i], 0,
N + 1 + n - num_bc_each_var[i],
4468 c * (
N + 1) + Lbc.m) =
4469 vr.block(row_counter, 0,
N + 1 + n - num_bc_each_var[i],
4470 c * (
N + 1) + Lbc.m);
4471 row_counter +=
N + 1 + n - num_bc_each_var[i];
4472 evecMat.block(0, 0, num_bc_each_var[i], c * (
N + 1) + Lbc.m) =
4473 fir_n_mat.block(col_counter, 0, num_bc_each_var[i],
4474 c * (
N + 1) + Lbc.m);
4475 col_counter += num_bc_each_var[i];
4476 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1) + Lbc.m) =
4477 Mat.
mats2[n] * evecMat;
4479 std::vector<std::vector<T> > eigenval_trunc_sorter;
4481 eigenval_trunc_sorter.resize(c * (
N + 1) + Lbc.m);
4482 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
4483 eigenval_trunc_sorter[i].resize(2);
4486 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1) + Lbc.m);
4487 MPcount.setConstant(0);
4488 std::vector<EigenSorter<T> > sorter;
4489 sorter.resize(c * (
N + 1) + Lbc.m);
4490 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
4491 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
4493 if (sorter[i].Mp ==
true) {
4497 int MPcount_sum = MPcount.sum();
4499 if (num_vals > masterL.rows()) {
4500 std::cout <<
"Only " << masterL.rows()
4501 <<
" eigenvalues can be calculated." 4502 <<
"Storing only that many." <<
'\n';
4503 num_vals = masterL.rows();
4506 for (
int i = 0; i < num_vals; i++) {
4510 if (MPcount_sum >= num_vals) {
4511 for (
int i = 0; i < c * (
N + 1); i++) {
4512 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
4513 eigenval_trunc_sorter[i][1] = i;
4517 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
4518 for (
int i = 0; i < num_vals; i++) {
4519 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
4520 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
4521 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
4523 for (
int j = 0; j < c; j++) {
4524 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
4525 ? highest_each_columnL[j]
4526 : highest_each_columnM[j];
4528 temp_vec.resize(
N + 1 + n, 1);
4529 for (
int i = 0; i < num_vals; i++) {
4531 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
4536 std::cout <<
"Last " << num_vals - MPcount_sum
4537 <<
" eigenvectors are not resolved to machine precision." 4539 for (
int i = 0; i < c * (
N + 1); i++) {
4540 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
4541 eigenval_trunc_sorter[i][1] = i;
4543 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
4544 for (
int i = 0; i < MPcount_sum; i++) {
4545 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
4546 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
4547 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
4549 for (
int j = 0; j < c; j++) {
4550 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
4551 ? highest_each_columnL[j]
4552 : highest_each_columnM[j];
4553 temp_vec.resize(
N + 1 + n, 1);
4554 for (
int i = 0; i < MPcount_sum; i++) {
4556 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
4561 std::vector<std::vector<T> > eigenval_trunc_sorter2;
4562 eigenval_trunc_sorter2.resize(c * (
N + 1) + Lbc.m - MPcount_sum);
4563 for (
int i = MPcount_sum; i < c * (
N + 1) + Lbc.m; i++) {
4564 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
4565 eigenval_trunc_sorter2[i - MPcount_sum][0] =
4566 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
4567 eigenval_trunc_sorter2[i - MPcount_sum][1] =
4568 eigenval_trunc_sorter[i][1];
4570 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
4571 for (
int i = MPcount_sum; i < num_vals; i++) {
4573 int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
4575 alpha_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
4576 beta[i] = beta_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
4578 for (
int j = 0; j < c; j++) {
4579 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
4580 ? highest_each_columnL[j]
4581 : highest_each_columnM[j];
4583 temp_vec.resize(
N + 1 + n, 1);
4584 for (
int i = MPcount_sum; i < num_vals; i++) {
4586 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
4614 int total_of_all_orders = 0;
4615 int total_boundary_conditions = 0;
4616 int total_constraints = 0;
4617 if (Lmat.
r != Lmat.
c) {
4618 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 4622 if (Mmat.
r != Mmat.
c) {
4623 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 4627 if (Mmat.
c != Lmat.
c) {
4628 std::cout <<
"Both matrices have to be of same size. Exiting ..." <<
'\n';
4632 if (Lmat.
c != Lbc_embed.n) {
4634 <<
"Number of columns in Lbc_embed have to be equal to number of " 4635 <<
"columns in Lmat . Exiting .... In line " << __LINE__ <<
'\n';
4638 if (Lmat.
c != Lbc_append.n) {
4640 <<
"Number of columns in Lbc_append have to be equal to number of " 4641 <<
"columns in Lmat . Exiting .... In line " << __LINE__ <<
'\n';
4644 if (Lmat.
c != Mbc_append.n) {
4646 <<
"Number of columns in Mbc_append have to be equal to number of " 4647 <<
"columns in Lmat . Exiting .... In line " << __LINE__ <<
'\n';
4650 if (Lbc_append.m != Mbc_append.m) {
4651 std::cout <<
"Number of rows in Mbc_append have to be equal to number of " 4652 <<
"rows in Lbc_append. Exiting .... In line " << __LINE__
4657 int r = Lmat.
r, c = Lmat.
c;
4661 std::vector<int> highest_each_columnL, highest_each_columnM,
4662 highest_each_column;
4663 highest_each_columnL.resize(c);
4664 highest_each_columnM.resize(c);
4665 highest_each_column.resize(c);
4667 std::vector<int> temp_vec_int;
4668 temp_vec_int.resize(r);
4669 for (
int j = 0; j < c; j++) {
4670 for (
int i = 0; i < r; i++) {
4671 temp_vec_int[i] = Lmat(i, j).n;
4673 highest_each_columnL[j] =
4674 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
4676 for (
int j = 0; j < c; j++) {
4677 for (
int i = 0; i < r; i++) {
4678 temp_vec_int[i] = Mmat(i, j).n;
4680 highest_each_columnM[j] =
4681 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
4683 for (
int i = 0; i < c; i++) {
4684 total_of_all_orders += (highest_each_columnL[i] > highest_each_columnM[i])
4685 ? highest_each_columnL[i]
4686 : highest_each_columnM[i];
4687 highest_each_column[i] =
4688 (highest_each_columnL[i] > highest_each_columnM[i])
4689 ? highest_each_columnL[i]
4690 : highest_each_columnM[i];
4692 total_boundary_conditions = Lbc_embed.m + Lbc_append.m;
4697 if (total_of_all_orders != total_boundary_conditions) {
4698 std::cout <<
"The problem is ill-posed, the total of the highest " 4700 "dependent variables has to be equal to the total number of " 4701 "boundary conditions specified." 4703 "Total no. of boundary conditions: " 4704 << total_boundary_conditions
4706 "Total of all orders: " 4707 << total_of_all_orders <<
"\n Exiting ...\n";
4711 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterL(
4712 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
4714 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterM(
4715 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
4717 masterL.setConstant(0.0);
4718 masterM.setConstant(0.0);
4720 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> subs_mat;
4721 subs_mat.resize(total_boundary_conditions, (
N + 1) * c);
4722 subs_mat.setConstant(0.0);
4723 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> mat_temp(
4724 total_boundary_conditions, total_boundary_conditions),
4725 constraints_embed(Lbc_embed.m, c * (
N + 1) + total_of_all_orders);
4727 mat_temp.setConstant(0.0);
4728 int row_counter = 0, col_counter = 0;
4730 for (
int i = 0; i < Lbc_embed.m; i++) {
4731 for (
int j = 0; j < Lbc_embed.n; j++) {
4732 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> temp =
4733 Lbc_embed(i, j, highest_each_column[j]);
4734 constraints_embed.block(i, col_counter, 1, temp.cols()) = temp;
4735 col_counter += temp.cols();
4740 Eigen::ColPivHouseholderQR<
4741 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
4743 qr.compute(constraints_embed);
4744 if (qr.rank() != constraints_embed.rows()) {
4745 std::cout <<
"The boundary conditions supplied are not " 4746 <<
" linearly independent." <<
'\n';
4747 std::cout <<
"qr.rank = " << qr.rank()
4748 <<
", no. bcs: " << total_boundary_conditions <<
". Exiting ..." 4754 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> P;
4755 P = qr.colsPermutation();
4757 constraints_embed = constraints_embed * P;
4758 mat_temp = constraints_embed.block(0, 0, constraints_embed.rows(),
4759 constraints_embed.rows());
4761 Eigen::ColPivHouseholderQR<
4762 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
4763 consSolver(mat_temp);
4764 subs_mat = -consSolver.inverse() *
4765 constraints_embed.block(
4766 0, constraints_embed.rows(), constraints_embed.rows(),
4767 constraints_embed.cols() - constraints_embed.rows());
4771 int master_row_counter = 0;
4772 int master_col_counter = 0;
4773 for (
int j = 0; j < c; j++) {
4774 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
4775 ? highest_each_columnL[j]
4776 : highest_each_columnM[j];
4778 for (
int i = 0; i < r; i++) {
4779 int diffn = n - Lmat(i, j).n;
4780 if (Lmat(i, j).NCC == 0) {
4781 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
4782 masterL.block(master_row_counter, master_col_counter,
N + 1,
4784 Lmat(i, j).coef[k] *
4785 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
4788 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
4789 masterL.block(master_row_counter, master_col_counter,
N + 1,
4791 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
4792 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
4795 diffn = n - Mmat(i, j).n;
4796 if (Mmat(i, j).NCC == 0) {
4797 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
4798 masterM.block(master_row_counter, master_col_counter,
N + 1,
4800 Mmat(i, j).coef[k] *
4801 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
4804 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
4805 masterM.block(master_row_counter, master_col_counter,
N + 1,
4807 Mmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
4808 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
4811 master_row_counter +=
N + 1;
4813 master_row_counter = 0;
4814 master_col_counter +=
N + 1 + n;
4817 masterL = masterL * P;
4818 masterM = masterM * P;
4820 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterL2(
4821 r * (
N + 1) + Lbc_append.m, c * (
N + 1) + Lbc_append.m),
4822 masterM2(r * (
N + 1) + Lbc_append.m, c * (
N + 1) + Lbc_append.m);
4824 masterL2.block(0, 0, r * (
N + 1), r * (
N + 1) + Lbc_append.m) =
4825 masterL.block(0, constraints_embed.rows(), c * (
N + 1),
4826 c * (
N + 1) + Lbc_append.m) +
4827 (masterL.block(0, 0, c * (
N + 1), constraints_embed.rows()) * subs_mat);
4828 masterM2.block(0, 0, r * (
N + 1), r * (
N + 1) + Lbc_append.m) =
4829 masterM.block(0, constraints_embed.rows(), c * (
N + 1),
4830 c * (
N + 1) + Lbc_append.m) +
4831 (masterM.block(0, 0, c * (
N + 1), constraints_embed.rows()) * subs_mat);
4833 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> constraints_appendL(
4834 Lbc_append.m, c * (
N + 1) + total_of_all_orders),
4835 constraints_appendM(Lbc_append.m, c * (
N + 1) + total_of_all_orders);
4837 for (
int i = 0; i < Lbc_append.m; i++) {
4838 for (
int j = 0; j < Lbc_append.n; j++) {
4839 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> temp =
4840 Lbc_append(i, j, highest_each_column[j]);
4841 constraints_appendL.block(i, col_counter, 1, temp.cols()) = temp;
4842 col_counter += temp.cols();
4847 for (
int i = 0; i < Lbc_append.m; i++) {
4848 for (
int j = 0; j < Lbc_append.n; j++) {
4849 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> temp =
4850 Mbc_append(i, j, highest_each_column[j]);
4851 constraints_appendM.block(i, col_counter, 1, temp.cols()) = temp;
4852 col_counter += temp.cols();
4856 constraints_appendM = constraints_appendM * P;
4857 constraints_appendL = constraints_appendL * P;
4859 masterL2.block(r * (
N + 1), 0, Lbc_append.m, r * (
N + 1) + Lbc_append.m) =
4860 constraints_appendL.block(0, Lbc_embed.m, Lbc_append.m,
4861 r * (
N + 1) + Lbc_append.m) +
4862 (constraints_appendL.block(0, 0, Lbc_append.m, Lbc_embed.m) * subs_mat);
4864 masterM2.block(r * (
N + 1), 0, Lbc_append.m, r * (
N + 1) + Lbc_append.m) =
4865 constraints_appendM.block(0, Lbc_embed.m, Lbc_append.m,
4866 r * (
N + 1) + Lbc_append.m) +
4867 (constraints_appendM.block(0, 0, Lbc_append.m, Lbc_embed.m) * subs_mat);
4869 #ifndef SIS_USE_LAPACK 4870 Eigen::ColPivHouseholderQR<
4871 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
4873 Eigen::ComplexEigenSolver<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
4875 bool Is_M_Invertible;
4876 if (solver.isInvertible()) {
4879 Is_M_Invertible =
true;
4880 eigs.compute(solver.inverse() * masterL2);
4885 Is_M_Invertible =
false;
4886 solver.compute(masterL2);
4887 eigs.compute(solver.inverse() * masterM2);
4892 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> evecMat_master(
4893 c * (
N + 1), c * (
N + 1) + Lbc_append.m);
4894 Eigen::Matrix<T, Eigen::Dynamic, 1> temp_vec;
4895 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
4896 subs_mat * eigs.eigenvectors();
4897 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> evecMat(
4898 c * (
N + 1) + total_boundary_conditions, c * (
N + 1) + Lbc_append.m);
4899 evecMat << fir_n_mat, eigs.eigenvectors();
4902 evecMat = P * evecMat;
4905 for (
int i = 0; i < c; i++) {
4906 int n = (highest_each_columnL[i] > highest_each_columnM[i])
4907 ? highest_each_columnL[i]
4908 : highest_each_columnM[i];
4910 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1) + Lbc_append.m) =
4912 evecMat.block(row_counter, 0,
N + 1 + n, c * (
N + 1) + Lbc_append.m);
4913 row_counter +=
N + 1 + n;
4915 std::vector<std::vector<T> > eigenval_trunc_sorter;
4917 eigenval_trunc_sorter.resize(c * (
N + 1) + Lbc_append.m);
4918 for (
int i = 0; i < c * (
N + 1) + Lbc_append.m; i++) {
4919 eigenval_trunc_sorter[i].resize(2);
4922 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1) + Lbc_append.m);
4923 MPcount.setConstant(0);
4924 std::vector<EigenSorter<T> > sorter;
4925 sorter.resize(c * (
N + 1) + Lbc_append.m);
4926 for (
int i = 0; i < c * (
N + 1) + Lbc_append.m; i++) {
4927 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
4928 if (!Is_M_Invertible) {
4931 if (abs(eigs.eigenvalues()[i]) < 1e-11) {
4932 sorter[i].numMp =
N + 1;
4933 sorter[i].Mp =
false;
4934 sorter[i].minVal = 1e11;
4938 if (sorter[i].Mp ==
true) {
4942 if (num_vals > masterL.rows()) {
4943 std::cout <<
"Only " << masterL.rows()
4944 <<
" eigenvalues can be calculated." 4945 <<
"Storing only that many." <<
'\n';
4946 num_vals = masterL.rows();
4948 int MPcount_sum = MPcount.sum();
4950 for (
int i = 0; i < num_vals; i++) {
4954 if (MPcount_sum >= num_vals) {
4955 for (
int i = 0; i < c * (
N + 1) + Lbc_append.m; i++) {
4956 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
4957 eigenval_trunc_sorter[i][1] = i;
4961 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
4962 for (
int i = 0; i < num_vals; i++) {
4963 if (Is_M_Invertible) {
4964 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
4967 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
4970 for (
int j = 0; j < c; j++) {
4971 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
4972 ? highest_each_columnL[j]
4973 : highest_each_columnM[j];
4975 temp_vec.resize(
N + 1 + n, 1);
4976 for (
int i = 0; i < num_vals; i++) {
4978 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
4982 std::cout <<
"Last " << num_vals - MPcount_sum
4983 <<
" eigenvectors are not resolved to machine precision." 4985 for (
int i = 0; i < c * (
N + 1) + Lbc_append.m; i++) {
4986 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
4987 eigenval_trunc_sorter[i][1] = i;
4989 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
4990 for (
int i = 0; i < MPcount_sum; i++) {
4991 if (Is_M_Invertible) {
4992 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
4995 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
4998 for (
int j = 0; j < c; j++) {
4999 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5000 ? highest_each_columnL[j]
5001 : highest_each_columnM[j];
5002 temp_vec.resize(
N + 1 + n, 1);
5003 for (
int i = 0; i < MPcount_sum; i++) {
5005 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
5009 std::vector<std::vector<T> > eigenval_trunc_sorter2;
5010 eigenval_trunc_sorter2.resize(c * (
N + 1) + Lbc_append.m - MPcount_sum);
5011 for (
int i = MPcount_sum; i < c * (
N + 1) + Lbc_append.m; i++) {
5012 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
5013 eigenval_trunc_sorter2[i - MPcount_sum][0] =
5014 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
5015 eigenval_trunc_sorter2[i - MPcount_sum][1] =
5016 eigenval_trunc_sorter[i][1];
5018 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
5019 for (
int i = MPcount_sum; i < num_vals; i++) {
5020 if (Is_M_Invertible) {
5022 eigenval_trunc_sorter2[i - MPcount_sum][1])];
5025 1.0 / eigs.eigenvalues()[int(
5026 eigenval_trunc_sorter2[i - MPcount_sum][1])];
5029 for (
int j = 0; j < c; j++) {
5030 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5031 ? highest_each_columnL[j]
5032 : highest_each_columnM[j];
5034 temp_vec.resize(
N + 1 + n, 1);
5035 for (
int i = MPcount_sum; i < num_vals; i++) {
5037 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
5043 std::cout <<
"Using lapack routine..." <<
'\n';
5046 std::complex<double> wkopt;
5047 std::complex<double> *work;
5048 alpha.resize(masterL2.rows(), 1);
5049 beta.resize(masterL2.rows(), 1);
5051 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL2_,
5052 masterM2_, vl(masterL2.rows(), masterL2.rows()),
5053 vr(masterL2.rows(), masterL2.rows()),
5054 eigenvalues_temp(masterL2.rows(), 1), alpha_temp(masterL2.rows(), 1),
5055 beta_temp(masterL2.rows(), 1);
5056 masterL2_ = masterL2;
5057 masterM2_ = masterM2;
5059 int ldL = masterL2.outerStride();
5060 int ldM = masterM2.outerStride();
5061 int ldvl = vl.outerStride();
5062 int ldvr = vr.outerStride();
5063 int sizeL = masterL2.rows();
5065 double rwork[8 * sizeL];
5068 zggev_(&jobvl, &jobvr, &sizeL, masterL2_.data(), &ldL, masterM2_.data(),
5069 &ldM, alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl,
5070 vr.data(), &ldvr, &wkopt, &lwork, rwork, &info);
5073 lwork = (int)
real(wkopt);
5074 work = (std::complex<double> *)malloc(lwork *
sizeof(std::complex<double>));
5077 zggev_(&jobvl, &jobvr, &sizeL, masterL2_.data(), &ldL, masterM2_.data(),
5078 &ldM, alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl,
5079 vr.data(), &ldvr, work, &lwork, rwork, &info);
5084 eigenvalues_temp = alpha_temp.array() / beta_temp.array();
5086 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
5087 evecMat_master(c * (
N + 1), c * (
N + 1) + Lbc_append.m);
5088 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
5089 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
5091 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
5092 c * (
N + 1) + total_boundary_conditions, c * (
N + 1) + Lbc_append.m);
5093 evecMat << fir_n_mat, vr;
5095 evecMat = P * evecMat;
5098 for (
int i = 0; i < c; i++) {
5099 int n = (highest_each_columnL[i] > highest_each_columnM[i])
5100 ? highest_each_columnL[i]
5101 : highest_each_columnM[i];
5103 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1) + Lbc_append.m) =
5105 evecMat.block(row_counter, 0,
N + 1 + n, c * (
N + 1) + Lbc_append.m);
5106 row_counter +=
N + 1 + n;
5108 std::vector<std::vector<T> > eigenval_trunc_sorter;
5110 eigenval_trunc_sorter.resize(c * (
N + 1) + Lbc_append.m);
5111 for (
int i = 0; i < c * (
N + 1) + Lbc_append.m; i++) {
5112 eigenval_trunc_sorter[i].resize(2);
5115 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1) + Lbc_append.m);
5116 MPcount.setConstant(0);
5117 std::vector<EigenSorter<T> > sorter;
5118 sorter.resize(c * (
N + 1) + Lbc_append.m);
5119 for (
int i = 0; i < c * (
N + 1) + Lbc_append.m; i++) {
5120 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
5122 if (sorter[i].Mp ==
true) {
5126 if (num_vals > masterL2.rows()) {
5127 std::cout <<
"Only " << masterL2.rows()
5128 <<
" eigenvalues can be calculated." 5129 <<
"Storing only that many." <<
'\n';
5130 num_vals = masterL2.rows();
5133 int MPcount_sum = MPcount.sum();
5135 for (
int i = 0; i < num_vals; i++) {
5139 beta.resize(num_vals);
5140 alpha.resize(num_vals);
5141 if (MPcount_sum >= num_vals) {
5142 for (
int i = 0; i < c * (
N + 1) + Lbc_append.m; i++) {
5143 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
5144 eigenval_trunc_sorter[i][1] = i;
5148 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
5149 for (
int i = 0; i < num_vals; i++) {
5150 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5151 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5152 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5154 for (
int j = 0; j < c; j++) {
5155 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5156 ? highest_each_columnL[j]
5157 : highest_each_columnM[j];
5159 temp_vec.resize(
N + 1 + n, 1);
5160 for (
int i = 0; i < num_vals; i++) {
5162 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
5167 std::cout <<
"Last " << num_vals - MPcount_sum
5168 <<
" eigenvectors are not resolved to machine precision." 5170 for (
int i = 0; i < c * (
N + 1) + Lbc_append.m; i++) {
5171 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
5172 eigenval_trunc_sorter[i][1] = i;
5174 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
5175 for (
int i = 0; i < MPcount_sum; i++) {
5176 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5177 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5178 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5180 for (
int j = 0; j < c; j++) {
5181 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5182 ? highest_each_columnL[j]
5183 : highest_each_columnM[j];
5184 temp_vec.resize(
N + 1 + n, 1);
5185 for (
int i = 0; i < MPcount_sum; i++) {
5187 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
5192 std::vector<std::vector<T> > eigenval_trunc_sorter2;
5193 eigenval_trunc_sorter2.resize(c * (
N + 1) + Lbc_append.m - MPcount_sum);
5194 for (
int i = MPcount_sum; i < c * (
N + 1) + Lbc_append.m; i++) {
5195 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
5196 eigenval_trunc_sorter2[i - MPcount_sum][0] =
5197 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
5198 eigenval_trunc_sorter2[i - MPcount_sum][1] =
5199 eigenval_trunc_sorter[i][1];
5201 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
5202 for (
int i = MPcount_sum; i < num_vals; i++) {
5204 int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
5206 alpha_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
5207 beta[i] = beta_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
5209 for (
int j = 0; j < c; j++) {
5210 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5211 ? highest_each_columnL[j]
5212 : highest_each_columnM[j];
5214 temp_vec.resize(
N + 1 + n, 1);
5215 for (
int i = MPcount_sum; i < num_vals; i++) {
5217 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
5240 #ifdef SIS_USE_LAPACK 5241 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> alpha, beta;
5249 int num_vals,
const BcMat<std::complex<T> > &bc_) {
5252 compute(Lmat_, Mmat, num_vals, bc_);
5258 const BcMat<std::complex<T> > &bc_) {
5260 int num_vals = Lmat_.r * (
N + 1);
5262 compute(Lmat_, Mmat, num_vals, bc_);
5271 const LinopMat<std::complex<T> > &Mmat_,
int num_vals,
5272 const BcMat<std::complex<T> > &Lbc_) {
5278 int total_of_all_orders = 0;
5279 int total_boundary_conditions = 0;
5281 if (Lmat.
r != Lmat.
c) {
5282 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 5286 if (Mmat.
r != Mmat.
c) {
5287 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 5291 if (Mmat.
c != Lmat.
c) {
5292 std::cout <<
"Both matrices have to be of same size. Exiting ..." <<
'\n';
5295 int r = Lmat.
r, c = Lmat.
c;
5299 std::vector<int> highest_each_columnL, highest_each_columnM,
5300 highest_each_column;
5301 highest_each_columnL.resize(c);
5302 highest_each_columnM.resize(c);
5303 highest_each_column.resize(c);
5305 std::vector<int> temp_vec_int;
5306 temp_vec_int.resize(r);
5307 for (
int j = 0; j < c; j++) {
5308 for (
int i = 0; i < r; i++) {
5309 temp_vec_int[i] = Lmat(i, j).n;
5311 highest_each_columnL[j] =
5312 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
5314 for (
int j = 0; j < c; j++) {
5315 for (
int i = 0; i < r; i++) {
5316 temp_vec_int[i] = Mmat(i, j).n;
5318 highest_each_columnM[j] =
5319 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
5321 for (
int i = 0; i < c; i++) {
5322 total_of_all_orders += (highest_each_columnL[i] > highest_each_columnM[i])
5323 ? highest_each_columnL[i]
5324 : highest_each_columnM[i];
5325 highest_each_column[i] =
5326 (highest_each_columnL[i] > highest_each_columnM[i])
5327 ? highest_each_columnL[i]
5328 : highest_each_columnM[i];
5332 total_boundary_conditions = Lbc.m;
5337 if (total_of_all_orders != total_boundary_conditions) {
5338 std::cout <<
"The problem is ill-posed, the total of the highest " 5340 "dependent variables has to be equal to the total number of " 5341 "boundary conditions specified." 5343 "Total no. of boundary conditions: " 5344 << total_boundary_conditions
5346 "Total of all orders: " 5347 << total_of_all_orders <<
"\n Exiting ...\n";
5351 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL(
5352 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
5354 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterM(
5355 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
5357 masterL.setConstant(0.0);
5358 masterM.setConstant(0.0);
5360 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> subs_mat;
5361 subs_mat.resize(total_boundary_conditions, (
N + 1) * c);
5362 subs_mat.setConstant(0.0);
5363 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> mat_temp(
5364 total_boundary_conditions, total_boundary_conditions),
5365 constraints(total_boundary_conditions,
5366 c * (
N + 1) + total_of_all_orders);
5368 mat_temp.setConstant(0.0);
5369 int row_counter = 0, col_counter = 0;
5370 for (
int i = 0; i < Lbc.m; i++) {
5371 for (
int j = 0; j < Lbc.n; j++) {
5372 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> temp=
5373 Lbc(i, j, highest_each_column[j]);
5376 constraints.block(i, col_counter, 1, temp.cols()) = temp;
5377 col_counter += temp.cols();
5382 Eigen::ColPivHouseholderQR<
5383 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
5385 qr.compute(constraints);
5386 if (qr.rank() != constraints.rows()) {
5387 std::cout <<
"The boundary conditions supplied are not " 5388 <<
" linearly independent." <<
'\n';
5389 std::cout <<
"qr.rank = " << qr.rank()
5390 <<
", no. bcs: " << total_boundary_conditions <<
". Exiting ..." 5396 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> P;
5397 P = qr.colsPermutation();
5399 constraints = constraints * P;
5400 mat_temp = constraints.block(0, 0, constraints.rows(), constraints.rows());
5402 Eigen::ColPivHouseholderQR<
5403 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
5404 consSolver(mat_temp);
5405 subs_mat = -consSolver.inverse() *
5406 constraints.block(0, constraints.rows(), constraints.rows(),
5407 constraints.cols() - constraints.rows());
5411 int master_row_counter = 0;
5412 int master_col_counter = 0;
5413 for (
int j = 0; j < c; j++) {
5414 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5415 ? highest_each_columnL[j]
5416 : highest_each_columnM[j];
5418 for (
int i = 0; i < r; i++) {
5419 int diffn = n - Lmat(i, j).n;
5420 if (Lmat(i, j).NCC == 0) {
5421 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
5422 masterL.block(master_row_counter, master_col_counter,
N + 1,
5424 Lmat(i, j).coef[k] *
5425 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
5435 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
5436 masterL.block(master_row_counter, master_col_counter,
N + 1,
5438 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
5439 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
5451 diffn = n - Mmat(i, j).n;
5452 if (Mmat(i, j).NCC == 0) {
5453 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
5454 masterM.block(master_row_counter, master_col_counter,
N + 1,
5456 Mmat(i, j).coef[k] *
5457 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
5460 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
5461 masterM.block(master_row_counter, master_col_counter,
N + 1,
5463 Mmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
5464 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
5467 master_row_counter +=
N + 1;
5469 master_row_counter = 0;
5470 master_col_counter +=
N + 1 + n;
5473 masterL = masterL * P;
5474 masterM = masterM * P;
5476 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL2,
5480 masterL.block(0, constraints.rows(), c * (
N + 1), c * (
N + 1)) +
5481 (masterL.block(0, 0, c * (
N + 1), constraints.rows()) * subs_mat);
5484 masterM.block(0, constraints.rows(), c * (
N + 1), c * (
N + 1)) +
5485 (masterM.block(0, 0, c * (
N + 1), constraints.rows()) * subs_mat);
5487 #if defined SIS_USE_LAPACK 5490 std::complex<double> wkopt;
5491 std::complex<double> *work;
5492 alpha.resize(masterL2.rows(), 1);
5493 beta.resize(masterL2.rows(), 1);
5495 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> vl(
5496 masterL2.rows(), masterL2.rows()),
5497 vr(masterL2.rows(), masterL2.rows()),
5498 eigenvalues_temp(masterL2.rows(), 1), alpha_temp(masterL2.rows(), 1),
5499 beta_temp(masterL2.rows(), 1);
5501 int ldL = masterL2.outerStride();
5502 int ldM = masterM2.outerStride();
5503 int ldvl = vl.outerStride();
5504 int ldvr = vr.outerStride();
5505 int sizeL = masterL2.rows();
5507 double rwork[8 * sizeL];
5510 zggev_(&jobvl, &jobvr, &sizeL, masterL2.data(), &ldL, masterM2.data(), &ldM,
5511 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
5512 &ldvr, &wkopt, &lwork, rwork, &info);
5515 lwork = (int)
real(wkopt);
5516 work = (std::complex<double> *)malloc(lwork *
sizeof(std::complex<double>));
5519 zggev_(&jobvl, &jobvr, &sizeL, masterL2.data(), &ldL, masterM2.data(), &ldM,
5520 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
5521 &ldvr, work, &lwork, rwork, &info);
5526 eigenvalues_temp = alpha_temp.array() / beta_temp.array();
5528 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
5529 evecMat_master(c * (
N + 1), c * (
N + 1));
5530 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
5531 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
5533 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
5534 c * (
N + 1) + total_boundary_conditions, c * (
N + 1));
5535 evecMat << fir_n_mat, vr;
5537 evecMat = P * evecMat;
5540 for (
int i = 0; i < c; i++) {
5541 int n = (highest_each_columnL[i] > highest_each_columnM[i])
5542 ? highest_each_columnL[i]
5543 : highest_each_columnM[i];
5545 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1)) =
5546 Mat.
mats2[n] * evecMat.block(row_counter, 0,
N + 1 + n, c * (
N + 1));
5547 row_counter +=
N + 1 + n;
5549 #ifndef SIS_DONT_SORT 5550 std::vector<std::vector<T> > eigenval_trunc_sorter;
5552 eigenval_trunc_sorter.resize(c * (
N + 1));
5553 for (
int i = 0; i < c * (
N + 1); i++) {
5554 eigenval_trunc_sorter[i].resize(2);
5557 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1));
5558 MPcount.setConstant(0);
5559 std::vector<EigenSorter<T> > sorter;
5560 sorter.resize(c * (
N + 1));
5561 for (
int i = 0; i < c * (
N + 1); i++) {
5562 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
5564 if (std::abs(beta_temp(i, 0)) < 1e-11) {
5565 sorter[i].numMp =
N + 1;
5566 sorter[i].Mp =
false;
5567 sorter[i].minVal = 1e11;
5569 if (sorter[i].Mp ==
true) {
5573 if (num_vals > masterL2.rows()) {
5574 std::cout <<
"Only " << masterL2.rows()
5575 <<
" eigenvalues can be calculated." 5576 <<
"Storing only that many." <<
'\n';
5577 num_vals = masterL2.rows();
5580 int MPcount_sum = MPcount.sum();
5581 converged = MPcount_sum;
5583 eigenvectors.
resize(c, num_vals);
5589 MPorNot.resize(num_vals);
5590 beta.resize(num_vals);
5591 alpha.resize(num_vals);
5592 converged = MPcount_sum;
5593 if (MPcount_sum >= num_vals) {
5594 for (
int i = 0; i < c * (
N + 1); i++) {
5595 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
5596 eigenval_trunc_sorter[i][1] = i;
5600 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
5601 for (
int i = 0; i < num_vals; i++) {
5602 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5603 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5604 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5607 for (
int j = 0; j < c; j++) {
5608 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5609 ? highest_each_columnL[j]
5610 : highest_each_columnM[j];
5612 temp_vec.resize(
N + 1 + n, 1);
5613 for (
int i = 0; i < num_vals; i++) {
5614 eigenvectors(j,i) = evecMat_master.block(
5615 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
5623 std::cout <<
"Last " << num_vals - MPcount_sum
5624 <<
" eigenvectors are not resolved to machine precision." 5626 for (
int i = 0; i < c * (
N + 1); i++) {
5627 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
5628 eigenval_trunc_sorter[i][1] = i;
5630 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
5631 for (
int i = 0; i < MPcount_sum; i++) {
5632 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5633 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5634 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
5637 for (
int j = 0; j < c; j++) {
5638 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5639 ? highest_each_columnL[j]
5640 : highest_each_columnM[j];
5641 temp_vec.resize(
N + 1 + n, 1);
5642 for (
int i = 0; i < MPcount_sum; i++) {
5643 eigenvectors(j,i) = evecMat_master.block(
5644 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
5652 std::vector<std::vector<T> > eigenval_trunc_sorter2;
5653 eigenval_trunc_sorter2.resize(c * (
N + 1) - MPcount_sum);
5654 for (
int i = MPcount_sum; i < c * (
N + 1); i++) {
5655 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
5656 eigenval_trunc_sorter2[i - MPcount_sum][0] =
5657 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
5658 eigenval_trunc_sorter2[i - MPcount_sum][1] =
5659 eigenval_trunc_sorter[i][1];
5661 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
5662 for (
int i = MPcount_sum; i < num_vals; i++) {
5664 int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
5666 alpha_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
5667 beta[i] = beta_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
5670 for (
int j = 0; j < c; j++) {
5671 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5672 ? highest_each_columnL[j]
5673 : highest_each_columnM[j];
5675 temp_vec.resize(
N + 1 + n, 1);
5676 for (
int i = MPcount_sum; i < num_vals; i++) {
5677 eigenvectors(j,i) = evecMat_master.block(
5678 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
5689 eigenvectors.
resize(c, c * (
N + 1));
5695 MPorNot.resize(c * (
N + 1));
5696 beta.resize(c * (
N + 1));
5697 alpha.resize(c * (
N + 1));
5699 for (
int i = 0; i < c * (
N + 1); i++) {
5701 alpha[i] = alpha_temp(i, 0);
5702 beta[i] = beta_temp(i, 0);
5705 for (
int j = 0; j < c; j++) {
5706 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5707 ? highest_each_columnL[j]
5708 : highest_each_columnM[j];
5710 temp_vec.resize(
N + 1 + n, 1);
5711 for (
int i = 0; i < c * (
N + 1); i++) {
5712 eigenvectors(j,i) = evecMat_master.block(j * (
N + 1), i,
N + 1, 1);
5721 Eigen::ColPivHouseholderQR<
5722 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
5724 Eigen::ComplexEigenSolver<
5725 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
5727 bool Is_M_Invertible;
5728 if (solver.isInvertible()) {
5731 Is_M_Invertible =
true;
5732 eigs.compute(solver.inverse() * masterL2);
5737 Is_M_Invertible =
false;
5738 solver.compute(masterL2);
5739 eigs.compute(solver.inverse() * masterM2);
5744 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
5745 evecMat_master(c * (
N + 1), c * (
N + 1));
5746 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
5747 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
5748 subs_mat * eigs.eigenvectors();
5749 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
5750 c * (
N + 1) + total_boundary_conditions, c * (
N + 1));
5751 evecMat << fir_n_mat, eigs.eigenvectors();
5754 evecMat = P * evecMat;
5757 for (
int i = 0; i < c; i++) {
5758 int n = (highest_each_columnL[i] > highest_each_columnM[i])
5759 ? highest_each_columnL[i]
5760 : highest_each_columnM[i];
5762 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1)) =
5763 Mat.
mats2[n] * evecMat.block(row_counter, 0,
N + 1 + n, c * (
N + 1));
5764 row_counter +=
N + 1 + n;
5767 #ifndef SIS_DONT_SORT 5768 std::vector<std::vector<T> > eigenval_trunc_sorter;
5770 eigenval_trunc_sorter.resize(c * (
N + 1));
5771 for (
int i = 0; i < c * (
N + 1); i++) {
5772 eigenval_trunc_sorter[i].resize(2);
5775 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1));
5776 MPcount.setConstant(0);
5777 std::vector<EigenSorter<T> > sorter;
5778 sorter.resize(c * (
N + 1));
5779 for (
int i = 0; i < c * (
N + 1); i++) {
5780 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
5781 if (!Is_M_Invertible) {
5784 if (abs(eigs.eigenvalues()[i]) < 1e-11) {
5785 sorter[i].numMp =
N + 1;
5786 sorter[i].Mp =
false;
5787 sorter[i].minVal = 1e11;
5791 if (sorter[i].Mp ==
true) {
5795 if (num_vals > masterL2.rows()) {
5796 std::cout <<
"Only " << masterL2.rows()
5797 <<
" eigenvalues can be calculated." 5798 <<
"Storing only that many." <<
'\n';
5799 num_vals = masterL2.rows();
5802 int MPcount_sum = MPcount.sum();
5803 converged = MPcount_sum;
5804 eigenvectors.
resize(c,num_vals);
5810 MPorNot.resize(num_vals);
5811 if (MPcount_sum >= num_vals) {
5812 for (
int i = 0; i < c * (
N + 1); i++) {
5813 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
5814 eigenval_trunc_sorter[i][1] = i;
5818 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
5819 for (
int i = 0; i < num_vals; i++) {
5820 if (Is_M_Invertible) {
5821 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
5825 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
5829 for (
int j = 0; j < c; j++) {
5830 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5831 ? highest_each_columnL[j]
5832 : highest_each_columnM[j];
5834 temp_vec.resize(
N + 1 + n, 1);
5835 for (
int i = 0; i < num_vals; i++) {
5836 eigenvectors(j,i) = evecMat_master.block(
5837 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
5845 std::cout <<
"Last " << num_vals - MPcount_sum
5846 <<
" eigenvectors are not resolved to machine precision." 5848 for (
int i = 0; i < c * (
N + 1); i++) {
5849 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
5850 eigenval_trunc_sorter[i][1] = i;
5852 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
5853 for (
int i = 0; i < MPcount_sum; i++) {
5854 if (Is_M_Invertible) {
5855 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
5860 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
5864 for (
int j = 0; j < c; j++) {
5865 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5866 ? highest_each_columnL[j]
5867 : highest_each_columnM[j];
5868 temp_vec.resize(
N + 1 + n, 1);
5869 for (
int i = 0; i < MPcount_sum; i++) {
5870 eigenvectors(j,i) = evecMat_master.block(
5871 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
5879 std::vector<std::vector<T> > eigenval_trunc_sorter2;
5880 eigenval_trunc_sorter2.resize(c * (
N + 1) - MPcount_sum);
5881 for (
int i = MPcount_sum; i < c * (
N + 1); i++) {
5882 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
5883 eigenval_trunc_sorter2[i - MPcount_sum][0] =
5884 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
5885 eigenval_trunc_sorter2[i - MPcount_sum][1] =
5886 eigenval_trunc_sorter[i][1];
5888 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
5889 for (
int i = MPcount_sum; i < num_vals; i++) {
5890 if (Is_M_Invertible) {
5892 eigenval_trunc_sorter2[i - MPcount_sum][1])];
5897 1.0 / eigs.eigenvalues()[int(
5898 eigenval_trunc_sorter2[i - MPcount_sum][1])];
5902 for (
int j = 0; j < c; j++) {
5903 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5904 ? highest_each_columnL[j]
5905 : highest_each_columnM[j];
5907 temp_vec.resize(
N + 1 + n, 1);
5908 for (
int i = MPcount_sum; i < num_vals; i++) {
5909 eigenvectors(j,i) = evecMat_master.block(
5910 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
5922 eigenvectors.
resize(c, c * (
N + 1))
5928 MPorNot.resize(c * (
N + 1));
5930 for (
int i = 0; i < c * (
N + 1); i++) {
5931 if (Is_M_Invertible) {
5939 for (
int j = 0; j < c; j++) {
5940 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
5941 ? highest_each_columnL[j]
5942 : highest_each_columnM[j];
5944 temp_vec.resize(
N + 1 + n, 1);
5945 for (
int i = 0; i < c * (
N + 1); i++) {
5946 eigenvectors(j,i) = evecMat_master.block(j * (
N + 1), i,
N + 1, 1);
5971 const LinopMat<std::complex<T> > &Mmat_,
int num_vals,
5972 const BcMat<std::complex<T> > &Lbc_) {
5978 int total_of_all_orders = 0;
5979 int total_boundary_conditions = 0;
5980 if (Lmat.
r != Lmat.
c) {
5981 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 5985 if (Mmat.
r != Mmat.
c) {
5986 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 5990 if (Mmat.
c != Lmat.
c) {
5991 std::cout <<
"Both matrices have to be of same size. Exiting ..." <<
'\n';
5994 int r = Lmat.
r, c = Lmat.
c;
5998 std::vector<int> highest_each_columnL, highest_each_columnM,
5999 highest_each_column;
6000 highest_each_columnL.resize(c);
6001 highest_each_columnM.resize(c);
6002 highest_each_column.resize(c);
6004 std::vector<int> temp_vec_int;
6005 temp_vec_int.resize(r);
6006 for (
int j = 0; j < c; j++) {
6007 for (
int i = 0; i < r; i++) {
6008 temp_vec_int[i] = Lmat(i, j).n;
6010 highest_each_columnL[j] =
6011 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
6013 for (
int j = 0; j < c; j++) {
6014 for (
int i = 0; i < r; i++) {
6015 temp_vec_int[i] = Mmat(i, j).n;
6017 highest_each_columnM[j] =
6018 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
6020 for (
int i = 0; i < c; i++) {
6021 total_of_all_orders += (highest_each_columnL[i] > highest_each_columnM[i])
6022 ? highest_each_columnL[i]
6023 : highest_each_columnM[i];
6024 highest_each_column[i] =
6025 (highest_each_columnL[i] > highest_each_columnM[i])
6026 ? highest_each_columnL[i]
6027 : highest_each_columnM[i];
6031 total_boundary_conditions = Lbc.m;
6036 if (total_of_all_orders != total_boundary_conditions) {
6037 std::cout <<
"The problem is ill-posed, the total of the highest " 6039 "dependent variables has to be equal to the total number of " 6040 "boundary conditions specified." 6042 "Total no. of boundary conditions: " 6043 << total_boundary_conditions
6045 "Total of all orders: " 6046 << total_of_all_orders <<
"\n Exiting ...\n";
6050 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL(
6051 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
6053 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterM(
6054 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
6056 masterL.setConstant(0.0);
6057 masterM.setConstant(0.0);
6059 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
6060 constraints(total_boundary_conditions,
6061 c * (
N + 1) + total_of_all_orders),
6062 Zeros(total_boundary_conditions,
6063 c * (
N + 1) + total_of_all_orders);
6065 Zeros.setConstant(0.0);
6066 int row_counter = 0, col_counter = 0;
6067 for (
int i = 0; i < Lbc.m; i++) {
6068 for (
int j = 0; j < Lbc.n; j++) {
6069 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> temp=
6070 Lbc(i, j, highest_each_column[j]);
6071 constraints.block(i, col_counter, 1, temp.cols()) = temp;
6072 col_counter += temp.cols();
6079 int master_row_counter = 0;
6080 int master_col_counter = 0;
6081 for (
int j = 0; j < c; j++) {
6082 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
6083 ? highest_each_columnL[j]
6084 : highest_each_columnM[j];
6086 for (
int i = 0; i < r; i++) {
6087 int diffn = n - Lmat(i, j).n;
6088 if (Lmat(i, j).NCC == 0) {
6089 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
6090 masterL.block(master_row_counter, master_col_counter,
N + 1,
6092 Lmat(i, j).coef[k] *
6093 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
6096 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
6097 masterL.block(master_row_counter, master_col_counter,
N + 1,
6099 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
6100 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
6103 diffn = n - Mmat(i, j).n;
6104 if (Mmat(i, j).NCC == 0) {
6105 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
6106 masterM.block(master_row_counter, master_col_counter,
N + 1,
6108 Mmat(i, j).coef[k] *
6109 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
6112 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
6113 masterM.block(master_row_counter, master_col_counter,
N + 1,
6115 Mmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
6116 (Mat.
mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
6119 master_row_counter +=
N + 1;
6121 master_row_counter = 0;
6122 master_col_counter +=
N + 1 + n;
6128 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL2(
6129 r * (
N + 1) + total_boundary_conditions,
6130 c * (
N + 1) + total_boundary_conditions),
6132 r * (
N + 1) + total_boundary_conditions,
6133 c * (
N + 1) + total_boundary_conditions);
6135 masterL2 << masterL,constraints;
6138 masterM2 << masterM, Zeros;
6140 #if defined SIS_USE_LAPACK 6143 std::complex<double> wkopt;
6144 std::complex<double> *work;
6145 alpha.resize(masterL2.rows(), 1);
6146 beta.resize(masterL2.rows(), 1);
6148 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> vl(
6149 masterL2.rows(), masterL2.rows()),
6150 vr(masterL2.rows(), masterL2.rows()),
6151 eigenvalues_temp(masterL2.rows(), 1), alpha_temp(masterL2.rows(), 1),
6152 beta_temp(masterL2.rows(), 1);
6154 int ldL = masterL2.outerStride();
6155 int ldM = masterM2.outerStride();
6156 int ldvl = vl.outerStride();
6157 int ldvr = vr.outerStride();
6158 int sizeL = masterL2.rows();
6160 double rwork[8 * sizeL];
6163 zggev_(&jobvl, &jobvr, &sizeL, masterL2.data(), &ldL, masterM2.data(), &ldM,
6164 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
6165 &ldvr, &wkopt, &lwork, rwork, &info);
6168 lwork = (int)
real(wkopt);
6169 work = (std::complex<double> *)malloc(lwork *
sizeof(std::complex<double>));
6172 zggev_(&jobvl, &jobvr, &sizeL, masterL2.data(), &ldL, masterM2.data(), &ldM,
6173 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
6174 &ldvr, work, &lwork, rwork, &info);
6179 eigenvalues_temp = alpha_temp.array() / beta_temp.array();
6182 alpha.resize(alpha_temp.rows(),1);
6183 beta.resize(beta_temp.rows(),1);
6188 std::cout <<
"This function needs SIS_USE_LAPACK to be defined, and LAPACK" 6189 <<
" linking is essential. Exiting ..." <<
'\n';
6194 #ifdef SIS_USE_FEAST 6195 void feast_compute(
const LinopMat<std::complex<T> > &Lmat_,
6196 const LinopMat<std::complex<T> > &Mmat_,
int num_vals,
6197 const BcMat<std::complex<T> > &Lbc_) {
6202 int total_of_all_orders = 0;
6203 int total_boundary_conditions = 0;
6204 if (Lmat.
r != Lmat.
c) {
6205 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 6209 if (Mmat.
r != Mmat.
c) {
6210 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 6214 if (Mmat.
c != Lmat.
c) {
6215 std::cout <<
"Both matrices have to be of same size. Exiting ..." <<
'\n';
6218 int r = Lmat.
r, c = Lmat.
c;
6222 std::vector<int> highest_each_columnL, highest_each_columnM,
6223 highest_each_column;
6224 highest_each_columnL.resize(c);
6225 highest_each_columnM.resize(c);
6226 highest_each_column.resize(c);
6228 std::vector<int> temp_vec_int;
6229 temp_vec_int.resize(r);
6230 for (
int j = 0; j < c; j++) {
6231 for (
int i = 0; i < r; i++) {
6232 temp_vec_int[i] = Lmat(i, j).n;
6234 highest_each_columnL[j] =
6235 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
6237 for (
int j = 0; j < c; j++) {
6238 for (
int i = 0; i < r; i++) {
6239 temp_vec_int[i] = Mmat(i, j).n;
6241 highest_each_columnM[j] =
6242 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
6244 for (
int i = 0; i < c; i++) {
6245 total_of_all_orders += (highest_each_columnL[i] > highest_each_columnM[i])
6246 ? highest_each_columnL[i]
6247 : highest_each_columnM[i];
6248 highest_each_column[i] =
6249 (highest_each_columnL[i] > highest_each_columnM[i])
6250 ? highest_each_columnL[i]
6251 : highest_each_columnM[i];
6255 total_boundary_conditions = Lbc.m;
6260 if (total_of_all_orders != total_boundary_conditions) {
6261 std::cout <<
"The problem is ill-posed, the total of the highest " 6263 "dependent variables has to be equal to the total number of " 6264 "boundary conditions specified." 6266 "Total no. of boundary conditions: " 6267 << total_boundary_conditions
6269 "Total of all orders: " 6270 << total_of_all_orders <<
"\n Exiting ...\n";
6274 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL(
6275 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
6277 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterM(
6278 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
6280 masterL.setConstant(0.0);
6281 masterM.setConstant(0.0);
6283 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> subs_mat;
6284 subs_mat.resize(total_boundary_conditions, (
N + 1) * c);
6285 subs_mat.setConstant(0.0);
6286 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> mat_temp(
6287 total_boundary_conditions, total_boundary_conditions),
6288 constraints(total_boundary_conditions,
6289 c * (
N + 1) + total_of_all_orders);
6291 mat_temp.setConstant(0.0);
6292 int row_counter = 0, col_counter = 0;
6294 for (
int i = 0; i < Lbc.m; i++) {
6295 for (
int j = 0; j < Lbc.n; j++) {
6296 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> temp =
6297 Lbc(i, j, highest_each_column[j]);
6298 constraints.block(i, col_counter, 1, temp.cols()) = temp;
6299 col_counter += temp.cols();
6304 Eigen::ColPivHouseholderQR<
6305 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
6307 qr.compute(constraints);
6308 if (qr.rank() != constraints.rows()) {
6309 std::cout <<
"The boundary conditions supplied are not " 6310 <<
" linearly independent." <<
'\n';
6311 std::cout <<
"qr.rank = " << qr.rank()
6312 <<
", no. bcs: " << total_boundary_conditions <<
". Exiting ..." 6318 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> P;
6319 P = qr.colsPermutation();
6321 constraints = constraints * P;
6322 mat_temp = constraints.block(0, 0, constraints.rows(), constraints.rows());
6324 Eigen::ColPivHouseholderQR<
6325 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
6326 consSolver(mat_temp);
6327 subs_mat = -consSolver.inverse() *
6328 constraints.block(0, constraints.rows(), constraints.rows(),
6329 constraints.cols() - constraints.rows());
6333 int master_row_counter = 0;
6334 int master_col_counter = 0;
6335 for (
int j = 0; j < c; j++) {
6336 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
6337 ? highest_each_columnL[j]
6338 : highest_each_columnM[j];
6340 for (
int i = 0; i < r; i++) {
6341 int diffn = n - Lmat(i, j).n;
6342 if (Lmat(i, j).NCC == 0) {
6343 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
6344 masterL.block(master_row_counter, master_col_counter,
N + 1,
6346 Lmat(i, j).coef[k] *
6347 (Mat.mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
6350 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
6351 masterL.block(master_row_counter, master_col_counter,
N + 1,
6353 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
6354 (Mat.mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
6357 diffn = n - Mmat(i, j).n;
6358 if (Mmat(i, j).NCC == 0) {
6359 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
6360 masterM.block(master_row_counter, master_col_counter,
N + 1,
6362 Mmat(i, j).coef[k] *
6363 (Mat.mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
6366 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
6367 masterM.block(master_row_counter, master_col_counter,
N + 1,
6369 Mmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
6370 (Mat.mats2[k + diffn].block(0, 0,
N + 1,
N + 1 + n));
6373 master_row_counter +=
N + 1;
6375 master_row_counter = 0;
6376 master_col_counter +=
N + 1 + n;
6379 masterL = masterL * P;
6380 masterM = masterM * P;
6382 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL2,
6386 masterL.block(0, constraints.rows(), c * (
N + 1), c * (
N + 1)) +
6387 (masterL.block(0, 0, c * (
N + 1), constraints.rows()) * subs_mat);
6390 masterM.block(0, constraints.rows(), c * (
N + 1), c * (
N + 1)) +
6391 (masterM.block(0, 0, c * (
N + 1), constraints.rows()) * subs_mat);
6393 int ldL = masterL2.outerStride();
6394 int ldM = masterM2.outerStride();
6400 double res[2 * feast::M0];
6401 feast::feast_init();
6403 feast::feastparam[0] = 1;
6404 feast::feastparam[7] = 56;
6410 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> lambda(
6412 vecs(masterM2.rows(), 2 * feast::M0), vr;
6413 lambda.setConstant(0.0);
6414 vecs.setConstant(0.0);
6415 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
6420 std::cout <<
"in " << __LINE__ <<
'\n' << std::flush;
6421 zfeast_gegv_(&
N, masterL2.data(), &ldL, masterM2.data(), &ldM,
6422 feast::feastparam, &epsout, &loop, Emid, &feast::radius,
6423 &feast::M0, lambda.data(), vecs.data(), &M, res, &feast::info);
6432 std::cout <<
"M = " << M <<
'\n';
6434 eigenvalues_temp = lambda.block(0, 0, M, 1);
6435 vr.resize(masterL2.rows(), M);
6436 vr = vecs.block(0, 0, vecs.rows(), M);
6437 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
6438 evecMat_master(c * (
N + 1), M);
6439 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
6440 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
6442 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
6443 c * (
N + 1) + total_boundary_conditions, M);
6444 evecMat << fir_n_mat, vr;
6446 evecMat = P * evecMat;
6449 for (
int i = 0; i < c; i++) {
6450 int n = (highest_each_columnL[i] > highest_each_columnM[i])
6451 ? highest_each_columnL[i]
6452 : highest_each_columnM[i];
6454 evecMat_master.block(i * (
N + 1), 0,
N + 1, M) =
6455 Mat.mats2[n] * evecMat.block(row_counter, 0,
N + 1 + n, M);
6456 row_counter +=
N + 1 + n;
6458 std::vector<std::vector<T> > eigenval_trunc_sorter;
6460 eigenval_trunc_sorter.resize(M);
6461 for (
int i = 0; i < M; i++) {
6462 eigenval_trunc_sorter[i].resize(2);
6465 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(M);
6466 MPcount.setConstant(0);
6467 std::vector<EigenSorter<T> > sorter;
6469 for (
int i = 0; i < M; i++) {
6470 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
6472 if (sorter[i].Mp ==
true) {
6477 std::cout <<
"Only " << M <<
" eigenvalues can be calculated." 6478 <<
"Storing only that many." <<
'\n';
6482 int MPcount_sum = MPcount.sum();
6483 converged = MPcount_sum;
6486 for (
int i = 0; i < num_vals; i++) {
6490 converged = MPcount_sum;
6491 if (MPcount_sum >= num_vals) {
6492 for (
int i = 0; i < M; i++) {
6493 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
6494 eigenval_trunc_sorter[i][1] = i;
6498 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
6499 for (
int i = 0; i < num_vals; i++) {
6500 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
6502 for (
int j = 0; j < c; j++) {
6503 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
6504 ? highest_each_columnL[j]
6505 : highest_each_columnM[j];
6507 temp_vec.resize(
N + 1 + n, 1);
6508 for (
int i = 0; i < num_vals; i++) {
6510 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
6515 std::cout <<
"Last " << num_vals - MPcount_sum
6516 <<
" eigenvectors are not resolved to machine precision." 6518 for (
int i = 0; i < M; i++) {
6519 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
6520 eigenval_trunc_sorter[i][1] = i;
6522 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
6523 for (
int i = 0; i < MPcount_sum; i++) {
6524 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
6526 for (
int j = 0; j < c; j++) {
6527 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
6528 ? highest_each_columnL[j]
6529 : highest_each_columnM[j];
6530 temp_vec.resize(
N + 1 + n, 1);
6531 for (
int i = 0; i < MPcount_sum; i++) {
6533 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
6538 std::vector<std::vector<T> > eigenval_trunc_sorter2;
6539 eigenval_trunc_sorter2.resize(M - MPcount_sum);
6540 for (
int i = MPcount_sum; i < M; i++) {
6541 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
6542 eigenval_trunc_sorter2[i - MPcount_sum][0] =
6543 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
6544 eigenval_trunc_sorter2[i - MPcount_sum][1] =
6545 eigenval_trunc_sorter[i][1];
6547 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
6548 for (
int i = MPcount_sum; i < num_vals; i++) {
6550 int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
6552 for (
int j = 0; j < c; j++) {
6553 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
6554 ? highest_each_columnL[j]
6555 : highest_each_columnM[j];
6557 temp_vec.resize(
N + 1 + n, 1);
6558 for (
int i = MPcount_sum; i < num_vals; i++) {
6560 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
6577 const LinopMat<std::complex<T> > &Mmat_,
6579 const BcMat<std::complex<T> > &Lbc_,
6580 const BcMat<std::complex<T> > &Mbc_) {
6582 LinopMat<std::complex<T> > Lmat = Lmat_;
6583 LinopMat<std::complex<T> > Mmat = Mmat_;
6584 BcMat<std::complex<T> > Lbc = Lbc_;
6585 BcMat<std::complex<T> > Mbc = Mbc_;
6587 int total_of_all_orders = 0;
6588 int total_boundary_conditions = 0;
6589 if (Lmat.r != Lmat.c) {
6590 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 6594 if (Mmat.r != Mmat.c) {
6595 std::cout <<
"Solution only possible with square LinopMats. Exiting ..." 6599 if (Mmat.c != Lmat.c) {
6600 std::cout <<
"Both matrices have to be of same size. Exiting ..." <<
'\n';
6603 int r = Lmat.r, c = Lmat.c;
6607 std::vector<int> highest_each_columnL, highest_each_columnM,
6608 highest_each_column, num_bc_each_var;
6609 highest_each_columnL.resize(c);
6610 highest_each_columnM.resize(c);
6611 highest_each_column.resize(c);
6612 num_bc_each_var.resize(c);
6613 std::vector<int> temp_vec_int;
6614 temp_vec_int.resize(r);
6615 for (
int j = 0; j < c; j++) {
6616 for (
int i = 0; i < r; i++) {
6617 temp_vec_int[i] = Lmat(i, j).n;
6619 highest_each_columnL[j] =
6620 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
6622 for (
int j = 0; j < c; j++) {
6623 for (
int i = 0; i < r; i++) {
6624 temp_vec_int[i] = Mmat(i, j).n;
6626 highest_each_columnM[j] =
6627 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
6629 for (
int i = 0; i < c; i++) {
6630 total_of_all_orders += (highest_each_columnL[i] > highest_each_columnM[i])
6631 ? highest_each_columnL[i]
6632 : highest_each_columnM[i];
6633 highest_each_column[i] =
6634 (highest_each_columnL[i] > highest_each_columnM[i])
6635 ? highest_each_columnL[i]
6636 : highest_each_columnM[i];
6638 for (
int i = 0; i < c; i++) {
6639 total_boundary_conditions += Lmat.BcVec[i].nbc();
6640 num_bc_each_var[i] = Lmat.BcVec[i].nbc();
6643 if (Lbc.m != Mbc.m) {
6644 std::cout <<
"The Lbc and Mbc have to be of same dimensions" <<
'\n' 6645 <<
"Exiting in " << __LINE__ <<
"...\n";
6652 if (total_of_all_orders != (total_boundary_conditions + Lbc.m)) {
6653 std::cout <<
"The problem is ill-posed, the total of the highest " 6655 "dependent variables has to be equal to the total number of " 6656 "boundary conditions plus number of constraints specified." 6658 "Total no. of boundary conditions: " 6659 << total_boundary_conditions
6661 "Total of all orders: " 6662 << total_of_all_orders <<
"\n Number of Constraints : " << Lbc.m
6663 <<
"\n Exiting in " << __LINE__ <<
" ...\n ";
6667 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL(
6668 r * (
N + 1) + Lbc.m, c * (
N + 1) + Lbc.m);
6670 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterM(
6671 r * (
N + 1) + Lbc.m, c * (
N + 1) + Lbc.m);
6673 masterL.setConstant(0.0);
6674 masterM.setConstant(0.0);
6676 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> subs_mat;
6678 subs_mat.resize(total_boundary_conditions, (
N + 1) * c + Lbc.m);
6680 subs_mat.setConstant(0.0);
6681 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> mat_temp(
6682 total_boundary_conditions, total_boundary_conditions);
6683 mat_temp.setConstant(0.0);
6684 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
6685 subs_mat_col_mul(c * (
N + 1), total_boundary_conditions);
6686 subs_mat_col_mul.setConstant(0.0);
6687 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
6688 subs_mat_col_mul2(c * (
N + 1), total_boundary_conditions);
6689 subs_mat_col_mul2.setConstant(0.0);
6690 int subs_mat_row_counter = 0;
6691 int subs_mat_col_counter = 0;
6692 int row_counter = 0, col_counter = 0;
6693 for (
int j = 0; j < c; j++) {
6695 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
6696 ? highest_each_columnL[j]
6697 : highest_each_columnM[j];
6703 std::vector<Eigen::Matrix<std::complex<T>, 1, Eigen::Dynamic> > lbc_vecs(
6705 Eigen::Matrix<std::complex<T>, 1, Eigen::Dynamic>(
N + 1 + 2 * n));
6706 std::vector<Eigen::Matrix<std::complex<T>, 1, Eigen::Dynamic> > rbc_vecs(
6708 Eigen::Matrix<std::complex<T>, 1, Eigen::Dynamic>(
N + 1 + 2 * n));
6709 std::vector<Eigen::Matrix<std::complex<T>, 1, Eigen::Dynamic> >
6710 lbc_con_vecs(Lmat.BcVec[j].nl,
6711 Eigen::Matrix<std::complex<T>, 1, Eigen::Dynamic>(n));
6712 std::vector<Eigen::Matrix<std::complex<T>, 1, Eigen::Dynamic> >
6713 rbc_con_vecs(Lmat.BcVec[j].nr,
6714 Eigen::Matrix<std::complex<T>, 1, Eigen::Dynamic>(n));
6715 Eigen::Matrix<T, 1, Eigen::Dynamic> ones(
N + 1 + 2 * n);
6716 Eigen::Matrix<T, 1, Eigen::Dynamic> onem(
N + 1 + 2 * n);
6717 Eigen::Matrix<T, 1, Eigen::Dynamic> onesn(n);
6718 Eigen::Matrix<T, 1, Eigen::Dynamic> onemn(n);
6720 ones.setConstant(1.0);
6721 onesn.setConstant(1.0);
6722 onem.setConstant(1.0);
6723 onemn.setConstant(1.0);
6725 for (
int k = 1; k <
N + 1 + 2 * n; k = k + 2) {
6728 for (
int k = 1; k < n; k = k + 2) {
6738 for (
int k = 0; k < Lmat.BcVec[j].nl; k++) {
6739 lbc_vecs[k].resize(
N + 1 + 2 * n);
6740 lbc_vecs[k].setConstant(std::complex<T>(0.0, 0.0));
6741 for (
int l = 0; l < Lmat.BcVec[j].ord + 1; l++) {
6742 lbc_vecs[k] += Lmat.BcVec[j].coefl(k, l) *
6743 (onem * Mat.mats[l + (n - Lmat.BcVec[j].ord)]);
6747 for (
int k = 0; k < Lmat.BcVec[j].nr; k++) {
6748 rbc_vecs[k].resize(
N + 1 + 2 * n);
6749 rbc_vecs[k].setConstant(std::complex<T>(0.0, 0.0));
6750 for (
int l = 0; l < Lmat.BcVec[j].ord + 1; l++) {
6751 rbc_vecs[k] += Lmat.BcVec[j].coefr(k, l) *
6752 (ones * Mat.mats[l + (n - Lmat.BcVec[j].ord)]);
6755 for (
int k = 0; k < Lmat.BcVec[j].nl; k++) {
6756 lbc_con_vecs[k].setConstant(0.0);
6757 for (
int l = 0; l < Lmat.BcVec[j].ord + 1; l++) {
6758 if (l + n - Lmat.BcVec[j].ord - 1 > -1) {
6760 Lmat.BcVec[j].coefl(k, l) *
6761 (onemn * Mat.con_mats[l + n - Lmat.BcVec[j].ord - 1]);
6765 for (
int k = 0; k < Lmat.BcVec[j].nr; k++) {
6766 rbc_con_vecs[k].setConstant(0.0);
6767 for (
int l = 0; l < Lmat.BcVec[j].ord + 1; l++) {
6768 if (l + n - Lmat.BcVec[j].ord - 1 > -1) {
6770 Lmat.BcVec[j].coefr(k, l) *
6771 (onesn * Mat.con_mats[l + n - Lmat.BcVec[j].ord - 1]);
6776 for (
int k = 0; k < Lmat.BcVec[j].nl; k++) {
6777 mat_temp.block(row_counter, col_counter, 1,
6778 Lmat.BcVec[j].nl + Lmat.BcVec[j].nr) =
6779 lbc_vecs[k].head(Lmat.BcVec[j].nl + Lmat.BcVec[j].nr);
6782 for (
int k = Lmat.BcVec[j].nl; k < Lmat.BcVec[j].nl + Lmat.BcVec[j].nr;
6784 mat_temp.block(row_counter, col_counter, 1,
6785 Lmat.BcVec[j].nl + Lmat.BcVec[j].nr) =
6786 rbc_vecs[k - Lmat.BcVec[j].nl].head(Lmat.BcVec[j].nl +
6790 col_counter = col_counter + Lmat.BcVec[j].nbc();
6791 for (
int k = 0; k < Lmat.BcVec[j].nl; k++) {
6792 subs_mat.block(subs_mat_row_counter, subs_mat_col_counter, 1,
6793 (
N + 1 - Lmat.BcVec[j].nbc())) =
6794 lbc_vecs[k].block(0, Lmat.BcVec[j].nbc(), 1,
6795 N + 1 - Lmat.BcVec[j].nbc());
6796 subs_mat.block(subs_mat_row_counter,
6797 subs_mat_col_counter + (
N + 1 - Lmat.BcVec[j].nbc()), 1,
6798 n) = lbc_con_vecs[k];
6799 subs_mat_row_counter++;
6802 for (
int k = Lmat.BcVec[j].nl; k < Lmat.BcVec[j].nbc(); k++) {
6803 subs_mat.block(subs_mat_row_counter, subs_mat_col_counter, 1,
6804 (
N + 1 - Lmat.BcVec[j].nbc())) =
6805 rbc_vecs[k - Lmat.BcVec[j].nl].block(0, Lmat.BcVec[j].nbc(), 1,
6806 N + 1 - Lmat.BcVec[j].nbc());
6807 subs_mat.block(subs_mat_row_counter,
6808 subs_mat_col_counter + (
N + 1 - Lmat.BcVec[j].nbc()), 1,
6809 n) = rbc_con_vecs[k - Lmat.BcVec[j].nl];
6810 subs_mat_row_counter++;
6812 subs_mat_col_counter += (
N + 1 + n - Lmat.BcVec[j].nbc());
6814 if (mat_temp.rows() != 0 || mat_temp.cols() != 0) {
6815 Eigen::ColPivHouseholderQR<
6816 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
6817 consSolver(mat_temp);
6818 if (!consSolver.isInvertible()) {
6819 std::cout <<
"the matrix is not invertible." <<
'\n';
6822 subs_mat = -consSolver.inverse() * subs_mat.eval();
6826 int master_row_counter = 0;
6827 int master_col_counter = 0;
6828 subs_mat_row_counter = 0;
6829 subs_mat_col_counter = 0;
6830 for (
int j = 0; j < c; j++) {
6831 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
6832 ? highest_each_columnL[j]
6833 : highest_each_columnM[j];
6835 for (
int i = 0; i < r; i++) {
6837 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
6838 solver_matL(
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc());
6839 solver_matL.setConstant(0.0);
6840 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
6841 solver_matM(
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc());
6842 solver_matM.setConstant(0.0);
6843 int diffn = n - Lmat(i, j).n;
6844 if (Lmat(i, j).NCC == 0) {
6845 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
6846 solver_matL.block(0, 0,
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc()) +=
6847 Lmat(i, j).coef[k] *
6848 (Mat.mats2[k + diffn].block(0, Lmat.BcVec[j].nbc(),
N + 1,
6849 N + 1 + n - Lmat.BcVec[j].nbc()));
6850 subs_mat_col_mul.block(i * (
N + 1), subs_mat_col_counter,
N + 1,
6851 Lmat.BcVec[j].nbc()) +=
6852 Lmat(i, j).coef[k] *
6853 (Mat.mats2[k + diffn].block(0, 0,
N + 1, Lmat.BcVec[j].nbc()));
6856 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
6857 solver_matL.block(0, 0,
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc()) +=
6858 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
6859 (Mat.mats2[k + diffn].block(0, Lmat.BcVec[j].nbc(),
N + 1,
6860 N + 1 + n - Lmat.BcVec[j].nbc()));
6861 subs_mat_col_mul.block(i * (
N + 1), subs_mat_col_counter,
N + 1,
6862 Lmat.BcVec[j].nbc()) +=
6863 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
6864 (Mat.mats2[k + diffn].block(0, 0,
N + 1, Lmat.BcVec[j].nbc()));
6867 diffn = n - Mmat(i, j).n;
6868 if (Mmat(i, j).NCC == 0) {
6869 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
6870 solver_matM.block(0, 0,
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc()) +=
6871 Mmat(i, j).coef[k] *
6872 (Mat.mats2[k + diffn].block(0, Lmat.BcVec[j].nbc(),
N + 1,
6873 N + 1 + n - Lmat.BcVec[j].nbc()));
6874 subs_mat_col_mul2.block(i * (
N + 1), subs_mat_col_counter,
N + 1,
6875 Lmat.BcVec[j].nbc()) +=
6876 Mmat(i, j).coef[k] *
6877 (Mat.mats2[k + diffn].block(0, 0,
N + 1, Lmat.BcVec[j].nbc()));
6880 for (
int k = 0; k < Mmat(i, j).n + 1; k++) {
6881 solver_matM.block(0, 0,
N + 1,
N + 1 + n - Lmat.BcVec[j].nbc()) +=
6882 Mmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
6883 (Mat.mats2[k + diffn].block(0, Lmat.BcVec[j].nbc(),
N + 1,
6884 N + 1 + n - Lmat.BcVec[j].nbc()));
6885 subs_mat_col_mul2.block(i * (
N + 1), subs_mat_col_counter,
N + 1,
6886 Lmat.BcVec[j].nbc()) +=
6887 Mmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
6888 (Mat.mats2[k + diffn].block(0, 0,
N + 1, Lmat.BcVec[j].nbc()));
6891 subs_mat_row_counter +=
N + 1 + n - Lmat.BcVec[j].nbc();
6892 masterL.block(i * (
N + 1), master_col_counter,
N + 1,
6893 N + 1 + n - Lmat.BcVec[j].nbc()) = solver_matL;
6894 masterM.block(i * (
N + 1), master_col_counter,
N + 1,
6895 N + 1 + n - Lmat.BcVec[j].nbc()) = solver_matM;
6897 subs_mat_col_counter += Lmat.BcVec[j].nbc();
6898 subs_mat_row_counter = 0;
6899 master_row_counter = 0;
6900 master_col_counter +=
N + 1 + n - Lmat.BcVec[j].nbc();
6902 if (mat_temp.rows() != 0 || mat_temp.cols() != 0) {
6903 masterL.block(0, 0, c * (
N + 1), c * (
N + 1) + Lbc.m) +=
6904 masterL.block(0, 0, c * (
N + 1), c * (
N + 1) + Lbc.m).eval() +
6905 (subs_mat_col_mul * subs_mat);
6906 masterM.block(0, 0, c * (
N + 1), c * (
N + 1) + Lbc.m) +=
6907 masterM.block(0, 0, c * (
N + 1), c * (
N + 1) + Lbc.m).eval() +
6908 (subs_mat_col_mul2 * subs_mat);
6912 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
6913 constraints_bigL(Lbc.m, c * (
N + 1) + Lbc.m),
6914 constraints_smallL(Lbc.m, total_boundary_conditions),
6915 constraints_bigM(Lbc.m, c * (
N + 1) + Lbc.m),
6916 constraints_smallM(Lbc.m, total_boundary_conditions);
6917 constraints_bigL.setConstant(0.0);
6918 constraints_smallL.setConstant(0.0);
6919 constraints_bigM.setConstant(0.0);
6920 constraints_smallM.setConstant(0.0);
6923 int col_counter2 = 0;
6924 int row_counter2 = 0;
6925 for (
int i = 0; i < Lbc.m; i++) {
6926 for (
int j = 0; j < Lbc.n; j++) {
6927 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> temp =
6928 Lbc(i, j, highest_each_column[j]);
6930 constraints_bigL.block(i, col_counter, 1,
6931 N + 1 + highest_each_column[j] -
6932 num_bc_each_var[j]) =
6933 temp.block(0, num_bc_each_var[j], 1,
6934 N + 1 + highest_each_column[j] - num_bc_each_var[j]);
6936 constraints_smallL.block(i, col_counter2, 1, num_bc_each_var[j]) =
6937 temp.block(0, 0, 1, num_bc_each_var[j]);
6941 temp = Mbc(i, j, highest_each_column[j]);
6943 constraints_bigM.block(i, col_counter, 1,
6944 N + 1 + highest_each_column[j] -
6945 num_bc_each_var[j]) =
6946 temp.block(0, num_bc_each_var[j], 1,
6947 N + 1 + highest_each_column[j] - num_bc_each_var[j]);
6949 constraints_smallM.block(i, col_counter2, 1, num_bc_each_var[j]) =
6950 temp.block(0, 0, 1, num_bc_each_var[j]);
6951 col_counter +=
N + 1 + highest_each_column[j] - num_bc_each_var[j];
6952 col_counter2 += num_bc_each_var[j];
6957 if (mat_temp.rows() != 0 || mat_temp.cols() != 0) {
6958 masterL.block(c * (
N + 1), 0, Lbc.m, c * (
N + 1) + Lbc.m) =
6959 constraints_bigL + constraints_smallL * subs_mat;
6960 masterM.block(c * (
N + 1), 0, Lbc.m, c * (
N + 1) + Lbc.m) =
6961 constraints_bigM + constraints_smallM * subs_mat;
6963 masterL.block(c * (
N + 1), 0, Lbc.m, c * (
N + 1) + Lbc.m) =
6965 masterM.block(c * (
N + 1), 0, Lbc.m, c * (
N + 1) + Lbc.m) =
6969 #ifndef SIS_USE_LAPACK 6970 Eigen::ColPivHouseholderQR<
6971 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
6973 Eigen::ComplexEigenSolver<
6974 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
6976 bool Is_M_Invertible;
6977 if (solver.isInvertible()) {
6978 Is_M_Invertible =
true;
6979 eigs.compute(solver.inverse() * masterL);
6982 Is_M_Invertible =
false;
6983 solver.compute(masterL);
6984 eigs.compute(solver.inverse() * masterM);
6989 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
6990 evecMat_master(c * (
N + 1) + Lbc.m, c * (
N + 1) + Lbc.m);
6991 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
6992 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat,
6994 if (subs_mat.size() > 0) {
6995 fir_n_mat = subs_mat * eigs.eigenvectors();
6997 full_mat.resize(c * (
N + 1) + Lbc.m + fir_n_mat.rows(),
6998 c * (
N + 1) + Lbc.m);
7004 for (
int i = 0; i < c; i++) {
7005 int n = (highest_each_columnL[i] > highest_each_columnM[i])
7006 ? highest_each_columnL[i]
7007 : highest_each_columnM[i];
7008 if (subs_mat.size() > 0) {
7009 full_mat.block(row_counter, 0, num_bc_each_var[i],
7010 c * (
N + 1) + Lbc.m) =
7011 fir_n_mat.block(col_counter, 0, num_bc_each_var[i],
7012 c * (
N + 1) + Lbc.m);
7014 row_counter += num_bc_each_var[i];
7015 col_counter += num_bc_each_var[i];
7017 full_mat.block(row_counter, 0,
N + 1 + n - num_bc_each_var[i],
7018 c * (
N + 1) + Lbc.m) =
7019 eigs.eigenvectors().block(row_counter2, 0,
7020 N + 1 + n - num_bc_each_var[i],
7021 c * (
N + 1) + Lbc.m);
7022 row_counter +=
N + 1 + n - num_bc_each_var[i];
7023 row_counter2 +=
N + 1 + n - num_bc_each_var[i];
7027 for (
int i = 0; i < c; i++) {
7028 int n = (highest_each_columnL[i] > highest_each_columnM[i])
7029 ? highest_each_columnL[i]
7030 : highest_each_columnM[i];
7032 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1) + Lbc.m) =
7034 full_mat.block(row_counter, 0,
N + 1 + n, c * (
N + 1) + Lbc.m);
7035 row_counter +=
N + 1 + n;
7038 std::vector<std::vector<T> > eigenval_trunc_sorter;
7040 eigenval_trunc_sorter.resize(c * (
N + 1) + Lbc.m);
7041 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
7042 eigenval_trunc_sorter[i].resize(2);
7045 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1) + Lbc.m);
7046 MPcount.setConstant(0);
7047 std::vector<EigenSorter<T> > sorter;
7048 sorter.resize(c * (
N + 1) + Lbc.m);
7049 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
7050 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
7051 if (!Is_M_Invertible) {
7054 if (abs(eigs.eigenvalues()[i]) < 1e-11) {
7055 sorter[i].numMp =
N + 1;
7056 sorter[i].Mp =
false;
7057 sorter[i].minVal = 1e11;
7061 if (sorter[i].Mp ==
true) {
7065 if (num_vals > masterL.rows()) {
7066 std::cout <<
"Only " << masterL.rows()
7067 <<
" eigenvalues can be calculated." 7068 <<
"Storing only that many." <<
'\n';
7069 num_vals = masterL.rows();
7071 int MPcount_sum = MPcount.sum();
7072 converged = MPcount_sum;
7074 eigenvectors.
resize(c, num_vals);
7080 if (MPcount_sum >= num_vals) {
7081 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
7082 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
7083 eigenval_trunc_sorter[i][1] = i;
7087 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
7088 for (
int i = 0; i < num_vals; i++) {
7089 if (Is_M_Invertible) {
7090 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
7093 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
7096 for (
int j = 0; j < c; j++) {
7097 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
7098 ? highest_each_columnL[j]
7099 : highest_each_columnM[j];
7101 temp_vec.resize(
N + 1 + n, 1);
7102 for (
int i = 0; i < num_vals; i++) {
7103 eigenvectors(j,i) = evecMat_master.block(
7104 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
7112 std::cout <<
"Last " << num_vals - MPcount_sum
7113 <<
" eigenvectors are not resolved to machine precision." 7115 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
7116 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
7117 eigenval_trunc_sorter[i][1] = i;
7119 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
7120 for (
int i = 0; i < MPcount_sum; i++) {
7121 if (Is_M_Invertible) {
7122 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
7125 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
7128 for (
int j = 0; j < c; j++) {
7129 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
7130 ? highest_each_columnL[j]
7131 : highest_each_columnM[j];
7132 temp_vec.resize(
N + 1 + n, 1);
7133 for (
int i = 0; i < MPcount_sum; i++) {
7134 eigenvectors(j,i) = evecMat_master.block(
7135 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
7143 std::vector<std::vector<T> > eigenval_trunc_sorter2;
7144 eigenval_trunc_sorter2.resize(c * (
N + 1) + Lbc.m - MPcount_sum);
7145 for (
int i = MPcount_sum; i < c * (
N + 1) + Lbc.m; i++) {
7146 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
7147 eigenval_trunc_sorter2[i - MPcount_sum][0] =
7148 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
7149 eigenval_trunc_sorter2[i - MPcount_sum][1] =
7150 eigenval_trunc_sorter[i][1];
7152 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
7153 for (
int i = MPcount_sum; i < num_vals; i++) {
7154 if (Is_M_Invertible) {
7156 eigenval_trunc_sorter2[i - MPcount_sum][1])];
7159 1.0 / eigs.eigenvalues()[int(
7160 eigenval_trunc_sorter2[i - MPcount_sum][1])];
7163 for (
int j = 0; j < c; j++) {
7164 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
7165 ? highest_each_columnL[j]
7166 : highest_each_columnM[j];
7168 temp_vec.resize(
N + 1 + n, 1);
7169 for (
int i = MPcount_sum; i < num_vals; i++) {
7170 eigenvectors(j,i) = evecMat_master.block(
7171 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
7185 std::complex<double> wkopt;
7186 std::complex<double> *work;
7187 alpha.resize(masterL.rows(), 1);
7188 beta.resize(masterL.rows(), 1);
7190 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> vl(
7191 masterL.rows(), masterL.rows()),
7192 vr(masterL.rows(), masterL.rows()), eigenvalues_temp(masterL.rows(), 1),
7193 alpha_temp(masterL.rows(), 1), beta_temp(masterL.rows(), 1);
7195 int ldL = masterL.outerStride();
7196 int ldM = masterM.outerStride();
7197 int ldvl = vl.outerStride();
7198 int ldvr = vr.outerStride();
7199 int sizeL = masterL.rows();
7201 double rwork[8 * sizeL];
7204 zggev_(&jobvl, &jobvr, &sizeL, masterL.data(), &ldL, masterM.data(), &ldM,
7205 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
7206 &ldvr, &wkopt, &lwork, rwork, &info);
7209 lwork = (int)
real(wkopt);
7210 work = (std::complex<double> *)malloc(lwork *
sizeof(std::complex<double>));
7213 zggev_(&jobvl, &jobvr, &sizeL, masterL.data(), &ldL, masterM.data(), &ldM,
7214 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
7215 &ldvr, work, &lwork, rwork, &info);
7220 eigenvalues_temp = alpha_temp.array() / beta_temp.array();
7222 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
7223 evecMat_master(c * (
N + 1), c * (
N + 1) + Lbc.m);
7224 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
7225 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
7229 for (
int i = 0; i < c; i++) {
7230 int n = (highest_each_columnL[i] > highest_each_columnM[i])
7231 ? highest_each_columnL[i]
7232 : highest_each_columnM[i];
7237 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
7238 N + 1 + n, c * (
N + 1) + Lbc.m);
7239 evecMat.setConstant(0.0);
7240 evecMat.block(num_bc_each_var[i], 0,
N + 1 + n - num_bc_each_var[i],
7241 c * (
N + 1) + Lbc.m) =
7242 vr.block(row_counter, 0,
N + 1 + n - num_bc_each_var[i],
7243 c * (
N + 1) + Lbc.m);
7244 row_counter +=
N + 1 + n - num_bc_each_var[i];
7245 evecMat.block(0, 0, num_bc_each_var[i], c * (
N + 1) + Lbc.m) =
7246 fir_n_mat.block(col_counter, 0, num_bc_each_var[i],
7247 c * (
N + 1) + Lbc.m);
7248 col_counter += num_bc_each_var[i];
7249 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1) + Lbc.m) =
7250 Mat.mats2[n] * evecMat;
7252 std::vector<std::vector<T> > eigenval_trunc_sorter;
7254 eigenval_trunc_sorter.resize(c * (
N + 1) + Lbc.m);
7255 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
7256 eigenval_trunc_sorter[i].resize(2);
7259 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1) + Lbc.m);
7260 MPcount.setConstant(0);
7261 std::vector<EigenSorter<T> > sorter;
7262 sorter.resize(c * (
N + 1) + Lbc.m);
7263 for (
int i = 0; i < c * (
N + 1) + Lbc.m; i++) {
7264 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
7266 if (sorter[i].Mp ==
true) {
7270 int MPcount_sum = MPcount.sum();
7271 converged = MPcount_sum;
7273 if (num_vals > masterL.rows()) {
7274 std::cout <<
"Only " << masterL.rows()
7275 <<
" eigenvalues can be calculated." 7276 <<
"Storing only that many." <<
'\n';
7277 num_vals = masterL.rows();
7280 eigenvectors.
resize(c,num_vals);
7286 if (MPcount_sum >= num_vals) {
7287 for (
int i = 0; i < c * (
N + 1); i++) {
7288 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
7289 eigenval_trunc_sorter[i][1] = i;
7293 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
7294 for (
int i = 0; i < num_vals; i++) {
7295 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7296 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7297 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7299 for (
int j = 0; j < c; j++) {
7300 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
7301 ? highest_each_columnL[j]
7302 : highest_each_columnM[j];
7304 temp_vec.resize(
N + 1 + n, 1);
7305 for (
int i = 0; i < num_vals; i++) {
7306 eigenvectors(j,i) = evecMat_master.block(
7307 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
7315 std::cout <<
"Last " << num_vals - MPcount_sum
7316 <<
" eigenvectors are not resolved to machine precision." 7318 for (
int i = 0; i < c * (
N + 1); i++) {
7319 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
7320 eigenval_trunc_sorter[i][1] = i;
7322 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
7323 for (
int i = 0; i < MPcount_sum; i++) {
7324 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7325 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7326 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7328 for (
int j = 0; j < c; j++) {
7329 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
7330 ? highest_each_columnL[j]
7331 : highest_each_columnM[j];
7332 temp_vec.resize(
N + 1 + n, 1);
7333 for (
int i = 0; i < MPcount_sum; i++) {
7334 eigenvectors(j,i) = evecMat_master.block(
7335 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
7343 std::vector<std::vector<T> > eigenval_trunc_sorter2;
7344 eigenval_trunc_sorter2.resize(c * (
N + 1) + Lbc.m - MPcount_sum);
7345 for (
int i = MPcount_sum; i < c * (
N + 1) + Lbc.m; i++) {
7346 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
7347 eigenval_trunc_sorter2[i - MPcount_sum][0] =
7348 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
7349 eigenval_trunc_sorter2[i - MPcount_sum][1] =
7350 eigenval_trunc_sorter[i][1];
7352 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
7353 for (
int i = MPcount_sum; i < num_vals; i++) {
7355 int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
7357 alpha_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
7358 beta[i] = beta_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
7360 for (
int j = 0; j < c; j++) {
7361 int n = (highest_each_columnL[j] >= highest_each_columnM[j])
7362 ? highest_each_columnL[j]
7363 : highest_each_columnM[j];
7365 temp_vec.resize(
N + 1 + n, 1);
7366 for (
int i = MPcount_sum; i < num_vals; i++) {
7367 eigenvectors(j,i) = evecMat_master.block(
7368 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
7390 std::vector<std::vector<T> > sorter;
7392 for (
int i = 0; i < n; i++) {
7393 sorter[i].resize(2);
7396 for (
int i = 0; i < n; i++) {
7402 std::sort(sorter.begin(), sorter.end());
7404 std::reverse(sorter.begin(), sorter.end());
7407 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> tempvals;
7408 Eigen::Matrix<int, Eigen::Dynamic, 1> tempMP;
7410 tempMat = eigenvectors;
7412 #ifdef SIS_USE_LAPACK 7413 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> tempAlpha, tempBeta;
7417 for (
int i = 0; i < n; i++) {
7419 for (
int j = 0; j < tempMat.r; j++)
7420 eigenvectors(j,i) = tempMat(j,sorter[i][1]);
7421 MPorNot[i] = tempMP[sorter[i][1]];
7423 #ifdef SIS_USE_LAPACK 7424 alpha[i] = tempAlpha[sorter[i][1]];
7425 beta[i] = tempBeta[sorter[i][1]];
7433 int c = eigenvectors.
c;
7434 int r = eigenvectors.
r;
7436 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> eigenvalues_temp;
7437 #ifdef SIS_USE_LAPACK 7438 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> alpha_temp = alpha;
7439 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> beta_temp = beta;
7441 beta.resize(converged);
7443 eigenvectors_temp = eigenvectors;
7445 eigenvectors.
resize(eigenvectors_temp.
r,converged);
7449 for (
int i = 0; i < eigenvalues_temp.size(); i++) {
7450 if (MPorNot[i] == 1) {
7451 for (
int j = 0; j < eigenvectors_temp.
r; j++)
7452 eigenvectors(j,count) = eigenvectors_temp(j,i);
7454 #ifdef SIS_USE_LAPACK 7455 alpha[count] = alpha_temp[i];
7456 beta[count] = beta_temp[i];
7461 MPorNot.resize(converged);
7462 MPorNot.setConstant(1);
7470 int c = eigenvectors.
c;
7471 int r = eigenvectors.
r;
7473 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> eigenvalues_temp;
7474 eigenvectors_temp = eigenvectors;
7476 #ifdef SIS_USE_LAPACK 7477 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> alpha_temp = alpha;
7478 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> beta_temp = beta;
7480 eigenvectors.
resize(eigenvectors_temp.
r,n);
7487 for (
int i = 0; i < n; i++) {
7488 for (
int j = 0; j < eigenvectors_temp.
r; j++)
7489 eigenvectors(j,i) = eigenvectors_temp(j,i);
7491 #ifdef SIS_USE_LAPACK 7492 alpha[i] = alpha_temp[i];
7493 beta[i] = beta_temp[i];
7502 std::vector<T> noninf_indices;
7504 #ifndef SIS_USE_LAPACK 7509 noninf_indices.push_back(i);
7512 if (std::abs(beta[i]) < 1.0e-8) {
7514 noninf_indices.push_back(i);
7519 int n = noninf_indices.size();
7520 int c = eigenvectors.
c;
7521 int r = eigenvectors.
r;
7523 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> eigenvalues_temp;
7524 Eigen::Matrix<int, Eigen::Dynamic, 1> MPorNot_temp;
7525 #ifdef SIS_USE_LAPACK 7526 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> alpha_temp = alpha;
7527 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> beta_temp = beta;
7529 eigenvectors_temp = eigenvectors;
7531 MPorNot_temp = MPorNot;
7532 eigenvectors.
resize(eigenvectors_temp.
r,n);
7539 #ifdef SIS_USE_LAPACK 7544 for (
int i = 0; i < n; i++) {
7545 for (
int j = 0; j < eigenvectors_temp.
r; j++)
7546 eigenvectors(j,i) = eigenvectors_temp(j,noninf_indices[i]);
7547 eigenvalues[i] = eigenvalues_temp[noninf_indices[i]];
7548 MPorNot[i] = MPorNot_temp[noninf_indices[i]];
7549 #ifdef SIS_USE_LAPACK 7550 alpha[i] = alpha_temp[noninf_indices[i]];
7551 beta[i] = beta_temp[noninf_indices[i]];
7557 const Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> &L_,
7558 const Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> &M_,
7560 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterM2 =
7564 int num_vals = masterM2.rows();
7565 int c = masterM2.rows() / (
N + 1);
7566 int total_boundary_conditions = Dis.subs_mat.rows();
7568 int row_counter = 0;
7569 int col_counter = 0;
7570 #ifndef SIS_USE_LAPACK 7571 Eigen::ColPivHouseholderQR<
7572 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
7574 Eigen::ComplexEigenSolver<
7575 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
7577 bool Is_M_Invertible;
7578 if (solver.isInvertible()) {
7581 Is_M_Invertible =
true;
7582 eigs.compute(solver.inverse() * masterL2);
7587 Is_M_Invertible =
false;
7588 solver.compute(masterL2);
7589 eigs.compute(solver.inverse() * masterM2);
7594 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
7595 evecMat_master(c * (
N + 1), c * (
N + 1));
7596 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
7597 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
7598 Dis.subs_mat * eigs.eigenvectors();
7599 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
7600 c * (
N + 1) + total_boundary_conditions, c * (
N + 1));
7601 evecMat << fir_n_mat, eigs.eigenvectors();
7605 evecMat = Dis.P * evecMat;
7607 for (
int i = 0; i < c; i++) {
7608 int n = Dis.highest_each_column[i];
7610 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1)) =
7611 Mat.
mats2[n] * evecMat.block(row_counter, 0,
N + 1 + n, c * (
N + 1));
7612 row_counter +=
N + 1 + n;
7614 std::vector<std::vector<T> > eigenval_trunc_sorter;
7616 eigenval_trunc_sorter.resize(c * (
N + 1));
7617 for (
int i = 0; i < c * (
N + 1); i++) {
7618 eigenval_trunc_sorter[i].resize(2);
7621 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1));
7622 MPcount.setConstant(0);
7623 std::vector<EigenSorter<T> > sorter;
7624 sorter.resize(c * (
N + 1));
7625 for (
int i = 0; i < c * (
N + 1); i++) {
7626 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
7627 if (!Is_M_Invertible) {
7630 if (abs(eigs.eigenvalues()[i]) < 1e-11) {
7631 sorter[i].numMp =
N + 1;
7632 sorter[i].Mp =
false;
7633 sorter[i].minVal = 1e11;
7637 if (sorter[i].Mp ==
true) {
7641 if (num_vals > masterL2.rows()) {
7642 std::cout <<
"Only " << masterL2.rows()
7643 <<
" eigenvalues can be calculated." 7644 <<
"Storing only that many." <<
'\n';
7645 num_vals = masterL2.rows();
7648 int MPcount_sum = MPcount.sum();
7649 converged = MPcount_sum;
7650 eigenvectors.
resize(c,num_vals);
7656 if (MPcount_sum >= num_vals) {
7657 for (
int i = 0; i < c * (
N + 1); i++) {
7658 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
7659 eigenval_trunc_sorter[i][1] = i;
7663 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
7664 for (
int i = 0; i < num_vals; i++) {
7665 if (Is_M_Invertible) {
7666 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
7669 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
7672 for (
int j = 0; j < c; j++) {
7673 int n = Dis.highest_each_column[j];
7675 temp_vec.resize(
N + 1 + n, 1);
7676 for (
int i = 0; i < num_vals; i++) {
7677 eigenvectors(j,i) = evecMat_master.block(
7678 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
7686 std::cout <<
"Last " << num_vals - MPcount_sum
7687 <<
" eigenvectors are not resolved to machine precision." 7689 for (
int i = 0; i < c * (
N + 1); i++) {
7690 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
7691 eigenval_trunc_sorter[i][1] = i;
7693 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
7694 for (
int i = 0; i < MPcount_sum; i++) {
7695 if (Is_M_Invertible) {
7696 eigenvalues[i] = eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
7699 1.0 / eigs.eigenvalues()[int(eigenval_trunc_sorter[i][1])];
7702 for (
int j = 0; j < c; j++) {
7703 int n = Dis.highest_each_column[j];
7704 temp_vec.resize(
N + 1 + n, 1);
7705 for (
int i = 0; i < MPcount_sum; i++) {
7706 eigenvectors(j,i) = evecMat_master.block(
7707 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
7715 std::vector<std::vector<T> > eigenval_trunc_sorter2;
7716 eigenval_trunc_sorter2.resize(c * (
N + 1) - MPcount_sum);
7717 for (
int i = MPcount_sum; i < c * (
N + 1); i++) {
7718 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
7719 eigenval_trunc_sorter2[i - MPcount_sum][0] =
7720 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
7721 eigenval_trunc_sorter2[i - MPcount_sum][1] =
7722 eigenval_trunc_sorter[i][1];
7724 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
7725 for (
int i = MPcount_sum; i < num_vals; i++) {
7726 if (Is_M_Invertible) {
7728 eigenval_trunc_sorter2[i - MPcount_sum][1])];
7731 1.0 / eigs.eigenvalues()[int(
7732 eigenval_trunc_sorter2[i - MPcount_sum][1])];
7735 for (
int j = 0; j < c; j++) {
7736 int n = Dis.highest_each_column[j];
7738 temp_vec.resize(
N + 1 + n, 1);
7739 for (
int i = MPcount_sum; i < num_vals; i++) {
7740 eigenvectors(j,i) = evecMat_master.block(
7741 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
7754 std::complex<double> wkopt;
7755 std::complex<double> *work;
7756 alpha.resize(masterL2.rows(), 1);
7757 beta.resize(masterL2.rows(), 1);
7759 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> vl(
7760 masterL2.rows(), masterL2.rows()),
7761 vr(masterL2.rows(), masterL2.rows()),
7762 eigenvalues_temp(masterL2.rows(), 1), alpha_temp(masterL2.rows(), 1),
7763 beta_temp(masterL2.rows(), 1);
7765 int ldL = masterL2.outerStride();
7766 int ldM = masterM2.outerStride();
7767 int ldvl = vl.outerStride();
7768 int ldvr = vr.outerStride();
7769 int sizeL = masterL2.rows();
7771 double rwork[8 * sizeL];
7774 zggev_(&jobvl, &jobvr, &sizeL, masterL2.data(), &ldL, masterM2.data(), &ldM,
7775 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
7776 &ldvr, &wkopt, &lwork, rwork, &info);
7779 lwork = (int)
real(wkopt);
7780 work = (std::complex<double> *)malloc(lwork *
sizeof(std::complex<double>));
7783 zggev_(&jobvl, &jobvr, &sizeL, masterL2.data(), &ldL, masterM2.data(), &ldM,
7784 alpha_temp.data(), beta_temp.data(), vl.data(), &ldvl, vr.data(),
7785 &ldvr, work, &lwork, rwork, &info);
7790 eigenvalues_temp = alpha_temp.array() / beta_temp.array();
7792 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
7793 evecMat_master(c * (
N + 1), c * (
N + 1));
7794 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, 1> temp_vec;
7795 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> fir_n_mat =
7797 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> evecMat(
7798 c * (
N + 1) + total_boundary_conditions, c * (
N + 1));
7799 evecMat << fir_n_mat, vr;
7801 evecMat = Dis.P * evecMat;
7802 for (
int i = 0; i < c; i++) {
7803 int n = Dis.highest_each_column[i];
7805 evecMat_master.block(i * (
N + 1), 0,
N + 1, c * (
N + 1)) =
7806 Mat.
mats2[n] * evecMat.block(row_counter, 0,
N + 1 + n, c * (
N + 1));
7807 row_counter +=
N + 1 + n;
7809 std::vector<std::vector<T> > eigenval_trunc_sorter;
7811 eigenval_trunc_sorter.resize(c * (
N + 1));
7812 for (
int i = 0; i < c * (
N + 1); i++) {
7813 eigenval_trunc_sorter[i].resize(2);
7816 Eigen::Matrix<int, Eigen::Dynamic, 1> MPcount(c * (
N + 1));
7817 MPcount.setConstant(0);
7818 std::vector<EigenSorter<T> > sorter;
7819 sorter.resize(c * (
N + 1));
7820 for (
int i = 0; i < c * (
N + 1); i++) {
7821 sorter[i].compute(evecMat_master.block(0, i, c * (
N + 1), 1), c);
7823 if (sorter[i].Mp ==
true) {
7827 if (num_vals > masterL2.rows()) {
7828 std::cout <<
"Only " << masterL2.rows()
7829 <<
" eigenvalues can be calculated." 7830 <<
"Storing only that many." <<
'\n';
7831 num_vals = masterL2.rows();
7834 int MPcount_sum = MPcount.sum();
7835 converged = MPcount_sum;
7837 eigenvectors.
resize(c,num_vals);
7843 beta.resize(num_vals);
7844 alpha.resize(num_vals);
7845 converged = MPcount_sum;
7846 if (MPcount_sum >= num_vals) {
7847 for (
int i = 0; i < c * (
N + 1); i++) {
7848 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
7849 eigenval_trunc_sorter[i][1] = i;
7853 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
7854 for (
int i = 0; i < num_vals; i++) {
7855 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7856 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7857 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7859 for (
int j = 0; j < c; j++) {
7860 int n = Dis.highest_each_column[j];
7862 temp_vec.resize(
N + 1 + n, 1);
7863 for (
int i = 0; i < num_vals; i++) {
7864 eigenvectors(j,i) = evecMat_master.block(
7865 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
7873 std::cout <<
"Last " << num_vals - MPcount_sum
7874 <<
" eigenvectors are not resolved to machine precision." 7876 for (
int i = 0; i < c * (
N + 1); i++) {
7877 eigenval_trunc_sorter[i][0] = T(sorter[i].numMp);
7878 eigenval_trunc_sorter[i][1] = i;
7880 std::sort(eigenval_trunc_sorter.begin(), eigenval_trunc_sorter.end());
7881 for (
int i = 0; i < MPcount_sum; i++) {
7882 eigenvalues[i] = eigenvalues_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7883 alpha[i] = alpha_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7884 beta[i] = beta_temp(
int(eigenval_trunc_sorter[i][1]), 0);
7886 for (
int j = 0; j < c; j++) {
7887 int n = Dis.highest_each_column[j];
7888 temp_vec.resize(
N + 1 + n, 1);
7889 for (
int i = 0; i < MPcount_sum; i++) {
7890 eigenvectors(j,i) = evecMat_master.block(
7891 j * (
N + 1),
int(eigenval_trunc_sorter[i][1]),
N + 1, 1);
7899 std::vector<std::vector<T> > eigenval_trunc_sorter2;
7900 eigenval_trunc_sorter2.resize(c * (
N + 1) - MPcount_sum);
7901 for (
int i = MPcount_sum; i < c * (
N + 1); i++) {
7902 eigenval_trunc_sorter2[i - MPcount_sum].resize(2);
7903 eigenval_trunc_sorter2[i - MPcount_sum][0] =
7904 sorter[int(eigenval_trunc_sorter[i][1])].minVal;
7905 eigenval_trunc_sorter2[i - MPcount_sum][1] =
7906 eigenval_trunc_sorter[i][1];
7908 std::sort(eigenval_trunc_sorter2.begin(), eigenval_trunc_sorter2.end());
7909 for (
int i = MPcount_sum; i < num_vals; i++) {
7911 int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
7913 alpha_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
7914 beta[i] = beta_temp(
int(eigenval_trunc_sorter2[i - MPcount_sum][1]), 0);
7916 for (
int j = 0; j < c; j++) {
7917 int n = Dis.highest_each_column[j];
7919 temp_vec.resize(
N + 1 + n, 1);
7920 for (
int i = MPcount_sum; i < num_vals; i++) {
7921 eigenvectors(j,i) = evecMat_master.block(
7922 j * (
N + 1),
int(eigenval_trunc_sorter2[i - MPcount_sum][1]),
7953 template <
class T>
class MatGen {
7958 std::vector<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
7960 std::vector<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
7962 std::vector<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
7976 for (
int i = 0; i < n + 1; i++) {
7977 mats[i].resize(
N + 1 + 2 * n,
N + 1 + 2 * n);
7978 mats[i].setConstant( 0.0);
7980 mats[0].block(0, 0,
N + 1,
N + 1) =
7981 Eigen::Matrix<T, Eigen::Dynamic,
7982 Eigen::Dynamic>::Identity(
N + 1,
N + 1);
7983 for (
int i = 1; i < n + 1; i++) {
7984 mats[i].row(0) = 0.5 *
mats[i - 1].row(1);
7985 for (
int j = 1; j <
N + 2 * n; j++) {
7987 (
mats[i - 1].row(j - 1) -
mats[i - 1].row(j + 1)) / (2.0 * j);
7992 for (
int i = 0; i < n; i++) {
7998 for (
int i = n - 2; i > -1; i--) {
7999 for (
int j = 0; j < n; j++) {
8004 mats2.resize(n + 1);
8005 for (
int i = 0; i < n + 1; i++) {
8006 mats2[i].resize(
N + 1,
N + 1 + n);
8007 mats2[i].setConstant( 0.0);
8009 for (
int i = 0; i < n + 1; i++) {
8010 mats2[i].block(0, 0,
N + 1,
N + 1) =
mats[i].block(0, 0,
N + 1,
N + 1);
8012 for (
int i = 0; i < n; i++) {
8034 std::vector<Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
8036 std::vector<Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
8038 std::vector<Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
8052 for (
int i = 0; i < n + 1; i++) {
8053 mats[i].resize(
N + 1 + 2 * n,
N + 1 + 2 * n);
8054 mats[i].setConstant(std::complex<T>(0.0, 0.0));
8056 mats[0].block(0, 0,
N + 1,
N + 1) =
8057 Eigen::Matrix<std::complex<T>, Eigen::Dynamic,
8058 Eigen::Dynamic>::Identity(
N + 1,
N + 1);
8059 for (
int i = 1; i < n + 1; i++) {
8060 mats[i].row(0) = 0.5 *
mats[i - 1].row(1);
8061 for (
int j = 1; j <
N + 2 * n; j++) {
8063 (
mats[i - 1].row(j - 1) -
mats[i - 1].row(j + 1)) / (2.0 * j);
8069 for (
int i = 0; i < n; i++) {
8071 con_mats[i].setConstant(std::complex<T>(0.0, 0.0));
8075 for (
int i = n - 2; i > -1; i--) {
8076 for (
int j = 0; j < n; j++) {
8081 mats2.resize(n + 1);
8082 for (
int i = 0; i < n + 1; i++) {
8083 mats2[i].resize(
N + 1,
N + 1 + n);
8084 mats2[i].setConstant(std::complex<T>(0.0, 0.0));
8086 for (
int i = 0; i < n + 1; i++) {
8087 mats2[i].block(0, 0,
N + 1,
N + 1) =
mats[i].block(0, 0,
N + 1,
N + 1);
8089 for (
int i = 0; i < n; i++) {
8105 template <
class T>
class LinopMat {
8159 for (
int i = 0; i <
r *
c; i++) {
8170 for (
int i = 0; i <
r *
c; i++) {
8255 if (b.c >
c || b.r >
r) {
8256 std::cout <<
"Incompatible shape to input LinopMat." 8257 <<
" In" << __LINE__ <<
'\n';
8260 for (
int i = 0; i < b.r; i++) {
8261 for (
int j = 0; j < b.c; j++) {
8286 for (
int i = 0; i < b.r; i++) {
8287 for (
int j = 0; j < b.c; j++) {
8301 for (
int i = 0; i < b.r; i++) {
8302 for (
int j = 0; j < b.c; j++) {
8328 for (
int i = 0; i <
r; i++) {
8329 for (
int j = 0; j <
c; j++) {
8330 temp(i, j) =
conj(
operator()(j, i));
8338 for (
int i = 0; i <
r; i++) {
8339 for (
int j = 0; j <
c; j++) {
8348 std::cout <<
"setIdentity() is only for square LinopMats" <<
'\n';
8352 for (
int i = 0; i <
r; i++) {
8411 for (
int i = 0; i <
r *
c; i++) {
8422 for (
int i = 0; i <
r *
c; i++) {
8432 for (
int i = 0; i <
r *
c; i++) {
8443 for (
int i = 0; i <
r *
c; i++) {
8480 std::cout <<
"Incompatible shapes in applying LinopMat to ChebfunMat." 8481 <<
"In line "<< __LINE__ <<
". Exiting "<<
'\n';
8484 for (
int i = 0 ; i < out.
r; i++){
8485 for (
int j = 0; j < out.
c; j++){
8486 out(i,j).v = std::complex<T>(0.0,0.0);
8489 for (
int i = 0; i <
r; i++) {
8490 for (
int j = 0; j < in.c; j++) {
8491 for (
int k = 0; k <
c; k++) {
8492 out(i, j) = out(i, j) + (
operator()(i, k) (in(k, j)));
8502 operator<<(Eigen::Array<std::complex<T>, Eigen::Dynamic, 1> b) {
8570 Eigen::Array<std::complex<T>, Eigen::Dynamic, 1> b) {
8609 for (
int i = 0; i <
r; i++) {
8610 for (
int j = 0; j <
c; j++) {
8618 for (
int i = 0; i <
r; i++) {
8619 for (
int j = 0; j <
c; j++) {
8628 std::cout <<
"setIdentity() is only for square LinopMats" <<
'\n';
8632 for (
int i = 0; i <
r; i++) {
8644 if (b.c >
c || b.r >
r) {
8645 std::cout <<
"Incompatible shape to input LinopMat." 8646 <<
" In" << __LINE__ <<
'\n';
8649 for (
int i = 0; i < b.r; i++) {
8650 for (
int j = 0; j < b.c; j++) {
8676 for (
int i = 0; i < b.r; i++) {
8677 for (
int j = 0; j < b.c; j++) {
8691 for (
int i = 0; i < b.r; i++) {
8692 for (
int j = 0; j < b.c; j++) {
8720 if (b.c >
c || b.r >
r) {
8721 std::cout <<
"Incompatible shape to input LinopMat." 8722 <<
" In" << __LINE__ <<
'\n';
8725 for (
int i = 0; i < b.r; i++) {
8726 for (
int j = 0; j < b.c; j++) {
8751 for (
int i = 0; i < b.r; i++) {
8752 for (
int j = 0; j < b.c; j++) {
8766 for (
int i = 0; i < b.r; i++) {
8767 for (
int j = 0; j < b.c; j++) {
8793 for (
int i = 0; i <
r; i++) {
8794 for (
int j = 0; j <
c; j++) {
8795 temp(i, j) =
conj(
operator()(j, i));
8817 template <
class T>
class BcMat {
8832 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
eval;
8833 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
vals;
8842 eval.resize(m_, n_);
8845 eval.setConstant(0.0);
8846 vals.setConstant(0.0);
8851 eval.resize(m_, n_);
8853 eval.setConstant(0.0);
8854 vals.setConstant(0.0);
8878 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
operator()(
int i,
int j,
8881 Eigen::Matrix<T, 1, Eigen::Dynamic>
vals(1,
N + 1 + 2 * n), valcons(n);
8882 for (
int k = 0; k <
N + 1 + 2 * n; k++) {
8883 vals[k] = cos(k * acos(
eval(i, j)));
8885 for (
int k = 0; k < n; k++) {
8886 valcons[k] = cos(k * acos(
eval(i, j)));
8892 Eigen::Matrix<T, 1, Eigen::Dynamic> out(1,
N + 1 + n);
8893 out.setConstant(0.0);
8894 int diffn = n -
L(i, j).n;
8895 for (
int k = 0; k <
L(i, j).n + 1; k++) {
8896 if (
L(i, j).NCC == 0) {
8898 out.block(0, 0, 1,
N + 1) +=
8899 (
L(i, j).coef[k] *
vals * Mat.
mats[k + diffn]).head(
N + 1);
8900 if (k + diffn - 1 > -1) {
8901 out.block(0,
N + 1, 1, n) +=
8902 (
L(i, j).coef[k] * valcons * Mat.
con_mats[k + diffn - 1]);
8905 out.block(0, 0, 1,
N + 1) +=
8906 (
L(i, j).coefFun[k](
eval(i, j)) *
vals * Mat.
mats[k + diffn])
8908 if (k + diffn - 1 > -1) {
8909 out.block(0,
N + 1, 1, n) += (
L(i, j).coefFun[k](
eval(i, j)) *
8910 valcons * Mat.
con_mats[k + diffn - 1]);
8933 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
eval;
8934 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
vals;
8942 eval.resize(m_, n_);
8951 eval.resize(m_, n_);
8978 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
8982 Eigen::Matrix<T, 1, Eigen::Dynamic>
vals(1,
N + 1 + 2 * n), valcons(n);
8983 for (
int k = 0; k <
N + 1 + 2 * n; k++) {
8984 vals[k] = cos(T(k) * acos(
eval(i, j)));
8986 for (
int k = 0; k < n; k++) {
8987 valcons[k] = cos(T(k) * acos(
eval(i, j)));
9000 Eigen::Matrix<std::complex<T>, 1, Eigen::Dynamic> out(1,
N + 1 + n);
9001 out.setConstant(0.0);
9002 int diffn = n -
L(i, j).n;
9003 for (
int k = 0; k <
L(i, j).n + 1; k++) {
9004 if (
L(i, j).NCC == 0) {
9012 out.block(0, 0, 1,
N + 1) +=
9013 (
L(i, j).coef[k] *
vals * Mat.
mats[k + diffn]).head(
N + 1);
9017 if (k + diffn - 1 > -1) {
9018 out.block(0,
N + 1, 1, n) +=
9019 (
L(i, j).coef[k] * valcons * Mat.
con_mats[k + diffn - 1]);
9022 out.block(0, 0, 1,
N + 1) +=
9023 (
L(i, j).coefFun[k](
eval(i, j)) *
vals * Mat.
mats[k + diffn])
9025 if (k + diffn - 1 > -1) {
9026 out.block(0,
N + 1, 1, n) += (
L(i, j).coefFun[k](
eval(i, j)) *
9027 valcons * Mat.
con_mats[k + diffn - 1]);
9044 if (k == 0 || k == n) {
9049 return nCk_(n - 1, k - 1) +
nCk_(n - 1, k);
9062 if (k == 0 || k == n) {
9067 return nCk_(n - 1, k - 1) +
nCk_(n - 1, k);
9075 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
9078 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> outmat(r * Amat[0].r,
9080 outmat.setConstant(0.0);
9082 for (
int i = 0; i < r; i++) {
9083 for (
int j = 0; j < c; j++) {
9084 for (
int l = 0; l < Amat[i * c + j].r; l++) {
9085 for (
int m = 0; m < Amat[i * c + j].c; m++) {
9086 outmat(i * Amat[i * c + j].r + l, j * Amat[i * c + j].c + m) =
9087 Amat[i * c + j](l, m)(a);
9104 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
9107 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> outmat(
9108 r * Amat[0].r, r * Amat[0].r);
9109 outmat.setConstant(0.0);
9111 for (
int i = 0; i < r; i++) {
9112 for (
int j = 0; j < c; j++) {
9113 for (
int l = 0; l < Amat[i * c + j].r; l++) {
9114 for (
int m = 0; m < Amat[i * c + j].c; m++) {
9115 outmat(i * Amat[i * c + j].r + l, j * Amat[i * c + j].c + m) =
9116 Amat[i * c + j](l, m)(a);
9134 class SingularValueDecomposition :
public GeneralizedEigenSolver<T> {
9140 const BcMat<T> &Rbc_,
int num_vals) {
9180 BcMat<T> BcComp(Lbc.m + Rbc.m + Bc_adjoint.m, 2 * A.r);
9181 LinopMat<T> Z1(Lbc.m, Astar.c), Z2(Rbc.m, Astar.c), Z3(Bc_adjoint.m, A.c);
9182 Z1.setConstant(0.0);
9183 Z2.setConstant(0.0);
9184 Z3.setConstant(0.0);
9187 for (
int i = 0; i < Lbc.m; i++) {
9188 for (
int j = 0; j < Lbc.n; j++) {
9189 Lbc.eval(i, j) = -1.0;
9192 for (
int i = 0; i < Rbc.m; i++) {
9193 for (
int j = 0; j < Rbc.n; j++) {
9194 Rbc.eval(i, j) = 1.0;
9207 BcComp.L << Lbc.L, Z1,
9211 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> z1(Lbc.m, Astar.c),
9212 z2(Rbc.m, Astar.c), z3(Bc_adjoint.m, A.c);
9213 z1.setConstant(0.0);
9214 z2.setConstant(0.0);
9215 z3.setConstant(0.0);
9216 BcComp.eval << Lbc.eval, z1,
9218 z3, Bc_adjoint.eval;
9247 const BcMat<T> &Rbc_,
int num_vals){
9260 const BcMat<T> &Rbc_,
int num_vals){
9276 std::vector<int> highest_each_columnL;
9277 highest_each_columnL.
resize(c);
9278 std::vector<int> temp_vec_int;
9279 temp_vec_int.resize(r);
9280 std::vector<int> alphaSize;
9281 int total_of_all_orders = 0;
9284 for (
int j = 0; j < c; j++) {
9285 for (
int i = 0; i < r; i++) {
9286 temp_vec_int[i] = Lmat(i, j).n;
9288 highest_each_columnL[j] =
9289 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
9292 for (
int i = 0; i < c; i++) {
9293 total_of_all_orders += highest_each_columnL[i];
9295 int n = *std::max_element(highest_each_columnL.begin(),
9296 highest_each_columnL.end());
9300 std::valarray<ChebfunMat<T> > alphais;
9301 std::valarray<ChebfunMat<T> > betais;
9302 outLmat.resize(Lmat.c, Lmat.r);
9303 alphais.resize(n + 1);
9304 betais.resize(n + 1);
9305 int outer_counter = 0;
9307 for (
int k = 0; k < n + 1; k++) {
9308 alphais[k].resize(Lmat.r, Lmat.c);
9309 alphais[k].setConstant(0.0);
9310 for (
int i = 0; i < Lmat.r; i++) {
9311 for (
int j = 0; j < Lmat.c; j++) {
9312 if (Lmat(i, j).n - k >= 0) {
9313 if (Lmat(i, j).NCC == 0) {
9314 alphais[k](i, j) = Lmat(i, j).coef[Lmat(i, j).n - k];
9317 alphais[k](i, j) = Lmat(i, j).coefFun[Lmat(i, j).n - k];
9329 std::cout <<
"in " << __LINE__ <<
'\n';
9330 for (
int k = 0; k < alphais.size(); k++) {
9331 for (
int i = 0; i < 2; i++) {
9332 for (
int j = 0; j < 2; j++) {
9333 std::cout << alphais[k](i, j) <<
'\n';
9334 std::cout <<
"(" << i <<
"," << j <<
")" <<
'\n';
9335 std::cout <<
"k: " << k <<
'\n';
9345 for (
int i = 0; i < n + 1; i++) {
9346 betais[i].resize(Lmat.r, Lmat.c);
9347 betais[i].setConstant(0.0);
9348 for (
int j = i; j < n + 1; j++) {
9350 betais[i] + (
pow(-1, j) * nck(j, i) *
diff(alphais[i], j - i));
9361 for (
int i = 0; i < n + 1; i++) {
9362 betais[i] = betais[i].cTranspose();
9366 std::cout <<
"in " << __LINE__ <<
'\n';
9367 for (
int k = 0; k < betais.size(); k++) {
9368 for (
int i = 0; i < 2; i++) {
9369 for (
int j = 0; j < 2; j++) {
9370 std::cout << betais[k](i, j) <<
'\n';
9371 std::cout <<
"(" << i <<
"," << j <<
")" <<
'\n';
9372 std::cout <<
"k: " << k <<
'\n';
9381 for (
int i = 0; i < Lmat.c; i++) {
9382 for (
int j = 0; j < Lmat.r; j++) {
9383 outLmat(i, j).ncc(n);
9384 for (
int k = 0; k < n + 1; k++) {
9385 outLmat(i, j).coefFun[n - k] = betais[k](i, j);
9416 std::vector<int> highest_each_columnL;
9417 highest_each_columnL.resize(c);
9418 std::vector<int> temp_vec_int;
9419 temp_vec_int.resize(r);
9420 std::vector<int> alphaSize;
9421 int total_of_all_orders = 0;
9425 for (
int j = 0; j < c; j++) {
9426 for (
int i = 0; i < r; i++) {
9427 temp_vec_int[i] = Lmat(i, j).n;
9429 highest_each_columnL[j] =
9430 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
9433 for (
int i = 0; i < c; i++) {
9434 total_of_all_orders += highest_each_columnL[i];
9436 int n = *std::max_element(highest_each_columnL.begin(),
9437 highest_each_columnL.end());
9440 std::valarray<ChebfunMat<T> > alphais;
9441 std::valarray<ChebfunMat<T> > betais;
9442 alphais.resize(n + 1);
9443 betais.resize(n + 1);
9444 int outer_counter = 0;
9446 for (
int k = 0; k < n + 1; k++) {
9447 alphais[k].resize(Lmat.r, Lmat.c);
9448 alphais[k].setConstant(0.0);
9449 for (
int i = 0; i < Lmat.r; i++) {
9450 for (
int j = 0; j < Lmat.c; j++) {
9451 if (Lmat(i, j).n - k >= 0) {
9452 if (Lmat(i, j).NCC == 0) {
9453 alphais[k](i, j) = Lmat(i, j).coef[Lmat(i, j).n - k];
9455 alphais[k](i, j) = Lmat(i, j).coefFun[Lmat(i, j).n - k];
9465 std::valarray<ChebfunMat<T> > Amat;
9467 for (
int i = 0; i < n * n; i++) {
9468 Amat[i].resize(Lmat.r, Lmat.c);
9469 Amat[i].setConstant(0.0);
9473 for (
int i = 0; i < n; i++) {
9474 for (
int j = 0; j < n - i; j++) {
9475 for (
int k = i; k < n - j; k++) {
9476 Amat[i * n + j] = Amat[i * n + j] + (
pow(-1, k) * nck(k, i) *
9477 diff(alphais[k + j + 1], k - i));
9481 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> Aplus(n * r, n * r),
9482 Aminus(n * r, n * r);
9484 Aplus =
feval2D(Amat, n, n, 1.0);
9485 Aminus =
feval2D(Amat, n, n, -1.0);
9490 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> Blbc(Lbc.m, n * Lbc.n),
9491 Brbc(Rbc.m, n * Rbc.n);
9492 Blbc.setConstant(0.0);
9493 Brbc.setConstant(0.0);
9495 for (
int k = 0; k < n + 1; k++) {
9496 for (
int i = 0; i < Lbc.m; i++) {
9497 for (
int j = 0; j < Lbc.n; j++) {
9498 if (Lbc.L(i, j).n - k >= 0) {
9499 if (Lbc.L(i, j).NCC == 0) {
9502 Blbc(i, Lbc.n * k + j) = Lbc.L(i, j).coef[Lbc.L(i, j).n - k];
9506 std::cout <<
"boundary conditions cannot have non-constant" 9507 <<
"coefficients" <<
'\n';
9514 for (
int k = 0; k < n + 1; k++) {
9515 for (
int i = 0; i < Rbc.m; i++) {
9516 for (
int j = 0; j < Rbc.n; j++) {
9517 if (Rbc.L(i, j).n - k >= 0) {
9518 if (Rbc.L(i, j).NCC == 0) {
9519 Brbc(i, Rbc.n * k + j) = Rbc.L(i, j).coef[Rbc.L(i, j).n - k];
9524 std::cout <<
"boundary conditions cannot have non-constant" 9525 <<
"coefficients" <<
'\n';
9533 Eigen::CompleteOrthogonalDecomposition<
9534 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
9537 if (cod.rank() != Blbc.rows()) {
9538 std::cout <<
"the bounndary conditions are not linearly independent." 9539 <<
"Exiting ..." <<
'\n';
9557 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> V =
9558 cod.matrixZ().adjoint();
9559 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> Null_space =
9560 V.block(0, cod.rank(), V.rows(), V.cols() - cod.rank());
9561 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> P = cod.colsPermutation();
9562 Null_space = P * Null_space;
9565 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> solutionL(
9566 Null_space.rows(), Null_space.cols());
9570 solutionL = Null_space;
9574 if (cod.rank() != Brbc.rows()) {
9575 std::cout <<
"the bounndary conditions are not linearly independent." 9576 <<
"Exiting ..." <<
'\n';
9584 V = cod.matrixZ().adjoint();
9586 Null_space = V.block(0, cod.rank(), V.rows(), V.cols() - cod.rank());
9588 P = cod.colsPermutation();
9590 Null_space = P * Null_space;
9593 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> solutionR(
9594 Null_space.rows(), Null_space.cols());
9598 solutionR = Null_space;
9600 solutionL.adjointInPlace();
9601 Aminus.adjointInPlace();
9602 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> lbc = solutionL * Aminus;
9604 solutionR.adjointInPlace();
9605 Aplus.adjointInPlace();
9606 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> rbc = solutionR * Aplus;
9610 out.resize(lbc.rows() + rbc.rows(), Lmat.r);
9614 for (
int i = 0; i < lbc.rows(); i++) {
9615 for (
int j = 0; j < Lmat.c; j++) {
9616 out.L(i, j).set(n - 1);
9617 out.eval(i, j) = -1.0;
9618 for (
int k = 0; k < n; k++) {
9619 out.L(i, j).coef[n - k - 1] = lbc(i, Lmat.c * k + j);
9624 for (
int i = 0; i < rbc.rows(); i++) {
9625 for (
int j = 0; j < Lmat.c; j++) {
9626 out.L(i + lbc.rows(), j).
set(n - 1);
9627 out.eval(i + lbc.rows(), j) = 1.0;
9628 for (
int k = 0; k < n; k++) {
9631 out.L(i + lbc.rows(), j).coef[n - k - 1] = rbc(i, Lmat.c * k + j);
9654 template <
class T>
class Discretize :
public MatGen<T> {
9656 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
P;
9657 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
subs_mat;
9658 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
mat_temp;
9664 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
9669 int r = Lmat.r, c = Lmat.c;
9670 if (Lmat_.c != bc_.n) {
9671 std::cout <<
"The number of comlumns have to be the same in " << __LINE__
9673 std::cout <<
". Exiting..." <<
'\n';
9679 int total_of_all_orders = 0;
9680 int total_boundary_conditions = 0;
9681 std::vector<int> temp_vec_int;
9682 temp_vec_int.resize(r);
9683 for (
int j = 0; j < c; j++) {
9684 for (
int i = 0; i < r; i++) {
9685 temp_vec_int[i] = Lmat(i, j).n;
9688 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
9692 total_boundary_conditions = bc.m;
9697 if (total_of_all_orders != total_boundary_conditions) {
9698 std::cout <<
"The problem is ill-posed, the total of the highest " 9700 "dependent variables has to be equal to the total number of " 9701 "boundary conditions specified." 9703 "Total no. of boundary conditions: " 9704 << total_boundary_conditions
9706 "Total of all orders: " 9707 << total_of_all_orders <<
"\n Exiting ...\n";
9711 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterL(
9712 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
9714 masterL.setConstant(0.0);
9716 subs_mat.resize(total_boundary_conditions, (
N + 1) * c);
9719 mat_temp.resize(total_boundary_conditions, total_boundary_conditions);
9720 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> constraints(
9721 total_boundary_conditions, c * (
N + 1) + total_of_all_orders);
9723 int row_counter = 0, col_counter = 0;
9724 for (
int i = 0; i < bc.m; i++) {
9725 for (
int j = 0; j < bc.n; j++) {
9726 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> temp =
9728 constraints.block(i, col_counter, 1, temp.cols()) = temp;
9729 col_counter += temp.cols();
9734 Eigen::ColPivHouseholderQR<
9735 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
9737 qr.compute(constraints);
9738 if (qr.rank() != constraints.rows()) {
9739 std::cout <<
"The boundary conditions supplied are not " 9740 <<
" linearly independent." <<
'\n';
9741 std::cout <<
"qr.rank = " << qr.rank()
9742 <<
", no. bcs: " << total_boundary_conditions <<
". Exiting ..." 9747 P = qr.colsPermutation();
9749 constraints = constraints *
P;
9750 mat_temp = constraints.block(0, 0, constraints.rows(), constraints.rows());
9752 Eigen::ColPivHouseholderQR<
9753 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >
9756 constraints.block(0, constraints.rows(), constraints.rows(),
9757 constraints.cols() - constraints.rows());
9761 int master_row_counter = 0;
9762 int master_col_counter = 0;
9763 for (
int j = 0; j < c; j++) {
9766 for (
int i = 0; i < r; i++) {
9767 int diffn = n - Lmat(i, j).n;
9768 if (Lmat(i, j).NCC == 0) {
9769 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
9770 masterL.block(master_row_counter, master_col_counter,
N + 1,
9772 Lmat(i, j).coef[k] *
9776 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
9777 masterL.block(master_row_counter, master_col_counter,
N + 1,
9779 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
9783 master_row_counter +=
N + 1;
9785 master_row_counter = 0;
9786 master_col_counter +=
N + 1 + n;
9790 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterL2;
9791 masterL = masterL *
P;
9793 masterL.block(0, constraints.rows(), c * (
N + 1), c * (
N + 1)) +
9794 (masterL.block(0, 0, c * (
N + 1), constraints.rows()) *
subs_mat);
9801 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
9803 int r = Lmat.r, c = Lmat.c;
9804 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterL(
9805 r * (
N + 1), c * (
N + 1) +
num_bc);
9807 masterL.setConstant(0.0);
9809 int row_counter = 0;
9810 int col_counter = 0;
9811 int master_row_counter = 0;
9812 int master_col_counter = 0;
9814 for (
int j = 0; j < c; j++) {
9817 for (
int i = 0; i < r; i++) {
9818 int diffn = n - Lmat(i, j).n;
9819 if (Lmat(i, j).NCC == 0) {
9820 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
9821 masterL.block(master_row_counter, master_col_counter,
N + 1,
9823 Lmat(i, j).coef[k] *
9827 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
9828 masterL.block(master_row_counter, master_col_counter,
N + 1,
9830 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
9834 master_row_counter +=
N + 1;
9836 master_row_counter = 0;
9837 master_col_counter +=
N + 1 + n;
9841 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> masterL2;
9842 masterL = masterL *
P;
9843 masterL2 = masterL.block(0,
num_bc, c * (
N + 1), c * (
N + 1)) +
9857 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
P;
9858 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
subs_mat;
9860 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
A1;
9861 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
invmat_temp;
9871 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
9873 const BcMat<std::complex<T> > &bc_) {
9877 int r = Lmat.r, c = Lmat.c;
9878 if (Lmat_.c != bc_.n) {
9879 std::cout <<
"The number of comlumns have to be the same in " << __LINE__
9881 std::cout <<
". Exiting..." <<
'\n';
9886 int total_of_all_orders = 0;
9887 int total_boundary_conditions = 0;
9888 std::vector<int> temp_vec_int;
9889 temp_vec_int.resize(r);
9890 for (
int j = 0; j < c; j++) {
9891 for (
int i = 0; i < r; i++) {
9892 temp_vec_int[i] = Lmat(i, j).n;
9895 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
9902 total_boundary_conditions = bc.m;
9907 if (total_of_all_orders != total_boundary_conditions) {
9908 std::cout <<
"The problem is ill-posed, the total of the highest " 9910 "dependent variables has to be equal to the total number of " 9911 "boundary conditions specified." 9913 "Total no. of boundary conditions: " 9914 << total_boundary_conditions
9916 "Total of all orders: " 9917 << total_of_all_orders <<
"\n Exiting ...\n";
9921 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL(
9922 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
9924 masterL.setConstant(0.0);
9926 subs_mat.resize(total_boundary_conditions, (
N + 1) * c);
9928 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
mat_temp;
9929 mat_temp.resize(total_boundary_conditions, total_boundary_conditions);
9930 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> constraints(
9931 total_boundary_conditions, c * (
N + 1) + total_of_all_orders);
9933 int row_counter = 0, col_counter = 0;
9934 for (
int i = 0; i < bc.m; i++) {
9935 for (
int j = 0; j < bc.n; j++) {
9936 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> temp =
9938 constraints.block(i, col_counter, 1, temp.cols()) = temp;
9939 col_counter += temp.cols();
9944 Eigen::ColPivHouseholderQR<
9945 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
9947 qr.compute(constraints);
9948 if (qr.rank() != constraints.rows()) {
9949 std::cout <<
"The boundary conditions supplied are not " 9950 <<
" linearly independent." <<
'\n';
9951 std::cout <<
"qr.rank = " << qr.rank()
9952 <<
", no. bcs: " << total_boundary_conditions <<
". Exiting ..." 9956 P = qr.colsPermutation();
9959 constraints = constraints *
P;
9960 mat_temp = constraints.block(0, 0, constraints.rows(), constraints.rows());
9962 Eigen::ColPivHouseholderQR<
9963 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
9966 constraints.block(0, constraints.rows(), constraints.rows(),
9967 constraints.cols() - constraints.rows());
9968 invmat_temp = consSolver.inverse();
9971 int master_row_counter = 0;
9972 int master_col_counter = 0;
9973 for (
int j = 0; j < c; j++) {
9976 for (
int i = 0; i < r; i++) {
9977 int diffn = n - Lmat(i, j).n;
9978 if (Lmat(i, j).NCC == 0) {
9979 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
9980 masterL.block(master_row_counter, master_col_counter,
N + 1,
9982 Lmat(i, j).coef[k] *
9987 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
9988 masterL.block(master_row_counter, master_col_counter,
N + 1,
9990 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
9995 master_row_counter +=
N + 1;
9997 master_row_counter = 0;
9998 master_col_counter +=
N + 1 + n;
10002 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL2;
10003 masterL = masterL *
P;
10005 masterL.block(0, constraints.rows(), c * (
N + 1), c * (
N + 1)) +
10006 (masterL.block(0, 0, c * (
N + 1), constraints.rows()) *
subs_mat);
10009 A1 = masterL.block(0, 0, c * (
N + 1), constraints.rows());
10016 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
10019 int r = Lmat.r, c = Lmat.c;
10021 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL(
10022 r * (
N + 1), c * (
N + 1) +
num_bc);
10023 masterL.setConstant(0.0);
10024 int row_counter = 0;
10025 int col_counter = 0;
10026 int master_row_counter = 0;
10027 int master_col_counter = 0;
10028 for (
int j = 0; j < c; j++) {
10031 for (
int i = 0; i < r; i++) {
10032 int diffn = n - Lmat(i, j).n;
10033 if (Lmat(i, j).NCC == 0) {
10034 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
10035 masterL.block(master_row_counter, master_col_counter,
N + 1,
10037 Lmat(i, j).coef[k] *
10042 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
10043 masterL.block(master_row_counter, master_col_counter,
N + 1,
10045 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
10050 master_row_counter +=
N + 1;
10052 master_row_counter = 0;
10053 master_col_counter +=
N + 1 + n;
10057 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL2;
10058 masterL = masterL *
P;
10059 masterL2 = masterL.block(0,
num_bc, r * (
N + 1), c * (
N + 1)) +
10065 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
10069 int r = Lmat.r, c = Lmat.c;
10072 int total_of_all_orders = 0;
10073 int total_boundary_conditions = 0;
10074 std::vector<int> temp_vec_int;
10075 temp_vec_int.resize(r);
10076 for (
int j = 0; j < c; j++) {
10077 for (
int i = 0; i < r; i++) {
10078 temp_vec_int[i] = Lmat(i, j).n;
10081 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
10088 std::vector<Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
10090 diffMats.resize(n + 1);
10092 for (
int i = 0; i < n + 1; i++) {
10093 diffMats[i].resize(
N + 1,
N + 1);
10096 diffMats[0] = Eigen::Matrix<std::complex<T>, Eigen::Dynamic,
10097 Eigen::Dynamic>::Identity(
N + 1,
N + 1);
10098 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> Dmat(
N + 1,
10100 masterL(r * (
N + 1), c * (
N + 1)), temp;
10102 Dmat.setConstant(0.0);
10103 masterL.setConstant(0.0);
10104 for (
int k = 0; k <
N + 1; k++) {
10105 for (
int p = k + 1; p <
N + 1; p++) {
10111 std::valarray<T>
y(
N + 1), y1(
N + 1);
10119 for (
int i = 1; i < n + 1; i++) {
10120 diffMats[i] = 2.0 * Dmat * diffMats[i - 1];
10126 int master_row_counter = 0;
10127 int master_col_counter = 0;
10128 for (
int j = 0; j < c; j++) {
10130 for (
int i = 0; i < r; i++) {
10131 int diffn = n - Lmat(i, j).n;
10132 if (Lmat(i, j).NCC == 0) {
10133 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
10134 masterL.block(master_row_counter, master_col_counter,
N + 1,
10136 Lmat(i, j).coef[Lmat(i, j).n - k] * (diffMats[k]);
10139 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
10140 masterL.block(master_row_counter, master_col_counter,
N + 1,
10142 Lmat(i, j).coefFun[Lmat(i, j).n - k].MultMat().block(
10143 0, 0,
N + 1,
N + 1) *
10147 master_row_counter +=
N + 1;
10149 master_row_counter = 0;
10150 master_col_counter +=
N + 1;
10159 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
10161 const BcMat<std::complex<T> > &bc_) {
10165 int r = Lmat.r, c = Lmat.c;
10166 if (Lmat_.c != bc_.n) {
10167 std::cout <<
"The number of comlumns have to be the same in " << __LINE__
10169 std::cout <<
". Exiting..." <<
'\n';
10174 int total_of_all_orders = 0;
10175 int total_boundary_conditions = 0;
10176 std::vector<int> temp_vec_int;
10177 temp_vec_int.resize(r);
10178 for (
int j = 0; j < c; j++) {
10179 for (
int i = 0; i < r; i++) {
10180 temp_vec_int[i] = Lmat(i, j).n;
10183 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
10190 total_boundary_conditions = bc.m;
10195 if (total_of_all_orders != total_boundary_conditions) {
10196 std::cout <<
"The problem is ill-posed, the total of the highest " 10198 "dependent variables has to be equal to the total number of " 10199 "boundary conditions specified." 10201 "Total no. of boundary conditions: " 10202 << total_boundary_conditions
10204 "Total of all orders: " 10205 << total_of_all_orders <<
"\n Exiting ...\n";
10209 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL(
10210 r * (
N + 1), c * (
N + 1) + total_boundary_conditions);
10212 masterL.setConstant(0.0);
10214 subs_mat.resize(total_boundary_conditions, (
N + 1) * c);
10216 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
mat_temp;
10217 mat_temp.resize(total_boundary_conditions, total_boundary_conditions);
10218 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> constraints(
10219 total_boundary_conditions, c * (
N + 1) + total_of_all_orders);
10221 int row_counter = 0, col_counter = 0;
10222 for (
int i = 0; i < bc.m; i++) {
10223 for (
int j = 0; j < bc.n; j++) {
10224 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> temp =
10226 constraints.block(i, col_counter, 1, temp.cols()) = temp;
10227 col_counter += temp.cols();
10234 int master_row_counter = 0;
10235 int master_col_counter = 0;
10236 for (
int j = 0; j < c; j++) {
10239 for (
int i = 0; i < r; i++) {
10240 int diffn = n - Lmat(i, j).n;
10241 if (Lmat(i, j).NCC == 0) {
10242 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
10243 masterL.block(master_row_counter, master_col_counter,
N + 1,
10245 Lmat(i, j).coef[k] *
10249 for (
int k = 0; k < Lmat(i, j).n + 1; k++) {
10250 masterL.block(master_row_counter, master_col_counter,
N + 1,
N + 1 + n) +=
10251 Lmat(i, j).coefFun[k].MultMat().block(0, 0,
N + 1,
N + 1) *
10255 master_row_counter +=
N + 1;
10257 master_row_counter = 0;
10258 master_col_counter +=
N + 1 + n;
10262 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> masterL2(
10263 r * (
N + 1) + total_boundary_conditions,
10264 c * (
N + 1) + total_boundary_conditions);
10266 masterL2 << masterL, constraints;
10296 const BcMat<std::complex<T> > &Lbc_,
10297 const BcMat<std::complex<T> > &Rbc_,
int num_vals) {
10308 Z.setConstant(0.0);
10339 Z3(Bc_adjoint.m, A.c);
10340 Z1.setConstant(0.0);
10341 Z2.setConstant(0.0);
10342 Z3.setConstant(0.0);
10344 for (
int i = 0; i < Lbc.m; i++) {
10345 for (
int j = 0; j < Lbc.n; j++) {
10346 Lbc.eval(i, j) = -1.0;
10349 for (
int i = 0; i < Rbc.m; i++) {
10350 for (
int j = 0; j < Rbc.n; j++) {
10351 Rbc.eval(i, j) = 1.0;
10364 BcComp.L << Lbc.L, Z1,
10368 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> z1(Lbc.m, Astar.c),
10369 z2(Rbc.m, Astar.c), z3(Bc_adjoint.m, A.c);
10370 z1.setConstant(0.0);
10371 z2.setConstant(0.0);
10372 z3.setConstant(0.0);
10374 BcComp.eval << Lbc.eval, z1,
10376 z3, Bc_adjoint.eval;
10405 const LinopMat<std::complex<T> > &B_,
10406 const LinopMat<std::complex<T> > &C_,
10407 const BcMat<std::complex<T> > &Lbc_,
10408 const BcMat<std::complex<T> > &Rbc_,
int num_vals) {
10456 Lbc.eval.setConstant(-1.0);
10457 Rbc.eval.setConstant(1.0);
10462 A_bc.eval << Lbc.eval,
10466 BBstar = B * Bstar;
10467 CstarC = Cstar * C;
10471 Mmat(A.r + Astar.r, A.c + Astar.c);
10473 Z3(Astar_bc.m, A_bc.n);
10474 Z1.setConstant(0.0);
10475 Z2.setConstant(0.0);
10476 Z3.setConstant(0.0);
10479 Mmat << Z1, BBstar,
10483 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> z2(A_bc.eval.rows(),
10484 Astar_bc.eval.cols()),
10485 z3(Astar_bc.eval.rows(), A_bc.eval.cols());
10486 z2.setConstant(0.0);
10487 z3.setConstant(0.0);
10488 bcf.L << A_bc.L, Z2,
10490 bcf.eval << A_bc.eval, z2,
10493 Lmat.r * (
N + 1), bcf);
10501 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> A0, A0star,
10502 B0B0star, C0starC0, L, M, invA0, invA0star;
10503 A0 = ADis(A, A_bc);
10504 A0star = AstarDis(Astar, Astar_bc);
10505 B0B0star = AstarDis((BBstar));
10506 C0starC0 = ADis((CstarC));
10507 Eigen::ColPivHouseholderQR<
10508 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
10510 if (!qr.isInvertible()) {
10511 std::cout <<
"Cannot compute the right singular vectors alone." 10512 <<
"Change svd_flag to SIS_SVD. Exiting ... " <<
'\n';
10515 invA0star = qr.inverse();
10517 if (!qr.isInvertible()) {
10518 std::cout <<
"Cannot compute the right singular vectors alone." 10519 <<
"Change svd_flag to SIS_SVD. Exiting ... " <<
'\n';
10522 invA0 = qr.inverse();
10523 L = B0B0star * invA0star * C0starC0;
10525 Eigen::ComplexEigenSolver<
10526 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
10536 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> A0, A0star,
10537 B0B0star, C0starC0, L, M, invA0, invA0star;
10538 A0 = ADis(A, A_bc);
10539 A0star = AstarDis(Astar, Astar_bc);
10540 B0B0star = AstarDis((BBstar));
10541 C0starC0 = ADis((CstarC));
10542 Eigen::ColPivHouseholderQR<
10543 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
10545 if (!qr.isInvertible()) {
10546 std::cout <<
"Cannot compute the right singular vectors alone." 10547 <<
"Change svd_flag to SIS_SVD. Exiting ... " <<
'\n';
10550 invA0star = qr.inverse();
10552 if (!qr.isInvertible()) {
10553 std::cout <<
"Cannot compute the right singular vectors alone." 10554 <<
"Change svd_flag to SIS_SVD. Exiting ... " <<
'\n';
10557 invA0 = qr.inverse();
10558 L = C0starC0 * invA0 * B0B0star;
10560 Eigen::ComplexEigenSolver<
10561 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
10581 const LinopMat<std::complex<T> > &B_,
10582 const LinopMat<std::complex<T> > &C_,
10583 const BcMat<std::complex<T> > &Lbc_,
10584 const BcMat<std::complex<T> > &Rbc_) {
10632 Lbc.eval.setConstant(-1.0);
10633 Rbc.eval.setConstant(1.0);
10638 A_bc.eval << Lbc.eval,
10642 BBstar = B * Bstar;
10643 CstarC = Cstar * C;
10647 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> A0, A0star,
10648 B0B0star, C0starC0, L, M, invA0, invA0star;
10649 A0 = ADis(A, A_bc);
10650 A0star = AstarDis(Astar, Astar_bc);
10651 B0B0star = AstarDis((BBstar));
10652 C0starC0 = ADis((CstarC));
10653 Eigen::ColPivHouseholderQR<
10654 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
10656 if (!qr.isInvertible()) {
10657 std::cout <<
"Cannot compute the right singular vectors alone." 10658 <<
"Change svd_flag to SIS_SVD. Exiting ... "<< __LINE__ <<
'\n';
10661 invA0 = qr.inverse();
10662 qr.compute(A0star);
10663 if (!qr.isInvertible()) {
10664 std::cout <<
"Cannot compute the right singular vectors alone." 10665 <<
"Change svd_flag to SIS_SVD. Exiting ... " << __LINE__<<
'\n';
10669 invA0star = qr.inverse();
10670 L = invA0 * B0B0star * invA0star * C0starC0;
10671 std::complex<T> tempc = L.trace();
10677 const LinopMat<std::complex<T> > &B_,
10678 const LinopMat<std::complex<T> > &C_,
10679 const BcMat<std::complex<T> > &Lbc_,
10680 const BcMat<std::complex<T> > &Rbc_,
10681 const BcMat<std::complex<T> > &Lbc_adjoint_,
10682 const BcMat<std::complex<T> > &Rbc_adjoint_) {
10731 BcMat<std::complex<T> > A_bc(Lbc.m + Rbc.m, Lbc.n), Astar_bc(Lbc_adjoint.m + Rbc_adjoint.m, Lbc_adjoint.n);
10732 Lbc.eval.setConstant(-1.0);
10733 Rbc.eval.setConstant(1.0);
10738 A_bc.eval << Lbc.eval,
10741 Astar_bc.L << Lbc_adjoint.L,
10743 Astar_bc.eval << Lbc_adjoint.eval,
10747 BBstar = B * Bstar;
10748 CstarC = Cstar * C;
10752 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> A0, A0star,
10753 B0B0star, C0starC0, L, M, invA0, invA0star;
10754 A0 = ADis(A, A_bc);
10755 A0star = AstarDis(Astar, Astar_bc);
10756 B0B0star = AstarDis((BBstar));
10757 C0starC0 = ADis((CstarC));
10758 Eigen::ColPivHouseholderQR<
10759 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
10761 if (!qr.isInvertible()) {
10762 std::cout <<
"Cannot compute the right singular vectors alone." 10763 <<
"Change svd_flag to SIS_SVD. Exiting ... "<< __LINE__ <<
'\n';
10766 invA0 = qr.inverse();
10767 qr.compute(A0star);
10768 if (!qr.isInvertible()) {
10769 std::cout <<
"Cannot compute the right singular vectors alone." 10770 <<
"Change svd_flag to SIS_SVD. Exiting ... " << __LINE__<<
'\n';
10774 invA0star = qr.inverse();
10775 L = invA0 * B0B0star * invA0star * C0starC0;
10776 std::complex<T> tempc = L.trace();
10782 const LinopMat<std::complex<T> > &B_,
10783 const LinopMat<std::complex<T> > &C1_,
10784 const LinopMat<std::complex<T> > &C2_,
10785 const LinopMat<std::complex<T> > &C3_,
10786 const BcMat<std::complex<T> > &Lbc_,
10787 const BcMat<std::complex<T> > &Rbc_) {
10840 Lbc.eval.setConstant(-1.0);
10841 Rbc.eval.setConstant(1.0);
10846 A_bc.eval << Lbc.eval,
10850 BBstar = B * Bstar;
10852 CstarC1 = Cstar1 * C1;
10853 CstarC2 = Cstar2 * C2;
10854 CstarC3 = Cstar3 * C3;
10858 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> A0, A0star,
10859 B0B0star, C0starC0,C0starC01,C0starC02,C0starC03, L, M, invA0, invA0star;
10860 A0 = ADis(A, A_bc);
10861 A0star = AstarDis(Astar, Astar_bc);
10862 B0B0star = AstarDis((BBstar));
10864 C0starC01 = ADis((CstarC1));
10865 C0starC02 = ADis((CstarC2));
10866 C0starC03 = ADis((CstarC3));
10868 Eigen::ColPivHouseholderQR<
10869 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
10871 if (!qr.isInvertible()) {
10872 std::cout <<
"Cannot compute the right singular vectors alone." 10873 <<
"Change svd_flag to SIS_SVD. Exiting ... " <<
'\n';
10876 invA0star = qr.inverse();
10878 if (!qr.isInvertible()) {
10879 std::cout <<
"Cannot compute the right singular vectors alone." 10880 <<
"Change svd_flag to SIS_SVD. Exiting ... " <<
'\n';
10884 invA0 = qr.inverse();
10885 L = invA0 * B0B0star * invA0star;
10886 std::valarray<std::complex<T> > tempc(3);
10887 tempc[0] = (L*C0starC01).trace();
10888 tempc[1] = (L*C0starC02).trace();
10889 tempc[2] = (L*C0starC03).trace();
10902 const LinopMat<std::complex<T> > &B_,
10903 const LinopMat<std::complex<T> > &C_,
10904 const BcMat<std::complex<T> > &Lbc_,
10905 const BcMat<std::complex<T> > &Rbc_,
10906 const BcMat<std::complex<T> > &Lbc_adjoint_,
10907 const BcMat<std::complex<T> > &Rbc_adjoint_,
int num_vals) {
10958 Lbc.eval.setConstant(-1.0);
10959 Rbc.eval.setConstant(1.0);
10961 Lbc_adjoint.eval.setConstant(-1.0);
10962 Rbc_adjoint.eval.setConstant(1.0);
10966 Astar_bc.L << Lbc_adjoint.L,
10969 A_bc.eval << Lbc.eval,
10971 Astar_bc.eval << Lbc_adjoint.eval,
10975 BBstar = B * Bstar;
10976 CstarC = Cstar * C;
10980 Mmat(A.r + Astar.r, A.c + Astar.c);
10982 Z3(Astar_bc.m, A_bc.n);
10983 Z1.setConstant(0.0);
10984 Z2.setConstant(0.0);
10985 Z3.setConstant(0.0);
10988 Mmat << Z1, BBstar,
10992 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> z2(A_bc.eval.rows(),
10993 Astar_bc.eval.cols()),
10994 z3(Astar_bc.eval.rows(), A_bc.eval.cols());
10995 z2.setConstant(0.0);
10996 z3.setConstant(0.0);
10997 bcf.L << A_bc.L, Z2,
10999 bcf.eval << A_bc.eval, z2,
11002 Lmat.r * (
N + 1), bcf);
11021 std::cout <<
"computing only right singular vectors" <<
'\n';
11023 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> A0, A0star,
11024 B0B0star, C0starC0, L, M, invA0, invA0star;
11025 A0 = ADis(A, A_bc);
11026 A0star = AstarDis(Astar, Astar_bc);
11027 B0B0star = AstarDis((BBstar));
11028 C0starC0 = ADis((CstarC));
11029 Eigen::ColPivHouseholderQR<
11030 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
11032 if (!qr.isInvertible()) {
11033 std::cout <<
"Cannot compute the right singular vectors alone." 11034 <<
"Change svd_flag to SIS_SVD. Exiting ... " <<
'\n';
11037 invA0star = qr.inverse();
11039 L = B0B0star * invA0star * C0starC0;
11048 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> A0, A0star,
11049 B0B0star, C0starC0, L, M, invA0, invA0star;
11050 A0 = ADis(A, A_bc);
11051 A0star = AstarDis(Astar, Astar_bc);
11052 B0B0star = AstarDis((BBstar));
11053 C0starC0 = ADis((CstarC));
11054 Eigen::ColPivHouseholderQR<
11055 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
11058 if (!qr.isInvertible()) {
11059 std::cout <<
"Cannot compute the right singular vectors alone." 11060 <<
"Change svd_flag to SIS_SVD. Exiting ... " <<
'\n';
11063 invA0 = qr.inverse();
11064 L = C0starC0 * invA0 * B0B0star;
11074 #ifdef SIS_USE_FEAST 11075 void feast_compute(
const LinopMat<std::complex<T> > &A_,
11077 const LinopMat<std::complex<T> > &B_,
11078 const LinopMat<std::complex<T> > &C_,
11079 const BcMat<std::complex<T> > &Lbc_,
11080 const BcMat<std::complex<T> > &Rbc_,
11081 const BcMat<std::complex<T> > &Lbc_adjoint_,
11082 const BcMat<std::complex<T> > &Rbc_adjoint_) {
11098 Lbc.eval.setConstant(-1.0);
11099 Rbc.eval.setConstant(1.0);
11101 Lbc_adjoint.eval.setConstant(-1.0);
11102 Rbc_adjoint.eval.setConstant(1.0);
11106 Astar_bc.L << Lbc_adjoint.L,
11109 A_bc.eval << Lbc.eval,
11111 Astar_bc.eval << Lbc_adjoint.eval,
11115 BBstar = B * Bstar;
11116 CstarC = Cstar * C;
11119 Mmat(A.r + Astar.r, A.c + Astar.c);
11121 Z3(Astar_bc.m, A_bc.n);
11122 Z1.setConstant(0.0);
11123 Z2.setConstant(0.0);
11124 Z3.setConstant(0.0);
11127 Mmat << Z1, BBstar,
11131 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> z2(A_bc.eval.rows(),
11132 Astar_bc.eval.cols()),
11133 z3(Astar_bc.eval.rows(), A_bc.eval.cols());
11134 z2.setConstant(0.0);
11135 z3.setConstant(0.0);
11136 bcf.L << A_bc.L, Z2,
11138 bcf.eval << A_bc.eval, z2,
11160 void HinfNorm(
const LinopMat<std::complex<T> > &E_,
11168 const LinopMat<std::complex<T> > &A_,
11169 const LinopMat<std::complex<T> > &B_,
11170 const LinopMat<std::complex<T> > &C_,
11171 const BcMat<std::complex<T> > &Lbc_,
11172 const BcMat<std::complex<T> > &Rbc_,
11173 const BcMat<std::complex<T> > &Lbc_adjoint_,
11174 const BcMat<std::complex<T> > &Rbc_adjoint_) {
11176 double seed = 10.0;
11180 std::complex<T>
ii(0.0, 1.0);
11181 LinopMat<std::complex<T> > E = E_;
11182 LinopMat<std::complex<T> > A = A_;
11183 LinopMat<std::complex<T> > B = B_;
11184 LinopMat<std::complex<T> > C = C_;
11185 BcMat<std::complex<T> > Lbc = Lbc_;
11186 BcMat<std::complex<T> > Rbc = Rbc_;
11187 BcMat<std::complex<T> > Lbc_adjoint = Lbc_adjoint_;
11188 BcMat<std::complex<T> > Rbc_adjoint = Rbc_adjoint_;
11189 LinopMat<std::complex<T> > Estar =
Adjoint(E);
11190 LinopMat<std::complex<T> > Astar =
Adjoint(A);
11191 LinopMat<std::complex<T> > Bstar =
Adjoint(B);
11192 LinopMat<std::complex<T> > Cstar =
Adjoint(C);
11193 LinopMat<std::complex<T> > BBstar = B * Bstar;
11194 LinopMat<std::complex<T> > CstarC = Cstar * C;
11195 LinopMat<std::complex<T> > A2, A2star, HamiltonL, HamiltonM;
11196 BcMat<std::complex<T> > A_bc(Lbc.m + Rbc.m, Lbc.n);
11197 BcMat<std::complex<T> > Astar_bc(Lbc_adjoint.m + Rbc_adjoint.m,
11202 Astar_bc.L << Lbc_adjoint.L,
11205 A_bc.eval << Lbc.eval,
11207 Astar_bc.eval << Lbc_adjoint.eval,
11210 BcMat<std::complex<T> > bcf(A_bc.m + Astar_bc.m, A_bc.n + A_bc.n);
11211 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> z2(A_bc.eval.rows(),
11212 Astar_bc.eval.cols()),
11213 z3(Astar_bc.eval.rows(), A_bc.eval.cols());
11214 z2.setConstant(0.0);
11215 z3.setConstant(0.0);
11216 LinopMat<std::complex<T> > Z1(A.r, A.c), Z2(A_bc.m, Astar_bc.n),
11217 Z3(Astar_bc.m, A_bc.n);
11218 Z1.setConstant(0.0);
11219 Z2.setConstant(0.0);
11220 Z3.setConstant(0.0);
11222 bcf.L << A_bc.L, Z2,
11224 bcf.eval << A_bc.eval, z2,
11227 double gamma_lb, gamma_ub, gamma;
11228 double Hinf_eps = 1e-4;
11230 A2 = (
ii * omega_opt * E) - A;
11231 compute(A2, B, C, Lbc, Rbc, Lbc_adjoint, Rbc_adjoint, A2.r * (
N + 1));
11232 gamma_lb = GeneralizedEigenSolver<std::complex<T> >
::eigenvalues[0].real();
11235 gamma = (1.0 + 2.0 * Hinf_eps) * gamma_lb;
11236 std::cout <<
"gamma : " << gamma <<
'\n';
11244 HamiltonL.resize(2 * A2.r, 2 * A2.c);
11245 HamiltonM.resize(2 * A2.r, 2 * A2.c);
11246 HamiltonL << A, (BBstar / (-gamma * gamma)),
11248 HamiltonM << E, Z1,
11250 GeneralizedEigenSolver<std::complex<T> >
::compute(HamiltonL, HamiltonM,
11251 4 * A.r * (
N + 1), bcf);
11253 GeneralizedEigenSolver<std::complex<T> >::sortByLargestReal();
11254 std::ofstream outf(
"eval_saver.txt");
11256 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> mattemp(
11258 mattemp << GeneralizedEigenSolver<std::complex<T> >::alpha,
11259 GeneralizedEigenSolver<std::complex<T> >::beta;
11261 std::cout <<
"eigenvalues from Hamiltonian: \n" 11264 outf <<
"eigenvalues from Hamiltonian: \n" << mattemp <<
'\n';
11268 std::vector<T> omegas;
11270 i < GeneralizedEigenSolver<std::complex<T> >
::eigenvalues.size();
11274 omegas.push_back(std::abs(
11278 if (omegas.size() == 0) {
11279 A2 = (
ii * omega_opt * E) - A;
11280 int num_vals = A2.r * 2 * (
N + 1);
11281 compute(A2, B, C, Lbc, Rbc, Lbc_adjoint, Rbc_adjoint, num_vals);
11286 std::sort(omegas.begin(), omegas.end());
11287 std::valarray<T> ms;
11288 ms.resize(omegas.size() - 1);
11289 for (
int i = 0; i < omegas.size() - 1; i++) {
11290 ms[i] = (omegas[i] + omegas[i + 1]) / 2.0;
11291 std::cout <<
"ms[" << i <<
"] : " << ms[i] <<
'\n';
11294 std::vector<std::vector<T> > gammas;
11295 gammas.resize(ms.size());
11296 for (
int i = 0; i < ms.size(); i++) {
11298 A2 = (
ii * ms[i] * E) - A;
11299 int num_vals = A2.r * 2 * (
N + 1);
11300 compute(A2, B, C, Lbc, Rbc, Lbc_adjoint, Rbc_adjoint, num_vals);
11302 gammas[i].resize(2);
11306 GeneralizedEigenSolver<std::complex<T> >
::eigenvalues[0].real();
11310 std::sort(gammas.begin(), gammas.end());
11311 std::cout <<
"gamma end: " << gammas[gammas.size() - 1][0] <<
'\n';
11312 std::cout <<
"gamma 0: " << gammas[0][0] <<
'\n';
11314 gamma_lb = gammas[gammas.size() - 1][0];
11315 omega_opt = ms[gammas[gammas.size() - 1][1]];
11316 std::cout <<
"omega_opt = " << omega_opt <<
'\n';
11318 gamma_opt = (gamma_lb + gamma_ub) / 2.0;
11334 std::vector<int> highest_each_columnL;
11335 highest_each_columnL.
resize(c);
11336 std::vector<int> temp_vec_int;
11337 temp_vec_int.resize(r);
11338 std::vector<int> alphaSize;
11339 int total_of_all_orders = 0;
11342 for (
int j = 0; j < c; j++) {
11343 for (
int i = 0; i < r; i++) {
11344 temp_vec_int[i] = Lmat(i, j).n;
11346 highest_each_columnL[j] =
11347 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
11350 for (
int i = 0; i < c; i++) {
11351 total_of_all_orders += highest_each_columnL[i];
11353 int n = *std::max_element(highest_each_columnL.begin(),
11354 highest_each_columnL.end());
11358 std::valarray<ChebfunMat<std::complex<T> > > alphais;
11359 std::valarray<ChebfunMat<std::complex<T> > > betais;
11360 outLmat.resize(Lmat.c, Lmat.r);
11361 alphais.resize(n + 1);
11362 betais.resize(n + 1);
11363 int outer_counter = 0;
11365 for (
int k = 0; k < n + 1; k++) {
11366 alphais[k].resize(Lmat.r, Lmat.c);
11367 alphais[k].setConstant(0.0);
11368 for (
int i = 0; i < Lmat.r; i++) {
11369 for (
int j = 0; j < Lmat.c; j++) {
11370 if (Lmat(i, j).n - k >= 0) {
11371 if (Lmat(i, j).NCC == 0) {
11372 alphais[k](i, j) = Lmat(i, j).coef[Lmat(i, j).n - k];
11375 alphais[k](i, j) = Lmat(i, j).coefFun[Lmat(i, j).n - k];
11403 for (
int i = 0; i < n + 1; i++) {
11404 betais[i].resize(Lmat.r, Lmat.c);
11405 betais[i].setConstant(0.0);
11406 for (
int j = i; j < n + 1; j++) {
11408 betais[i] + (
pow(-1, j) * nck(j, i) *
diff(alphais[j], j - i));
11419 for (
int i = 0; i < n + 1; i++) {
11420 betais[i] = betais[i].cTranspose();
11439 for (
int i = 0; i < Lmat.c; i++) {
11440 for (
int j = 0; j < Lmat.r; j++) {
11441 outLmat(i, j).ncc(n);
11442 for (
int k = 0; k < n + 1; k++) {
11443 outLmat(i, j).coefFun[n - k] = betais[k](i, j);
11461 for (
int i = 0; i < outLmat.r; i++) {
11462 for (
int j = 0; j < outLmat.c; j++) {
11463 tempMat(i, j).ncc(Lmat(j, i).n);
11464 for (
int k = 0; k < Lmat(j, i).n + 1; k++) {
11465 tempMat(i, j).coefFun[Lmat(j, i).n - k] =
11466 outLmat(i, j).coefFun[outLmat(i, j).n - k];
11506 const BcMat<std::complex<T> > &Lbc_,
11507 const BcMat<std::complex<T> > &Rbc_) {
11514 std::vector<int> highest_each_columnL;
11515 highest_each_columnL.resize(c);
11516 std::vector<int> temp_vec_int;
11517 temp_vec_int.resize(r);
11518 std::vector<int> alphaSize;
11519 int total_of_all_orders = 0;
11522 for (
int j = 0; j < c; j++) {
11523 for (
int i = 0; i < r; i++) {
11524 temp_vec_int[i] = Lmat(i, j).n;
11526 highest_each_columnL[j] =
11527 *std::max_element(temp_vec_int.begin(), temp_vec_int.end());
11530 for (
int i = 0; i < c; i++) {
11531 total_of_all_orders += highest_each_columnL[i];
11533 int n = *std::max_element(highest_each_columnL.begin(),
11534 highest_each_columnL.end());
11537 std::valarray<ChebfunMat<std::complex<T> > > alphais;
11538 std::valarray<ChebfunMat<std::complex<T> > > betais;
11539 alphais.resize(n + 1);
11540 betais.resize(n + 1);
11541 int outer_counter = 0;
11543 for (
int k = 0; k < n + 1; k++) {
11544 alphais[k].resize(Lmat.r, Lmat.c);
11545 alphais[k].setConstant(0.0);
11546 for (
int i = 0; i < Lmat.r; i++) {
11547 for (
int j = 0; j < Lmat.c; j++) {
11548 if (Lmat(i, j).n - k >= 0) {
11549 if (Lmat(i, j).NCC == 0) {
11550 alphais[k](i, j) = Lmat(i, j).coef[Lmat(i, j).n - k];
11552 alphais[k](i, j) = Lmat(i, j).coefFun[Lmat(i, j).n - k];
11560 std::valarray<ChebfunMat<std::complex<T> > > Amat;
11561 Amat.resize(n * n);
11562 for (
int i = 0; i < n * n; i++) {
11563 Amat[i].resize(Lmat.r, Lmat.c);
11564 Amat[i].setConstant(0.0);
11567 for (
int i = 0; i < n; i++) {
11568 for (
int j = 0; j < n - i; j++) {
11569 for (
int k = i; k < n - j; k++) {
11570 Amat[i * n + j] = Amat[i * n + j] + (
pow(-1, k) * nck(k, i) *
11571 diff(alphais[k + j + 1], k - i));
11577 std::valarray<std::complex<double> > rr(
N + 1);
11580 for (
int i = 0; i < n * n; i++) {
11581 for (
int l = 0; l < Amat[i].r; l++) {
11582 for (
int m = 0; m < Amat[i].c; m++) {
11584 Amat[i](l, m).v = Amat[i](l, m).v / (rr * rr);
11586 Amat[i](l, m).c2p();
11587 Amat[i](l, m).v = Amat[i](l, m).v / (rr * rr);
11588 Amat[i](l, m).p2c();
11594 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> Aplus(n * r,
11596 Aminus(n * r, n * r);
11598 Aplus =
feval2D(Amat, n, n, 1.0);
11599 Aminus =
feval2D(Amat, n, n, -1.0);
11604 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> Blbc(
11606 Brbc(Rbc.m, n * Rbc.n);
11607 Blbc.setConstant(0.0);
11608 Brbc.setConstant(0.0);
11610 for (
int k = 0; k < n + 1; k++) {
11611 for (
int i = 0; i < Lbc.m; i++) {
11612 for (
int j = 0; j < Lbc.n; j++) {
11613 if (Lbc.L(i, j).n - k >= 0) {
11614 if (Lbc.L(i, j).NCC == 0) {
11617 Blbc(i, Lbc.n * k + j) = Lbc.L(i, j).coef[Lbc.L(i, j).n - k];
11621 std::cout <<
"boundary conditions cannot have non-constant" 11622 <<
"coefficients" <<
'\n';
11629 for (
int k = 0; k < n + 1; k++) {
11630 for (
int i = 0; i < Rbc.m; i++) {
11631 for (
int j = 0; j < Rbc.n; j++) {
11632 if (Rbc.L(i, j).n - k >= 0) {
11633 if (Rbc.L(i, j).NCC == 0) {
11634 Brbc(i, Rbc.n * k + j) = Rbc.L(i, j).coef[Rbc.L(i, j).n - k];
11639 std::cout <<
"boundary conditions cannot have non-constant" 11640 <<
"coefficients" <<
'\n';
11649 Eigen::CompleteOrthogonalDecomposition<
11650 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
11653 if (cod.rank() != Blbc.rows()) {
11654 std::cout <<
"the bounndary conditions are not linearly independent." 11655 <<
"Exiting ..." <<
'\n';
11673 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> V =
11674 cod.matrixZ().adjoint();
11675 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> Null_space =
11676 V.block(0, cod.rank(), V.rows(), V.cols() - cod.rank());
11677 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> P = cod.colsPermutation();
11678 Null_space = P * Null_space;
11680 cod.compute(Null_space);
11684 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> solutionL(
11685 Null_space.rows(), Null_space.cols());
11689 solutionL = Null_space;
11692 if (cod.rank() != Brbc.rows()) {
11693 std::cout <<
"the bounndary conditions are not linearly independent." 11694 <<
"Exiting ..." <<
'\n';
11702 V = cod.matrixZ().adjoint();
11704 Null_space = V.block(0, cod.rank(), V.rows(), V.cols() - cod.rank());
11706 P = cod.colsPermutation();
11708 Null_space = P * Null_space;
11711 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> solutionR(
11712 Null_space.rows(), Null_space.cols());
11716 solutionR = Null_space;
11719 solutionL.adjointInPlace();
11720 Aminus.adjointInPlace();
11721 cod.compute(Aminus);
11725 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
11726 lbc1 = solutionL * Aminus,
11731 cod.compute(lbc1.transpose());
11732 Ptemp = cod.colsPermutation();
11733 lbc1 = Ptemp * lbc1;
11734 lbc = lbc1.block(0, 0, cod.rank(), lbc1.cols());
11736 solutionR.adjointInPlace();
11737 Aplus.adjointInPlace();
11738 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic>
11739 rbc1 = solutionR * Aplus,
11741 cod.compute(rbc1.transpose());
11742 Ptemp2 = cod.colsPermutation();
11743 rbc1 = Ptemp2 * rbc1;
11744 rbc = rbc1.block(0, 0, cod.rank(), rbc1.cols());
11748 out.resize(lbc.rows() + rbc.rows(), Lmat.r);
11752 for (
int i = 0; i < lbc.rows(); i++) {
11753 for (
int j = 0; j < Lmat.c; j++) {
11754 out.L(i, j).set(n - 1);
11755 out.eval(i, j) = -1.0;
11756 for (
int k = 0; k < n; k++) {
11757 out.L(i, j).coef[n - k - 1] = lbc(i, Lmat.c * k + j);
11762 for (
int i = 0; i < rbc.rows(); i++) {
11763 for (
int j = 0; j < Lmat.c; j++) {
11764 out.L(i + lbc.rows(), j).
set(n - 1);
11765 out.eval(i + lbc.rows(), j) = 1.0;
11766 for (
int k = 0; k < n; k++) {
11768 out.L(i + lbc.rows(), j).coef[n - k - 1] = rbc(i, Lmat.c * k + j);
11775 for (
int i = 0; i < out.m; i++) {
11776 for (
int j = 0; j < out.n; j++) {
11777 tempMat.L(i, j).set(highest_each_columnL[j] - 1);
11778 for (
int k = 0; k < highest_each_columnL[j]; k++) {
11779 tempMat.L(i, j).coef[highest_each_columnL[j] - k - 1] =
11780 out.L(i, j).coef[out.L(i, j).n - k];
11784 tempMat.eval = out.eval;
11807 const std::valarray<double> &
y,
11808 const std::valarray<double> &z,
11809 const std::valarray<double> &u,
11810 const std::valarray<double> &v,
11811 const std::valarray<double> &w,
11812 const std::valarray<double> &p) {
11813 std::string filename;
11814 filename = flnm +
".vtk";
11815 std::ofstream outf(filename);
11818 outf <<
"# vtk DataFile Version 2.0\n" 11819 <<
"2D3C velocity vector data \n" 11821 <<
"DATASET RECTILINEAR_GRID\n" 11822 <<
"DIMENSIONS " << 1 <<
" " << Ny <<
" " << Nz <<
"\n" 11823 <<
"X_COORDINATES " << 1 <<
" double\n";
11826 <<
"Y_COORDINATES " << Ny <<
" double\n";
11827 for (
int i = 0; i < Ny; i++) {
11828 outf <<
y[i] <<
" ";
11831 <<
"Z_COORDINATES " << Nz <<
" double\n";
11832 for (
int i = 0; i < Nz; i++) {
11833 outf << z[i] <<
" ";
11836 <<
"POINT_DATA " << Nz * (Ny) <<
"\n" 11837 <<
"SCALARS pressure double 1\n" 11838 <<
"LOOKUP_TABLE default\n";
11839 for (
int j = 0; j < Nz; j++) {
11840 for (
int i = 0; i < Ny; i++) {
11841 outf << p[(Ny)*i + j] <<
"\t";
11846 <<
"VECTORS Velocity double\n";
11847 for (
int j = 0; j < Nz; j++) {
11848 for (
int i = 0; i < Ny; i++) {
11849 outf << u[Nz * i + j] <<
" " << v[Nz * i + j] <<
" " << w[Nz * i + j]
11863 const std::string &flnm,
const std::valarray<double> &x,
11864 const std::valarray<double> &
y,
const std::valarray<double> &z,
11865 const std::valarray<double> &u,
const std::valarray<double> &v,
11866 const std::valarray<double> &w,
const std::valarray<double> &p) {
11867 std::string filename;
11868 filename = flnm +
".vtk";
11869 std::ofstream outf(filename);
11873 outf <<
"# vtk DataFile Version 2.0\n" 11874 <<
"3D velocity vector data \n" 11876 <<
"DATASET RECTILINEAR_GRID\n" 11877 <<
"DIMENSIONS " << Nx <<
" " << Ny <<
" " << Nz <<
"\n" 11878 <<
"X_COORDINATES " << Nx <<
" double\n";
11879 for (
int i = 0; i < Nx; i++) {
11880 outf << x[i] <<
" ";
11883 <<
"Y_COORDINATES " << Ny <<
" double\n";
11884 for (
int i = 0; i < Ny; i++) {
11885 outf <<
y[i] <<
" ";
11888 <<
"Z_COORDINATES " << Nz <<
" double\n";
11889 for (
int i = 0; i < Nz; i++) {
11890 outf << z[i] <<
" ";
11893 <<
"POINT_DATA " << Nx * Nz * (Ny) <<
"\n" 11894 <<
"SCALARS pressure double 1\n" 11895 <<
"LOOKUP_TABLE default\n";
11896 for (
int k = 0; k < Nz; k++) {
11897 for (
int i = 0; i < Ny; i++) {
11898 for (
int j = 0; j < Nx; j++) {
11899 outf << p[i * Nx * Nz + j * Nz + k] <<
"\t";
11905 <<
"VECTORS Velocity double\n";
11906 for (
int k = 0; k < Nz; k++) {
11907 for (
int i = 0; i < Ny; i++) {
11908 for (
int j = 0; j < Nx; j++) {
11909 outf << u[i * Nx * Nz + j * Nz + k] <<
" " 11910 << v[i * Nx * Nz + j * Nz + k] <<
" " 11911 << w[i * Nx * Nz + j * Nz + k] <<
"\n";
11924 const std::string &flnm,
const std::valarray<double> &x,
11925 const std::valarray<double> &
y,
const std::valarray<double> &z,
11926 const std::valarray<double> &t11,
const std::valarray<double> &t12,
11927 const std::valarray<double> &t13,
const std::valarray<double> &t22,
11928 const std::valarray<double> &t23,
const std::valarray<double> &t33) {
11929 std::string filename;
11930 filename = flnm +
".vtk";
11931 std::ofstream outf(filename);
11935 outf <<
"# vtk DataFile Version 2.0\n" 11936 <<
"3D velocity vector data \n" 11938 <<
"DATASET RECTILINEAR_GRID\n" 11939 <<
"DIMENSIONS " << Nx <<
" " << Ny <<
" " << Nz <<
"\n" 11940 <<
"X_COORDINATES " << Nx <<
" double\n";
11941 for (
int i = 0; i < Nx; i++) {
11942 outf << x[i] <<
" ";
11945 <<
"Y_COORDINATES " << Ny <<
" double\n";
11946 for (
int i = 0; i < Ny; i++) {
11947 outf <<
y[i] <<
" ";
11950 <<
"Z_COORDINATES " << Nz <<
" double\n";
11951 for (
int i = 0; i < Nz; i++) {
11952 outf << z[i] <<
" ";
11955 <<
"POINT_DATA " << Nx * Nz * (Ny) <<
"\n" 11956 <<
"TENSORS Stress double\n";
11957 for (
int k = 0; k < Nz; k++) {
11958 for (
int i = 0; i < Ny; i++) {
11959 for (
int j = 0; j < Nx; j++) {
11960 outf << t11[i * Nx * Nz + j * Nz + k] <<
" " 11961 << t12[i * Nx * Nz + j * Nz + k] <<
" " 11962 << t13[i * Nx * Nz + j * Nz + k] <<
"\n" 11963 << t12[i * Nx * Nz + j * Nz + k] <<
" " 11964 << t22[i * Nx * Nz + j * Nz + k] <<
" " 11965 << t23[i * Nx * Nz + j * Nz + k] <<
"\n" 11966 << t13[i * Nx * Nz + j * Nz + k] <<
" " 11967 << t23[i * Nx * Nz + j * Nz + k] <<
" " 11968 << t33[i * Nx * Nz + j * Nz + k] <<
"\n\n";
11978 in.
coef = in.
coef.conjugate().eval();
11980 for (
int i = 0; i < in.
n + 1; i++) {
11991 if (a.
r != b.
r || a.
c != b.
c) {
11992 std::cout <<
"addition of vector of ChebfunMats not possible" 11993 <<
". In " << __LINE__ <<
'\n';
11997 for (
int i = 0; i < out.
r; i++) {
11998 for (
int j = 0; j < out.
c; j++) {
12004 out(i, j) = a(i, j) + b(i, j);
12016 if (a.size() != b.size()) {
12017 std::cout <<
"addition of vector of ChebfunMats not possible" 12018 <<
". In " << __LINE__ <<
'\n';
12021 std::vector<sis::ChebfunMat<T> > out;
12022 out.resize(a.size());
12023 for (
int i = 0; i < a.size(); i++) {
12024 if (a[i].r != b[i].r || a[i].c != b[i].c) {
12025 std::cout <<
"addition of vector of ChebfunMats not possible" 12026 <<
". In " << __LINE__ <<
'\n';
12029 out[i] = a[i] + b[i];
12037 std::ostream &operator<<(std::ostream &stream, std::valarray<T> a) {
12039 for (
int i = 0; i < a.size(); i++) {
12040 stream << a[i] <<
"\n";
12046 std::ostream &operator<<(std::ostream &stream, std::vector<T> a) {
12048 for (
int i = 0; i < a.size(); i++) {
12049 stream << a[i] <<
"\n";
12058 if (out.
NCC == 0) {
12061 for (
int i = 0; i < out.
n + 1; i++) {
12082 int diffn = l_.
n - r_.
n;
12084 for (
int i = r_.
n; i > -1; i--) {
12085 out.
coef[i + diffn] = l_.
coef[i + diffn] + r_.
coef[i];
12087 for (
int i = 0; i < diffn; i++) {
12091 int diffn = r_.
n - l_.
n;
12093 for (
int i = l_.
n; i > -1; i--) {
12094 out.
coef[i + diffn] = r_.
coef[i + diffn] + l_.
coef[i];
12096 for (
int i = 0; i < diffn; i++) {
12103 int diffn = l_.
n - r_.
n;
12105 for (
int i = r_.
n; i > -1; i--) {
12108 for (
int i = 0; i < diffn; i++) {
12112 int diffn = r_.
n - l_.
n;
12114 for (
int i = l_.
n; i > -1; i--) {
12117 for (
int i = 0; i < diffn; i++) {
12125 int diffn = l_.
n - r_.
n;
12127 for (
int i = r_.
n; i > -1; i--) {
12130 for (
int i = 0; i < diffn; i++) {
12134 int diffn = r_.
n - l_.
n;
12136 for (
int i = l_.
n; i > -1; i--) {
12139 for (
int i = 0; i < diffn; i++) {
12145 int diffn = l_.
n - r_.
n;
12147 for (
int i = r_.
n; i > -1; i--) {
12150 for (
int i = 0; i < diffn; i++) {
12154 int diffn = r_.
n - l_.
n;
12156 for (
int i = l_.
n; i > -1; i--) {
12159 for (
int i = 0; i < diffn; i++) {
12172 if (
real.NCC == 0) {
12173 if (
imag.NCC == 0) {
12177 for (
int i =
imag.n; i > -1; i--) {
12178 out.
coef[i + diffn] =
12179 std::complex<T>(
real.coef[i + diffn],
imag.coef[i]);
12181 for (
int i = 0; i < diffn; i++) {
12187 for (
int i =
real.n; i > -1; i--) {
12188 out.
coef[i + diffn] =
12189 std::complex<T>(
real.coef[i],
imag.coef[i + diffn]);
12191 for (
int i = 0; i < diffn; i++) {
12192 out.
coef[i] = std::complex<T>(0.0,
imag.coef[i]);
12199 for (
int i =
imag.n; i > -1; i--) {
12200 std::valarray<T> temp(
N + 1);
12201 temp =
real.coef[i + diffn];
12204 for (
int i = 0; i < diffn; i++) {
12205 out.
coefFun[i].v = std::complex<T>(
real.coef[i], 0.0);
12210 for (
int i =
real.n; i > -1; i--) {
12211 std::valarray<T> temp(
N + 1);
12212 temp =
real.coef[i];
12215 for (
int i = 0; i < diffn; i++) {
12216 std::valarray<T> temp(
N + 1);
12223 if (
imag.NCC == 0) {
12227 for (
int i =
imag.n; i > -1; i--) {
12228 std::valarray<T> temp(
N + 1);
12229 temp =
imag.coef[i];
12232 for (
int i = 0; i < diffn; i++) {
12233 std::valarray<T> temp(
N + 1);
12240 for (
int i =
real.n; i > -1; i--) {
12241 std::valarray<T> temp(
N + 1);
12242 temp =
imag.coef[i + diffn];
12245 for (
int i = 0; i < diffn; i++) {
12246 out.
coefFun[i].v = std::complex<T>(0.0,
imag.coef[i]);
12253 for (
int i =
imag.n; i > -1; i--) {
12257 for (
int i = 0; i < diffn; i++) {
12258 std::valarray<T> temp(
N + 1);
12265 for (
int i =
real.n; i > -1; i--) {
12269 for (
int i = 0; i < diffn; i++) {
12270 std::valarray<T> temp(
N + 1);
12285 outr = l_.real() + r_;
12296 outr = l_ + r_.real();
12312 Chebfun<std::complex<T> > r_) {
12323 outr = l_ + r_.real();
12332 outr = l_.real() + r_;
12347 Linop<std::complex<T> > r_) {
12357 outr = l_ + r_.real();
12365 outr = l_.real() + r_;
12380 std::valarray<std::complex<T> > r_) {
12389 std::valarray<std::complex<T> > r_) {
12395 return temp1 + temp2;
12401 std::valarray<T> r_) {
12403 outr = l_.real() + r_;
12418 const Linop<std::complex<T> > &r_) {
12427 Linop<std::complex<T> > r_) {
12435 outr =
real(l_) + r_;
12465 Chebfun<std::complex<T> > r_) {
12489 Linop<std::complex<T> > r_) {
12506 return l_ + std::valarray<T>(-r_);
12512 std::valarray<std::complex<T> > r_) {
12513 return l_ + std::valarray<std::complex<T> >(-r_);
12519 std::valarray<T> r_) {
12520 return l_ + std::valarray<T>(-r_);
12532 Linop<std::complex<T> > r_) {
12543 Eigen::Array<T, Eigen::Dynamic, 1>
12545 const Eigen::Array<T, Eigen::Dynamic, 1> &right) {
12546 Eigen::Array<T, Eigen::Dynamic, 1> out;
12547 out.resize(left.size());
12548 for (
int i = 0; i < left.size(); i++) {
12549 out[i] = left[i] * right[i];
12557 if (right.
NCC == 0) {
12559 for (
int i = 0; i < right.
n + 1; i++) {
12564 for (
int i = 0; i < right.
n + 1; i++) {
12576 return left * temp;
12581 Linop<std::complex<T> > right) {
12582 std::valarray<std::complex<T> > temp;
12583 std::valarray<T> zvec;
12586 return temp * right;
12593 if (right.
NCC == 0) {
12595 for (
int i = 0; i < right.
n + 1; i++) {
12600 for (
int i = 0; i < right.
n + 1; i++) {
12612 return left * temp;
12617 Linop<std::complex<T> > right) {
12620 return temp * right;
12627 if (right.
NCC == 0) {
12628 for (
int i = 0; i < right.
n + 1; i++) {
12629 temp.
coef[i] = left * right.
coef[i];
12633 for (
int i = 0; i < right.
n + 1; i++) {
12644 return left * temp;
12649 std::complex<T> temp(left, 0.0);
12650 return temp * right;
12657 return _right + left;
12664 return _left + right;
12673 return _right + left;
12681 return _left + right;
12689 return _right + left;
12695 const Linop<std::complex<T> > &right) {
12698 return _left + right;
12704 return left - _right;
12712 return _left - right;
12718 const Linop<std::complex<T> > &right) {
12721 return _left - right;
12728 return _left - right;
12736 return left - _right;
12743 return left - _right;
12788 for (
int i = 0; i < in.
r; i++) {
12789 for (
int j = 0; j < in.
c; j++) {
12790 out(i, j) = a * in(i, j);
12803 for (
int i = 0; i < in.r; i++) {
12804 for (
int j = 0; j < in.c; j++) {
12805 out(i, j) = a * in(i, j);
12817 for (
int i = 0; i < in.
r; i++) {
12818 for (
int j = 0; j < in.
c; j++) {
12819 out(i, j) = a * in(i, j);
12830 std::valarray<ChebfunMat<T> > out;
12831 out.resize(in.size());
12832 for (
int i = 0; i < in.size(); i++) {
12833 out[i] = a * in[i];
12841 std::valarray<ChebfunMat<std::complex<T> > >
12843 std::valarray<ChebfunMat<std::complex<T> > > out;
12844 out.resize(in.size());
12845 for (
int i = 0; i < in.size(); i++) {
12846 out[i] = a * in[i];
12854 std::valarray<ChebfunMat<T> >
12856 std::valarray<ChebfunMat<std::complex<T> > > out;
12857 out.resize(in.size());
12858 for (
int i = 0; i < in.size(); i++) {
12859 out[i] = a * in[i];
12930 out.
set(L1.
n + L2.
n);
12931 if (L1.
NCC == 0 && L1.
NCC == 0) {
12932 for (
int i = 0; i < L1.
n + L2.
n + 1; i++) {
12935 for (
int i = 0; i < L1.
n + 1; i++) {
12936 out += L1.
coef[i] *
diff(L2, L1.
n - i);
12939 out.
ncc(L1.
n + L2.
n);
12940 for (
int i = 0; i < L1.
n + L2.
n + 1; i++) {
12944 for (
int i = 0; i < L1.
n + 1; i++) {
12945 out += L1.
coef[i] *
diff(L2, L1.
n - i);
12948 for (
int i = 0; i < L1.
n + 1; i++) {
12959 out.
set(L1.n + L2.
n);
12960 if (L1.NCC == 0 && L1.NCC == 0) {
12961 for (
int i = 0; i < L1.n + L2.
n + 1; i++) {
12964 for (
int i = 0; i < L1.n + 1; i++) {
12965 out += L1.
coef[i] *
diff(L2, L1.
n - i);
12968 out.
ncc(L1.n + L2.
n);
12969 for (
int i = 0; i < L1.n + L2.
n + 1; i++) {
12973 for (
int i = 0; i < L1.n + 1; i++) {
12974 out += L1.
coef[i] *
diff(L2, L1.
n - i);
12977 for (
int i = 0; i < L1.n + 1; i++) {
12987 out.
set(L1.
n + L2.n);
12988 if (L1.
NCC == 0 && L1.
NCC == 0) {
12989 for (
int i = 0; i < L1.
n + L2.n + 1; i++) {
12992 for (
int i = 0; i < L1.
n + 1; i++) {
12993 out += L1.
coef[i] *
diff(L2, L1.
n - i);
12996 out.
ncc(L1.
n + L2.n);
12997 for (
int i = 0; i < L1.
n + L2.n + 1; i++) {
13001 for (
int i = 0; i < L1.
n + 1; i++) {
13002 out += L1.
coef[i] *
diff(L2, L1.
n - i);
13005 for (
int i = 0; i < L1.
n + 1; i++) {
13054 std::cout <<
"Cannot have a negative power for linop ..." <<
'\n';
13055 std::cout <<
"in " << __LINE__ <<
'\n';
13057 }
else if (a == 1) {
13060 return pow(in, a - 1) * in;
13066 if (left.r != right.r || left.c != right.c) {
13067 std::cout <<
"Incompatible shapes of LinopMats for addition." <<
'\n';
13070 temp.resize(left.r, left.c);
13071 for (
int i = 0; i < left.r; i++) {
13072 for (
int j = 0; j < left.c; j++) {
13073 temp(i, j) = left(i, j) + right(i, j);
13083 if (left.r != right.r || left.c != right.c) {
13084 std::cout <<
"Incompatible shapes of LinopMats for addition." <<
'\n';
13087 temp.resize(left.r, left.c);
13088 for (
int i = 0; i < left.r; i++) {
13089 for (
int j = 0; j < left.c; j++) {
13090 temp(i, j) = left(i, j) + right(i, j);
13098 LinopMat<std::complex<T> > right) {
13100 if (left.r != right.r || left.c != right.c) {
13101 std::cout <<
"Incompatible shapes of LinopMats for addition." <<
'\n';
13104 temp.resize(left.r, left.c);
13105 for (
int i = 0; i < left.r; i++) {
13106 for (
int j = 0; j < left.c; j++) {
13107 temp(i, j) = left(i, j) + right(i, j);
13115 for (
int i = 0; i < right.r; i++) {
13116 for (
int j = 0; j < right.c; j++) {
13117 right(i, j) = a * right(i, j);
13126 for (
int i = 0; i < right.r; i++) {
13127 for (
int j = 0; j < right.c; j++) {
13128 right(i, j) = a * right(i, j);
13138 for (
int i = 0; i < right.r; i++) {
13139 for (
int j = 0; j < right.c; j++) {
13140 out(i, j) = a * right(i, j);
13148 if (left.c != right.r) {
13149 std::cout <<
"Incompatible shapes of LinopMats for multiplication." <<
'\n';
13154 out.setConstant(0.0);
13155 for (
int i = 0; i < left.r; i++) {
13156 for (
int j = 0; j < right.c; j++) {
13157 for (
int k = 0; k < left.c; k++) {
13158 out(i, j) = out(i, j) + (left(i, k) * right(k, j));
13168 if (left.c != right.r) {
13169 std::cout <<
"Incompatible shapes of LinopMats for multiplication." <<
'\n';
13174 out.setConstant(0.0);
13175 for (
int i = 0; i < left.r; i++) {
13176 for (
int j = 0; j < right.c; j++) {
13177 for (
int k = 0; k < left.c; k++) {
13178 out(i, j) = out(i, j) + (left(i, k) * right(k, j));
13187 LinopMat<std::complex<T> > right) {
13188 if (left.c != right.r) {
13189 std::cout <<
"Incompatible shapes of LinopMats for multiplication." <<
'\n';
13194 out.setConstant(0.0);
13195 for (
int i = 0; i < left.r; i++) {
13196 for (
int j = 0; j < right.c; j++) {
13197 for (
int k = 0; k < left.c; k++) {
13198 out(i, j) = out(i, j) + (left(i, k) * right(k, j));
13208 if (left.r != right.r || left.c != right.c) {
13209 std::cout <<
"Incompatible shapes of LinopMats for subtraction." <<
'\n';
13212 temp.resize(left.r, left.c);
13213 for (
int i = 0; i < left.r; i++) {
13214 for (
int j = 0; j < left.c; j++) {
13215 temp(i, j) = left(i, j) - right(i, j);
13225 if (left.r != right.r || left.c != right.c) {
13226 std::cout <<
"Incompatible shapes of LinopMats for addition." <<
'\n';
13229 temp.resize(left.r, left.c);
13230 for (
int i = 0; i < left.r; i++) {
13231 for (
int j = 0; j < left.c; j++) {
13232 temp(i, j) = left(i, j) - right(i, j);
13240 LinopMat<std::complex<T> > right) {
13242 if (left.r != right.r || left.c != right.c) {
13243 std::cout <<
"Incompatible shapes of LinopMats for addition." <<
'\n';
13246 temp.resize(left.r, left.c);
13247 for (
int i = 0; i < left.r; i++) {
13248 for (
int j = 0; j < left.c; j++) {
13249 temp(i, j) = left(i, j) - right(i, j);
13257 outMat.resize(left_.r, left_.c);
13258 for (
int i = 0; i < left_.r; i++) {
13259 for (
int j = 0; j < left_.c; j++) {
13260 outMat(i, j) = left_(i, j) / right;
13270 outMat.resize(left_.r, left_.c);
13271 for (
int i = 0; i < left_.r; i++) {
13272 for (
int j = 0; j < left_.c; j++) {
13273 outMat(i, j) = left_(i, j) / right;
13281 ChebfunMat<std::complex<T> >
13283 const BcMat<std::complex<T> > &bcmat_,
13284 const ChebfunMat<std::complex<T> > &forc_) {
13290 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> A0 =
13291 Dis.MatAppend(Lmat, bcmat);
13292 Eigen::ColPivHouseholderQR<
13293 Eigen::Matrix<std::complex<T>, Eigen::Dynamic, Eigen::Dynamic> >
13296 if (!qr.isInvertible()) {
13297 std::cout <<
"Solution not possible. This system is singular." <<
'\n';
13300 Eigen::Matrix<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> force =
13307 Eigen::Matrix<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> force2(
13308 A0.rows(), force.cols());
13310 for (
int i = 0; i < force2.cols(); i++) {
13311 force2.block(0, i, force.rows(), 1) = force.col(i);
13312 force2.block(force.rows(), i, bcmat.vals.rows(), 1) = bcmat.vals;
13320 force2 = qr.inverse() * force2;
13325 int row_counter = 0;
13326 for (
int i = 0; i < forc.
c; i++) {
13327 int n = Dis.highest_each_column[i];
13329 force.block(i * (
N + 1), 0,
N + 1, forc.
c) =
13331 force2.block(row_counter, 0,
N + 1 + n, forc.
c);
13332 row_counter +=
N + 1 + n;
13342 for (
int i = 0; i < out.
r; i++) {
13343 for (
int j = 0; j < out.
c; j++) {
void operator=(const ChebfunMat &in)
Assignment operator.
void operator+=(const Linop< std::complex< T > > &in)
void c2p()
Converts every element to phys-space, if not already in phys-space.
void operator=(const LinopMat< std::complex< T > > &in)
Assignment operator.
Chebfun()
Null constructor.
void compute(const LinopMat< std::complex< T > > &Lmat_, int num_vals, const BcMat< std::complex< T > > &bc_)
Call this with an input Linear operator to solve for eigenvalues and vectors. The number of Eigen val...
LinopMat(int r_, int c_)
Initializes a Linop Matrix of r_ rows and c_ columns.
void operator=(const T &in)
Assignment operator for constant input.
void compute(const LinopMat< T > &A_, const LinopMat< T > &B_, const LinopMat< T > &C_, const BcMat< T > &Lbc_, const BcMat< T > &Rbc_, int num_vals)
Computes the Singular value(s) of a system in the input-output form, This is used to the find the fr...
Chebfun< T > operator()(Chebfun< T > in)
Apply the operator on a Chebfun.
Linop()
A null-constructor for Linop.
BcMat< std::complex< T > > AdjointBc_analytical(const LinopMat< std::complex< T > > &Lmat_, const BcMat< std::complex< T > > &Lbc_, const BcMat< std::complex< T > > &Rbc_)
Computes adjoint boundary conditions analytically, needs boundary conditions all right boundary condi...
Linop()
A null-constructor for Linop.
Eigen::Array< std::complex< T >, Eigen::Dynamic, 1 > evc()
Returns property complex array vr + i vi in terms of Eigen::Array.
void ncc(int n_)
Sets the the size of non-constant coefficient array based on the order of differential equation...
void removeInf()
This will remove all infinite eigenvalues. Useful when solving generalized eigenvalue problems...
void resize(int r_, int c_)
This clears all contents in the LinopMat, and then creates a fresh LinopMat of size r_ x c_...
BcMat will hold general Boundary conditions as LinopMats at evealuation points, as given by operator ...
std::valarray< std::complex< T > > operator*(std::complex< T > left, std::valarray< T > right)
Multiplying a complex number with a real valarray.
void compute(const LinopMat< std::complex< T > > &A_, const BcMat< std::complex< T > > &Lbc_, const BcMat< std::complex< T > > &Rbc_, int num_vals)
Computes the singular values/functions of a Linear block matrix operator.
LinopMat< T > & operator,(Eigen::Array< T, Eigen::Dynamic, 1 > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type Eigen array.
ChebfunMat< std::complex< T > > linSolve(const LinopMat< std::complex< T > > &Lmat_, const BcMat< std::complex< T > > &bcmat_, const ChebfunMat< std::complex< T > > &forc_)
Linear equation solver.
Linop(const Linop< std::complex< T > > &in)
Copy constructor.
void operator=(const Eigen::Matrix< T, Eigen::Dynamic, 1 > &right)
To assign a Chebfun through a vector.
This class sets up integration Matrices. This class must be intiated by the highest order of based on...
MatGen()
Null Constructor.
void operator=(Chebfun< T > in)
Assignment through a Chebfun:
void operator+=(std::complex< T > right)
add a constant to self
Chebfun< T > & operator[](int i)
Use this to to refer to Chebfuns. For 1D Matrices, we use the Row major format when refering to [i]...
ChebfunMat< std::complex< T > > & operator,(std::complex< T > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type complex constant...
void operator=(const Linop< std::complex< T > > &in)
void disp(std::valarray< T > in)
Prints a valarray to terminal.
void operator+=(const T &right)
Adding constant to itself.
LinopMat< std::complex< T > > & operator,(Linop< T > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type Chebfun.
Chebfun< std::complex< T > > cumsum()
void compute(const LinopMat< std::complex< T > > &A_, const LinopMat< std::complex< T > > &B_, const LinopMat< std::complex< T > > &C_, const BcMat< std::complex< T > > &Lbc_, const BcMat< std::complex< T > > &Rbc_, int num_vals)
Computes singular values of the frequency response operator of a system in the input-output form...
MatGen(int n_)
Constructor.
std::valarray< T > ifft2_cs(std::valarray< std::complex< T > > in1, int Nx, int Nz)
ifft2 for a 2D matrix stored in the row-major format, Nx and Nz denote dimensions in x and z...
void resize(int m_, int n_)
std::vector< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > mats2
int converged
Number of eigenvalues that have converged to machine precision.
LinopMat< T > operator/(LinopMat< T > left_, T right)
ChebfunMat< T > cTranspose()
LinopMat< std::complex< T > > & operator,(T b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type constant.
Linop< T > pow(Linop< T > in, int a)
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > eval
std::valarray< std::complex< T > > PowerSpectralDensityIndividual(const LinopMat< std::complex< T > > &A_, const LinopMat< std::complex< T > > &B_, const LinopMat< std::complex< T > > &C1_, const LinopMat< std::complex< T > > &C2_, const LinopMat< std::complex< T > > &C3_, const BcMat< std::complex< T > > &Lbc_, const BcMat< std::complex< T > > &Rbc_)
LinopMat< std::complex< T > > & operator,(std::complex< T > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type constant.
SingularValueDecomposition()
This is a chebfun analogue. Chebfun will represent both values in physical space or an array of Cheby...
void operator=(const LinopMat< T > &in)
Assignment operator.
Class to compute binomial coefficients returns a double output.
std::valarray< T > v
Stores a flag to denote if function is in Cheb-space or physical space.
Chebfun(const Eigen::Array< T, Eigen::Dynamic, Eigen::Dynamic > &in)
constructor by an input Eigen::Array<T,Eigen::Dynamic,1>
Linop This class creates a Linear operator to solve TPBVPs.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > MatAppend(const LinopMat< std::complex< T > > &Lmat_, const BcMat< std::complex< T > > &bc_)
valarray< T > imag(const valarray< complex< T > > &in)
imaginary part of a complex valarray
void compute(const LinopMat< std::complex< T > > &Lmat_, const LinopMat< std::complex< T > > &Mmat_, int num_vals, const BcMat< std::complex< T > > &Lbc_)
The main solver for LinopMat. Read about class BcMat to see how this works, also see examples example...
bool Mp
Stores true if machine precision is reached, else false.
void operator=(const BcMat< std::complex< T > > &in)
LinopMat< T > & operator,(Linop< T > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type Chebfun.
ChebfunMat(const ChebfunMat< T > &in)
Copy constructor.
Eigen::Array< T, Eigen::Dynamic, 1 > ev()
Returns property v in terms of Eigen::Array.
void compute(const LinopMat< T > &A_, const ChebfunMat< T > &B_, const LinopMat< T > &C_, const BcMat< T > &Lbc_, const BcMat< T > &Rbc_, int num_vals)
Computes the Singular value(s) of a system in the input-output form, here, B(y) is a function and no...
std::vector< Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > > mats2
Chebfun< T > & operator()(int i, int j)
Use this to to refer to Chebfuns. For 2D Matrices, refer to matrix element Chebfun by (i...
LinopMat(const LinopMat< std::complex< T > > &in)
Copy constructor.
Linop(const int &n_)
Makes a Linop by specifying the order n_ of the differential equation.
void operator=(const std::complex< T > &right)
To assign a Chebfun to a constant.
Chebfun(const Chebfun &in)
Copy conststructor.
std::valarray< std::complex< T > > fft(std::valarray< T > in1)
Linop< T > operator/(T in)
Dividing Linop by scalar.
void operator=(const std::valarray< T > &right)
LinopMat< std::complex< T > > & operator,(LinopMat< std::complex< T > > b)
void compute_with_constraints(const LinopMat< T > &Lmat_, const LinopMat< T > &Mmat_, int num_vals, const BcMat< T > &Lbc_, const BcMat< T > &Mbc_)
Chebfun(const Eigen::Array< std::complex< T >, Eigen::Dynamic, 1 > &in)
constructor by an input Eigen::Array<T,Eigen::Eigen::Dynamic,1>
void compute_with_constraints(const LinopMat< T > &Lmat_, const LinopMat< T > &Mmat_, int num_vals, const BcMat< T > &Lbc_embed_, const BcMat< T > &Lbc_append_, const BcMat< T > &Mbc_append_)
void setIdentity()
Sets LinopMat to identity.
Linop< T > operator-(const Linop< T > &in)
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > P
std::valarray< Chebfun< std::complex< T > > > ChebfunVec
This 1D vector of Chebfuns holds all Chebfuns of the ChebfunMat in the row-major format.
Chebfun< std::complex< T > > operator()(Chebfun< std::complex< T > > in)
Apply the operator on a Chebfun.
ChebfunMat< std::complex< T > > eigenvectors
EigenSorter()
Null constructor.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, 1 > coef
Stores the coefficients in the differential equation.
std::valarray< std::complex< T > > dealias_prod_2D(std::valarray< std::complex< T > > a, std::valarray< std::complex< T > > b, int Nx, int Nz)
dealias_prod_2D for a 2D matrix stored in the row-major format, Nx and Nz denote dimensions in x and ...
double omega_opt
This is the value of at which H-infinity norm occurs.
void p2c()
Converts a Chebfun from values in physical-space to coefficients of Chebyshev polynomials.
Linop< std::complex< T > > & operator[](int i)
Use this to to refer to Linops. For 1D Matrices, we use the Row major format when refering to [i]...
LinopMat< T > Adjoint(const LinopMat< T > &Lmat_)
Computes the adjoint of a linear operator. This is a differential adjoint, and not the conjugate tran...
void operator=(Chebfun< T > in)
void setConstant(T in)
Sets every member in LinopMat to constant.
std::vector< ChebfunMat< std::complex< T > > > eigenvectorsMat
std::valarray< T > ifft_cs(std::valarray< std::complex< T > > in)
Linop(const int &n_)
Makes a Linop by specifying the order n_ of the differential equation.
complex< double > ii(0.0, 1.0)
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > operator()(const LinopMat< std::complex< T > > &Lmat_, const BcMat< std::complex< T > > &bc_)
std::valarray< std::complex< SIS_TYPE > > rev_half_shift(N+1)
void ncc(int n_)
Sets the the size of non-constant coefficient array based on the order of differential equation...
void operator=(const Chebfun< T > &in)
assignment operator of Chebfun
std::valarray< std::complex< T > > v
Stores a flag to denote if function is in Cheb-space or physical space.
LinopMat(int r_, int c_)
Initializes a Linop Matrix of r_ rows and c_ columns.
void sortByLargestReal()
This function will sort the eigenvalues and vectors by the largest real part.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > subs_mat
void keepConverged()
This will remove all unconverged and infinite eigenvalues from the list.
void operator=(const Linop< T > &in)
Eigen::Matrix< SIS_TYPE, Eigen::Dynamic, Eigen::Dynamic > yEigen
std::complex< T > PowerSpectralDensity(const LinopMat< std::complex< T > > &A_, const LinopMat< std::complex< T > > &B_, const LinopMat< std::complex< T > > &C_, const BcMat< std::complex< T > > &Lbc_, const BcMat< std::complex< T > > &Rbc_, const BcMat< std::complex< T > > &Lbc_adjoint_, const BcMat< std::complex< T > > &Rbc_adjoint_)
std::vector< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > mats
LinopMat< std::complex< T > > & operator,(std::valarray< std::complex< T > > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type valarray.
void operator=(const BcMat< T > &in)
LinopMat< T > & operator<<(T b)
Use this to input multiple Linops to the LinopMat using comma separators. Input type of constant...
ChebfunMat< std::complex< T > > operator()(ChebfunMat< std::complex< T > > in)
Use this to apply a LinopMat on a ChebfunMat.
Chebfun< std::complex< T > > & operator[](int i)
Use this to to refer to Chebfuns. For 1D Matrices, we use the Row major format when refering to [i]...
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, 1 > solution
Stores the solution.
std::complex< T > size(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &in)
This function is useful to see size of Eigen matrices. Returns a complex number, where the real part ...
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > P
ChebfunMat(int r_, int c_)
Initializes a Chebfun Matrix of r_ rows and c_ columns.
void operator=(Chebfun< std::complex< T > > in)
Linop< std::complex< T > > operator/(std::complex< T > in)
Dividing Linop by scalar.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > operator()(const LinopMat< T > &Lmat)
Discretization based on a previous call with Boundary conditions. Then other LinopMats can be discret...
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > operator()(const LinopMat< T > &Lmat_, const BcMat< T > &bc_)
void operator=(const ChebfunMat< std::complex< T > > &in)
Assignment operator.
void operator+=(Chebfun< std::complex< T > > b)
Add complex chebfun to self.
std::vector< int > highest_each_column
void compute(int n_)
Call this to generate integration matrices for highest order n.
std::valarray< T > idct(const std::valarray< T > &u)
void vtkExportCartesian2D3C(const std::string &flnm, const std::valarray< double > &y, const std::valarray< double > &z, const std::valarray< double > &u, const std::valarray< double > &v, const std::valarray< double > &w, const std::valarray< double > &p)
Exports all data of 2D3C to a file. There are two dimensions, the wall-normal and the spanwise...
void operator+=(Chebfun right)
Add a Chebfun to itself. If both are in same space, return will be in same space, else the lhs will r...
Discretize()
Null Constructor.
void vtkExportCartesian3D(const std::string &flnm, const std::valarray< double > &x, const std::valarray< double > &y, const std::valarray< double > &z, const std::valarray< double > &u, const std::valarray< double > &v, const std::valarray< double > &w, const std::valarray< double > &p)
Exports all data of 3D velocity to a file. VTK file can be directly exported into paraview...
bool isMachinePrecision()
void setIdentity()
Sets LinopMat to identity.
void operator+=(const Linop< T > &in)
Add to self:
void c2p()
Converts a Chebfun from Chebyshev coefficients to values in physical space.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, 1 > eigenvalues
void operator=(T right)
Equating the Chebfun to a constant.
LinopMat< T > & operator,(T b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type constant.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > operator()(T p)
Use this to evaluate the whole ChebfunMat at a given point. Point must lie in the domain...
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > ChebDiff(const LinopMat< std::complex< T > > &Lmat_)
Chebyshev differentiation operator for LinopMat.
This class represents a block matrix operator. It is a matrix of operators.
bool isMachinePrecisionHalf()
void p2c()
Converts every element to Cheb-space, if not already in Cheb-space.
T minVal
Stores the smallest value in the Chebyshev series.
Given a linear block matrix operator and appropriate boundary conditions, this class will produce an ...
std::valarray< std::complex< SIS_TYPE > > yc(N+1)
T operator()(int n, int k)
std::valarray< std::complex< T > > operator-(std::complex< T > left, std::valarray< T > right)
Subtracting a real valarray from a complex number.
void operator=(const Eigen::Array< std::complex< T >, Eigen::Dynamic, 1 > &in)
Assignment operator for function input, through Eigen array.
std::complex< T > operator()(const double &a)
To assign a Chebfun through a array.
void setConstant(T in)
sets the all the Chebfuns in the ChebfunMat to constant
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > operator()(int i, int j, int ord)
Calling BcMat(i,j, ord) will produce row vector representing [---—][a0 a1 ... an C0 C1]^T...
Linop< T > operator*(Linop< T > L1, Linop< T > L2)
These are used to define operator compositions, L1(L2). It is defined as operator multiplication...
void operator=(const std::valarray< std::complex< T > > &right)
To assign a Chebfun through a valarray.
std::valarray< Linop< T > > LinopVec
This 1D vector of Linops holds all Linops of the LinopMat in the row-major format.
Chebfun()
Null constructor.
int n
The order of the Linear differential operator.
void set()
Sets the the size of coefficient array based on the order of differential equation. Suppose order is 3, then the size of array needed is 4.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > operator()(T p)
Use this to evaluate the whole ChebfunMat at a given point. Point must lie in the domain...
std::valarray< std::complex< T > > dou2com(const std::valarray< T > &a, const std::valarray< T > &b)
Use this to make a complex valarray out of two real valarrays.
void compute(int n_)
Call this to generate integration matrices for highest order n.
void operator=(const Chebfun &right)
To assign a Chebfun through another Chebfun.
Linop(const Linop< T > &in)
Copy constructor.
void operator=(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &in)
Assigning a ChebfunMat using a Eigen-matrix. Eigen-Matrix should be of size (r*(N+1), c), else an error is thrown. This implies that one must have called the resize(r,c) function before using this.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > invmat_temp
Eigen::Matrix< T, Eigen::Dynamic, 1 > solution
Stores the solution.
int NCC
Flag to set (value 1) for enabling nonconstant coefficients.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > ChebfunMat2EigenMat()
Returns an Eigen matrix representing the ChebfunMat.
std::valarray< T > dct(const std::valarray< T > &x)
ChebfunMat(const ChebfunMat< std::complex< T > > &in)
Copy constructor.
ChebfunMat< T > & operator,(std::valarray< T > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type valarray.
Eigen::Array< T, Eigen::Dynamic, 1 > operator*(std::valarray< T > left, const Eigen::Array< T, Eigen::Dynamic, 1 > &right)
Chebfun< std::complex< T > > solve(Chebfun< std::complex< T > > in)
This function solves the differential equation. See solve for details.
LinopMat< std::complex< T > > cTranspose()
LinopMat< T > & operator,(LinopMat< T > b)
void operator=(const Eigen::Matrix< std::complex< T >, Eigen::Dynamic, 1 > &right)
To assign a Chebfun through a vector.
Linop< std::complex< T > > operator/(T in)
Dividing Linop by scalar.
void operator+=(const Linop< T > &in)
std::valarray< std::complex< T > > operator+(std::complex< T > left, std::valarray< T > right)
Adding a complex number to a real valarray.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > operator()(const LinopMat< std::complex< T > > &Lmat_)
Discretization based on a previous call with Boundary conditions. Then other LinopMats can be discret...
LinopMat< std::complex< T > > & operator,(LinopMat< T > b)
int NCC
Flag to set (value 1) for enabling nonconstant coefficients.
T operator()(const T &a)
To assign a Chebfun through a Array.
std::valarray< std::complex< T > > fft2(std::valarray< T > in1, int Nx, int Nz)
fft2 for a 2D matrix stored in the row-major format, Nx and Nz denote dimensions in x and z...
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > MultMat()
This function returns the Toeplitz + almost Hankel matrix needed to express multiplication of two Che...
void operator=(const Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > &in)
Assigning a ChebfunMat using a Eigen-matrix. Eigen-Matrix should be of size (r*(N+1), c), else an error is thrown. This implies that one must have called the resize(r,c) function before using this.
void compute(const LinopMat< T > &A_, const BcMat< T > &Lbc_, const BcMat< T > &Rbc_, int num_vals)
Computes the singular values/functions of a Linear block matrix operator.
int numMp
Stores number of Chebyshev coefficients in which MP is reached, if not reached, it is set to N+1...
ChebfunMat< T > & operator,(T b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type constant.
Eigen::Matrix< T, Eigen::Dynamic, 1 > coef
Stores the coefficients in the differential equation.
void setChebPts(std::valarray< T > &in)
This function sets points to evaluate a function so that a DCT will give represent the same function ...
Chebfun(const Eigen::Matrix< std::complex< T >, Eigen::Dynamic, 1 > &in)
constructor by an input Eigen::Matrix<T,Eigen::Eigen::Dynamic,1>
Eigen::Matrix< T, Eigen::Dynamic, 1 > diff(const Eigen::Matrix< T, Eigen::Dynamic, 1 > &u)
Chebyshev differentiation operator for a vector of Chebyshev coefficients.
ChebfunMat()
Null constructor.
valarray< complex< T > > pow(valarray< complex< T > > base, T power)
ChebfunMat< std::complex< T > > cTranspose()
double gamma_opt
This is the H-infinity norm.
void operator=(const std::valarray< T > &in)
Assignment operator for function input, through valarray.
Eigen::Matrix< std::complex< SIS_TYPE >, Eigen::Dynamic, Eigen::Dynamic > ycEigen
ChebfunMat< std::complex< T > > coefFun
Use this to input all non-constant coefficients. See coefFun for details.
Eigen::Array< T, Eigen::Dynamic, 1 > evi()
Returns property v in terms of Eigen::Array.
std::vector< int > highest_each_column
LinopMat(const LinopMat< T > &in)
Copy constructor.
ChebfunMat< std::complex< T > > & operator,(Eigen::Array< std::complex< T >, Eigen::Dynamic, 1 > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type complex Eigen array...
void compute(const LinopMat< std::complex< T > > &Lmat_, const BcMat< std::complex< T > > &bc_)
Call this with an input Linear operator to solve for eigenvalues and vectors.
ChebfunMat< T > operator+(ChebfunMat< T > a, ChebfunMat< T > b)
Defining addition of ChebfunMats.
std::vector< Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > > mats
void keep(int n)
This will keep only n and remove the rest. Use this carefully. Only first n will be kept...
Linop< std::complex< T > > operator*(std::complex< T > in)
Multiplying Linop by scalar.
MatGen(int n_)
Constructor.
ChebfunMat< T > & operator<<(T b)
Use this to input multiple Chebfuns to the ChebfunMat using comma separators. Input type of constant...
Chebfun(const std::valarray< T > &in)
constructor by an input valarray
void compute(Linop< T > L, Linop< T > M, int num_vals)
Call this with an input Linear operator to solve for eigenvalues and vectors. The number of Eigen val...
void vtkExportCartesianStress3D(const std::string &flnm, const std::valarray< double > &x, const std::valarray< double > &y, const std::valarray< double > &z, const std::valarray< double > &t11, const std::valarray< double > &t12, const std::valarray< double > &t13, const std::valarray< double > &t22, const std::valarray< double > &t23, const std::valarray< double > &t33)
Exports stress data to a file. VTK file can be directly exported into paraview, or into Python using ...
LinopMat< std::complex< T > > & operator,(std::valarray< T > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type valarray.
void setConstant(std::complex< T > in)
sets the all the Chebfuns in the ChebfunMat to constant
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > feval2D(std::valarray< ChebfunMat< T > > Amat, int r, int c, T a)
void p2c()
Converts a Chebfun from values in physical-space to coefficients of Chebyshev polynomials.
Eigen::Array< std::complex< T >, Eigen::Dynamic, 1 > dou2com(const Eigen::Array< T, Eigen::Dynamic, 1 > &a, const Eigen::Array< T, Eigen::Dynamic, 1 > &b)
Use this to make a complex array out of two Eigen real valarrays.
void compute(const LinopMat< std::complex< T > > &A_, const LinopMat< std::complex< T > > &B_, const LinopMat< std::complex< T > > &C_, const BcMat< std::complex< T > > &Lbc_, const BcMat< std::complex< T > > &Rbc_, const BcMat< std::complex< T > > &Lbc_adjoint_, const BcMat< std::complex< T > > &Rbc_adjoint_, int num_vals)
Computes singular values of the frequency response operator of a system in the input-output form...
Linop< std::complex< T > > operator*(T in)
Multiplying Linop by scalar.
void operator=(T in)
Assignment operator for constant input.
This class computes various SingularValues of a differential block matrix operator using using it's a...
void ncc()
Sets the the size of non-constant coefficient array based on the order of differential equation...
T L2norm()
Returns the L2norm of the function.
BcMat< T > AdjointBc_analytical(const LinopMat< T > &Lmat_, const BcMat< T > &Lbc_, const BcMat< T > &Rbc_)
Computes adjoint boundary conditions analytically, needs boundary conditions all right boundary condi...
std::valarray< Chebfun< T > > ChebfunVec
This 1D vector of Chebfuns holds all Chebfuns of the ChebfunMat in the row-major format.
ChebfunMat< std::complex< T > > & operator,(std::valarray< std::complex< T > > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type complex valarray...
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > operator()(int i, int j, int ord)
Calling BcMat(i,j, ord) will produce row vector representing [---—][a0 a1 ... an C0 C1]^T...
ChebfunMat< T > solve(const ChebfunMat< T > &in)
Solves an input ChebfunMat, Dimensions of ChebfunMat have to be (c,1)
void operator+=(Chebfun< T > b)
Add real Chebfun to self.
LinopMat(const LinopMat< T > &in)
Copy constructor.
int N
Specifies number of Chebyshev polynomials, default N = 31.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > ChebfunMat2EigenMat()
Returns an Eigen matrix representing the ChebfunMat.
void setConstant(T in)
Sets every member in LinopMat to constant.
std::complex< T > PowerSpectralDensity(const LinopMat< std::complex< T > > &A_, const LinopMat< std::complex< T > > &B_, const LinopMat< std::complex< T > > &C_, const BcMat< std::complex< T > > &Lbc_, const BcMat< std::complex< T > > &Rbc_)
Computes power spectral density from the frequency response operator of a system in the input-output ...
LinopMat< T > cTranspose()
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > MultMat()
This function returns the Toeplitz + almost Hankel matrix needed to express multiplication of two Che...
void compute(Eigen::Matrix< std::complex< T >, Eigen::Dynamic, 1 > in)
Computes Mp and numMp for Linops.
void ncc()
Sets the the size of non-constant coefficient array based on the order of differential equation...
Chebfun< T > cumsum()
Returns a Chebfun that represents the indefinite integral of the Chebfun.
Chebfun(const std::valarray< std::complex< T > > &in)
constructor by an input valarray
void operator=(const Chebfun< std::complex< T > > &in)
assignment operator of Chebfun
void p2c()
Converts every element to Cheb-space, if not already in Cheb-space.
void computeAppend(const LinopMat< std::complex< T > > &Lmat_, const LinopMat< std::complex< T > > &Mmat_, int num_vals, const BcMat< std::complex< T > > &Lbc_)
Another main solver for LinopMat, a minimal solver for eigenvalues only. LAPACK needs to be linked to...
void resize(int m_, int n_)
MatGen()
Null Constructor.
GeneralizedEigenSolver()
Null constructor.
void operator=(const ChebfunMat< T > &in)
Assignment operator.
void compute(const Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > &L_, const Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > &M_, Discretize< std::complex< T > > Dis)
This is used to use a discretization to compute eigenvalues.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > mat_temp
Linop< std::complex< T > > & operator()(int i, int j)
Use this to to refer to Linop. For 2D Matrices, refer to matrix element Linop by (i,j) with the row and column index. Indices start from 0.
void c2p()
Converts every element to phys-space, if not already in phys-space.
Chebfun< T > conj(Chebfun< T > in)
Complex conjugate of a Chebfun.
GeneralizedEigenSolver()
Null constructor.
valarray< T > real(const valarray< complex< T > > &in)
real part of a complex valarray
void resize(int r_, int c_)
This clears all contents in the ChebfunMat, and then creates a fresh ChebfunMat of size r_ x c_...
Linop< T > & operator[](int i)
Use this to to refer to Linops. For 1D Matrices, we use the Row major format when refering to [i]...
Eigen::Matrix< int, Eigen::Dynamic, 1 > MPorNot
This class computes the eigenvalues and eigenvectors (functions) of a Linear operator Linop...
void compute(const LinopMat< T > &Lmat_, const LinopMat< T > &Mmat_, int num_vals, const BcMat< T > &Lbc_)
This will use do the same work as compute(), but will overide all boundary conditions specified throu...
void compute(Eigen::Matrix< std::complex< T >, Eigen::Dynamic, 1 > in, int c)
Computes Mp and numMp for LinopMats.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > subs_mat
void c2p()
Converts a Chebfun from Chebyshev coefficients to values in physical space.
This class will solve the generalized eigenvalue problem for two linear operators. One of them can be singular.
T trunc()
Provides the truncation defined in terms of the abs(last + last_but_one)/2.0.
Chebfun(const Chebfun< std::complex< T > > &in)
Copy constructor.
void operator=(const LinopMat &in)
Assignment operator.
This class stores functions and values needed to sort Eigenvalues.
void operator=(const std::complex< T > &in)
Assignment operator for constant input.
void operator=(const std::valarray< std::complex< T > > &in)
std::vector< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > con_mats
ChebfunMat< T > & operator,(Eigen::Array< T, Eigen::Dynamic, 1 > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type Eigen array.
LinopMat< std::complex< T > > & operator,(Eigen::Array< std::complex< T >, Eigen::Dynamic, 1 > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type Eigen array.
std::valarray< SIS_TYPE > y(N+1)
Eigen::Array< T, Eigen::Dynamic, 1 > evr()
Returns property vr in terms of Eigen::Array.
This class holds a matrix of Chebfuns.
void setConstant(double in)
sets the all the Chebfuns in the ChebfunMat to constant
void resize(int r_, int c_)
This clears all contents in the LinopMat, and then creates a fresh LinopMat of size r_ x c_...
Chebfun< std::complex< T > > & operator()(int i, int j)
Use this to to refer to Chebfuns. For 2D Matrices, refer to matrix element Chebfun by (i...
ChebfunMat< T > & operator,(Chebfun< T > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type Chebfun.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, 1 > eigenvalues
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > vals
Eigen::Matrix< T, Eigen::Dynamic, 1 > integ(const Eigen::Matrix< T, Eigen::Dynamic, 1 > &u)
Chebyshev integration operator for a vector of Chebyshev coefficients.
std::valarray< std::complex< SIS_TYPE > > half_shift(N+1)
void setConstant(std::complex< T > in)
Sets every member in LinopMat to complex constant.
void resize(int r_, int c_)
This clears all contents in the ChebfunMat, and then creates a fresh ChebfunMat of size r_ x c_...
LinopMat< std::complex< T > > & operator,(Linop< std::complex< T > > b)
Overloads comma separator to input Chebfuns into a ChebfunMat. Input type Chebfun.
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > A1
void operator=(const std::valarray< T > &in)
Assignment operator for function input, through valarray.
void operator=(const std::valarray< T > &right)
To assign a Chebfun through a valarray.
Linop< T > conj(Linop< T > in)
void operator=(const Linop< T > &in)
Assignment operator.
Linop< T > & operator()(int i, int j)
Use this to to refer to Linop. For 2D Matrices, refer to matrix element Linop by (i,j) with the row and column index. Indices start from 0.
ChebfunMat(int r_, int c_)
Initializes a Chebfun Matrix of r_ rows and c_ columns.
std::vector< Eigen::Matrix< std::complex< T >, Eigen::Dynamic, Eigen::Dynamic > > con_mats
T operator()(int n, int k)
LinopMat< std::complex< T > > Adjoint(const LinopMat< std::complex< T > > &Lmat_)
Computes the formal adjoint of a Linear operator. This is a differential adjoint, and not the conjuga...
void operator=(const Eigen::Array< T, Eigen::Dynamic, 1 > &in)
Assignment operator for function input, through Eigen array.