TailGF & TailGF::operator *= (const TailGF & t) { const int omin(OrderMin()), omax(OrderMax()); const int new_ordermin(omin+t.OrderMin()); const int new_ordermax(min(omax+t.OrderMax(),OrderMaxMAX)); if (N1!=t.N1 || N2!=t.N2) TRIQS_RUNTIME_ERROR<<"Multiplication is valid only for similar tail shapes !"; if (new_ordermin < OrderMinMIN) TRIQS_RUNTIME_ERROR<<"The multiplication makes the new tail have a too small OrderMin"; Array<COMPLEX,3> newM(Range(OrderMinMIN, OrderMaxMAX), Range(1,N1), Range(1,N2)); Array<COMPLEX,2> tmp(N1, N2, fortranArray); for (int n = new_ordermin; n <= new_ordermax; ++n) { const int kmin(max(0,n-t.OrderMax()-omin)); const int kmax(min(omax-omin,n-t.OrderMin()-omin)); // cout << "n, kmin, kmax" << n << " " << kmin << " " << kmax << endl; for (int k = kmin; k <= kmax; ++k) { matmul_lapack(M(omin+k,ALL,ALL), t.M(n-omin-k,ALL,ALL), tmp); newM(n,ALL,ALL) += tmp; } } OrderMaxArray = new_ordermax; M = newM; return *this; }
void TailGF::invert() { const int omin(OrderMin()), omax(OrderMax()); if (N1!=N2) TRIQS_RUNTIME_ERROR<<"Inversion can only be done for square matrix !"; int new_OrderMin = - omin; if (new_OrderMin <OrderMinMIN) TRIQS_RUNTIME_ERROR<<" I can not inverse with the OrderMinMIN and OrderMaxMAX provided"; int new_OrderMax = min(OrderMaxMAX,omax - omin + new_OrderMin); Array<COMPLEX,3> newM(Range(OrderMinMIN, OrderMaxMAX),Range(0,N1-1),Range(0,N2-1)); //new_OrderMax - new_OrderMin +1,N1,N2); newM=0; Array<COMPLEX,2> tmp(N1,N2,fortranArray),S(N1,N2,fortranArray); Array<COMPLEX,2> M0( newM(new_OrderMin,ALL,ALL)); M0 = M(omin,ALL,ALL); if (!Inverse_Matrix(M0)) TRIQS_RUNTIME_ERROR<<"TailGF::invert : This tail is 0 !!!"; // b_n = - a_0^{-1} * sum_{p=0}^{n-1} b_p a_{n-p} for n>0 // b_0 = a_0^{-1} for (int n = 1; n<=new_OrderMax-new_OrderMin; ++n) { S = 0; for (int p=0; p<n;p++) { matmul_lapack(newM(new_OrderMin + p,ALL,ALL),M(omin+ n-p ,ALL,ALL),tmp); S +=tmp; } matmul_lapack(M0,S,tmp); newM(n+new_OrderMin,ALL,ALL) = -tmp; } M= newM; OrderMaxArray = new_OrderMax; }
/* Test with test.mat, but only with k = 2! (eigen vectors = (0.577, 0.577, 0.5770), (-0.707, 0, 0,707), and a mysterious third? eig values = (12, 6, 0) */ int main(int argc, char *argv[]) { if (argc != 6) { fprintf(stderr, "Error: wrong number of arguments provided. Program expects 5 arguments (k, log(epsilon), filename, matrix dimension n, mode). \n Mode 1 = read from file. Mode 2 = generate matrix. \n\n"); exit(1); } //int k = atoi(argv[1]); double epsilon = (double)atof(argv[2]); char *input = argv[3]; int n = atoi(argv[4]); int mode = atoi(argv[5]); //printf("\nRunning eigP with arguments (%i, %f, %s, %i)\n\n", k, epsilon, input, n); /* Get input matrix A */ double **A = newM(n, n); switch(mode) { case(1): A = readM(input, n, n); break; case(2): A = symRandomM(n); writeM(A, "test.mat", n, n); break; } printM(A, n, n); double **eVecs = newM(n, n); double *eVals = (double *)malloc(sizeof(double)*n); jacobi(A, eVecs, eVals, n, n); eVecs = sortEigenVecs(eVecs, eVals, n, n); // For Power method /*double *eVec1 = powerConverge(A, n, epsilon); printM(&eVec1, 1, n); eVecs = powerConvergeK(A, n, epsilon, k); eVals = eigenVals(A, eVecs, n); */ /* printf("Results:\n\n"); printM(eVecs, n, n); printM(&eVals, 1, n); */ writeM(eVecs, "eVecs.data", n, n); writeM(&eVals, "eVals.data", 1, n); return 0; }
/// Division of a real matrix by an integer number Matrix operator/(const Matrix& first, int second) { Matrix newM(first.n,first.p); REAL invsecond = (REAL)1.0 / second; for(int i=0; i<newM.n*newM.p; i++) { newM.m[i] = first.m[i]*invsecond; } return newM; }
//Rotates around the x axis mat4 rotX(float theta) { mat4 newM ( 1, 0, 0, 0, 0, cos(theta), sin(theta), 0, 0, -sin(theta), cos(theta), 0, 0, 0, 0, 1); return newM; }
//Rotates around the y axis mat4 rotY(float theta) { mat4 newM ( cos(theta), 0, -sin(theta), 0, 0, 1, 0, 0, sin(theta), 0, cos(theta), 0, 0, 0, 0, 1); return newM; }
/// Difference of two real matrices /// if the dimension is different returns the first matrix Matrix operator-(const Matrix& first, const Matrix& second) { int d1 = first.n; int d2 = first.p; if(d1!=second.n || d2!=second.p) return first; Matrix newM(d1,d2); for(int i=0; i<d1*d2; i++) { newM.m[i] = (first.m[i] - second.m[i]); } return newM; }
/// Multiplication of two real matrices /// if the dimension is incompatible returns the first matrix Matrix operator*(const Matrix& first, const Matrix& second) { int d1 = first.n; int d = first.p; int d2 = second.p; if(d!=second.n) return first; Matrix newM(d1,d2); for(int i=0; i<d1; i++) { for(int j=0; j<d2; j++) { for(int k=0; k<d; k++) { newM.m[i*d2+j] += (first.m[i*d+k])*second.m[k*d2+j]; } } } return newM; }