double dlognormal(double *x, double *mean, double **var,int len) { // The log density of the multivariate normal distribution // (-nrow(y)/2)*log(2*pi)-0.5*log(det(cov))-0.5*t(y-mean)%*%solve(cov)%*%(y-mean) double dens,determinant,**invvar,**vartemp,bigsum=0; int i,j; vartemp = (double **)calloc(len, sizeof(double *)); for (i=0;i<len;i++) { vartemp[i] = (double *)calloc(len, sizeof(double)); } for(i=0;i<len;i++) { for(j=0;j<len;j++) { vartemp[i][j]=var[i][j]; } } determinant = deter(vartemp,len); invvar = generate_identity(len); GaussJordan(len,var,invvar); for(i=0;i<len;i++) { for(j=0;j<len;j++) { bigsum += (x[j]-mean[j])*(x[i]-mean[i])*invvar[i][j]; } } dens = -(double)len/2 * log(2*PI) - 0.5*log(determinant)-0.5*bigsum; return(dens); }
/* Perform the least square fitting of (Ax-b)^2 where A is a n by m matrix, b is a n-vector and x is a m-vector. */ std::vector<double> LeastSquaresFitting(const std::vector<double>& A, const std::vector<double>& b, int m, bool& bSuccess) { std::vector<double> M(m*m); std::vector<double> y(m); int n = b.size(); for(int i=0; i<m; ++i) { for(int j=0; j<m; ++j) { double sum = 0; for(int k=0; k<n; ++k) { sum += A[i+m*k] * A[j+m*k]; } M[i*m+j] = sum; } } for(int i=0; i<m; ++i) { double sum = 0; for(int k=0; k<n; ++k) { sum += A[i+m*k] * b[k]; } y[i] = sum; } bSuccess = GaussJordan(M, y, m); return y; }
/* ---------------------------------------------------------------------------- * private method to convert the cartisan coordinate of basis into fractional * ---------------------------------------------------------------------------- */ void DynMat::car2dir() { double mat[9]; for (int idim = 0; idim < 9; ++idim) mat[idim] = basevec[idim]; GaussJordan(3, mat); for (int i = 0; i < nucell; ++i){ double x[3]; x[0] = x[1] = x[2] = 0.; for (int idim = 0; idim < sysdim; idim++) x[idim] = basis[i][idim]; for (int idim = 0; idim < sysdim; idim++) basis[i][idim] = x[0]*mat[idim] + x[1]*mat[3+idim] + x[2]*mat[6+idim]; } return; }
/* ---------------------------------------------------------------------------- * private method to convert the cartisan coordinate of basis into fractional * ---------------------------------------------------------------------------- */ void DynMat::car2dir(int flag) { if (!flag) { // in newer version, this is done in fix-phonon for (int i=0; i<3; i++) { basevec[i] /= double(nx); basevec[i+3] /= double(ny); basevec[i+6] /= double(nz); } } double mat[9]; for (int idim=0; idim<9; idim++) mat[idim] = basevec[idim]; GaussJordan(3, mat); for (int i=0; i<nucell; i++) { double x[3]; x[0] = x[1] = x[2] = 0.; for (int idim=0; idim<sysdim; idim++) x[idim] = basis[i][idim]; for (int idim=0; idim<sysdim; idim++) basis[i][idim] = x[0]*mat[idim] + x[1]*mat[3+idim] + x[2]*mat[6+idim]; } return; }
int main(int narg, char *arg[]) { int iarg, nspec, npts, i; double *specx, *specy, *specd; double *ptx, *pty, *ptd; double_complex mat[MAX_DYN_DIM_SQ]; char *specsym, *stifffn, *gffn; StiffnessKernel *kernel; Domain domain; Error error; Memory memory(&error); FILE *f; /* --- */ domain.xprd = 1.0; domain.yprd = 1.0; domain.zprd = 1.0; if (narg < 4) { printf("Syntax: eval_stiffness <filename with special points> " "<stiffness filename> <greens functions filename> " "<number of band points> <kernel> <kernel parameters>\n"); exit(999); } /* nspec = atoi(arg[1]); specsym = (char *) malloc(nspec*sizeof(char)); specx = (double *) malloc(nspec*sizeof(double)); specy = (double *) malloc(nspec*sizeof(double)); specd = (double *) malloc(nspec*sizeof(double)); */ iarg = 1; f = fopen(arg[iarg], "r"); if (!f) { printf("Error opening %s.\n", arg[iarg]); exit(999); } iarg++; fscanf(f, "%i", &nspec); specsym = (char *) malloc(nspec*SYM_LEN*sizeof(char)); specx = (double *) malloc(nspec*sizeof(double)); specy = (double *) malloc(nspec*sizeof(double)); specd = (double *) malloc(nspec*sizeof(double)); for (i = 0; i < nspec; i++) { fscanf(f, "%s%lf%lf", &specsym[i*SYM_LEN], &specx[i], &specy[i]); } fclose(f); stifffn = arg[iarg]; iarg++; gffn = arg[iarg]; iarg++; npts = atoi(arg[iarg]); iarg++; if (npts <= nspec) { printf("Number of band points must be larger that number of special " "points.\n"); exit(999); } iarg++; kernel = stiffness_kernel_factory(arg[iarg-1], narg, &iarg, arg, &domain, &memory, &error); if (!kernel) { printf("Could not find stiffness kernel %s.\n", arg[iarg-1]); exit(999); } ptx = (double *) malloc(npts*sizeof(double)); pty = (double *) malloc(npts*sizeof(double)); ptd = (double *) malloc(npts*sizeof(double)); band_lines(nspec, specx, specy, specd, npts, ptx, pty, ptd); /* * stiffness.out */ f = fopen(stifffn, "w"); if (!f) { printf("Error opening %s.\n", stifffn); exit(999); } fprintf(f, "# dist qx qy"); int dim = kernel->get_dimension(); i = 4; for (int k = 0; k < dim; k++) for (int l = 0; l < dim-k; l++) { fprintf(f, " %i:mat%i%i", i, l+1, l+k+1); i += 2; } fprintf(f, "\n"); for (i = 0; i < npts; i++) { kernel->get_stiffness_matrix(2*M_PI*ptx[i], 2*M_PI*pty[i], mat); fprintf(f, "%e %e %e", ptd[i], ptx[i], pty[i]); for (int k = 0; k < dim; k++) for (int l = 0; l < dim-k; l++) fprintf(f, " %e %e", creal(MEL(dim, mat, l, l+k)), cimag(MEL(dim, mat, l, l+k))); fprintf(f, "\n"); } fclose(f); /* * greens_function.out */ f = fopen(gffn, "w"); if (!f) { printf("Error opening %s.\n", gffn); exit(999); } fprintf(f, "# dist qx qy"); dim = kernel->get_dimension(); i = 4; for (int k = 0; k < dim; k++) for (int l = 0; l < dim-k; l++) { fprintf(f, " %i:mat%i%i", i, l+1, l+k+1); i += 2; } fprintf(f, "\n"); for (i = 0; i < npts; i++) { kernel->get_stiffness_matrix(2*M_PI*ptx[i], 2*M_PI*pty[i], mat); GaussJordan(dim, mat, &error); fprintf(f, "%e %e %e", ptd[i], ptx[i], pty[i]); for (int k = 0; k < dim; k++) for (int l = 0; l < dim-k; l++) fprintf(f, " %e %e", creal(MEL(dim, mat, l, l+k)), cimag(MEL(dim, mat, l, l+k))); fprintf(f, "\n"); } fclose(f); f = fopen("specpoints.out", "w"); fprintf(f, "# symbol dist qx qy\n"); for (i = 0; i < nspec; i++) { // fprintf(f, "%c %e %e %e\n", specsym[i], specd[i], specx[i], specy[i]); fprintf(f, "%s %e %e %e\n", &specsym[i*SYM_LEN], specd[i], specx[i], specy[i]); } fclose(f); free(specsym); free(specx); free(specy); free(specd); free(ptx); free(pty); free(ptd); }
void transform_coord_3D_2D(int nvertex_net, struct vertex_net VERTEX_net[]) { int i; int n_gj, m_gj; /*arguments of the fct. 'GaussJordan()'*/ double ROT[3][3]; /* rotation matrix: spherical rotation of a cartesian coordinate system */ double B_GJ[3][3]; /*arguments of the fct. 'GaussJordan()'*/ struct point a, b, c, n, origin_K1, hpt; /**************************************************************************/ /* Serach for the corner nodes of the quadrilateral subplane3D */ /* --> VERTEX_net[0] ... VERTEX_net[3] are the corner nodes */ /* */ /* Calculate the norm vector (vector product) */ /* n = (VERTEX_net[1]-VERTEX_net[0]) x (VERTEX_net[3]-VERTEX_net[0]) */ /* n = ( a ) x ( b ) */ /* */ /* The axis (x1, y1, z1) of the new cartesian coordinate system K_1 */ /* x1 = a */ /* y1 = ... vector product y1 = (n) x (a) */ /* z1 = n */ /* */ /* What about vector b? Vector a and b are not directily othogonal! */ /* */ /**************************************************************************/ a.x = VERTEX_net[1].pt.x - VERTEX_net[0].pt.x; a.y = VERTEX_net[1].pt.y - VERTEX_net[0].pt.y; a.z = VERTEX_net[1].pt.z - VERTEX_net[0].pt.z; b.x = VERTEX_net[3].pt.x - VERTEX_net[0].pt.x; b.y = VERTEX_net[3].pt.y - VERTEX_net[0].pt.y; b.z = VERTEX_net[3].pt.z - VERTEX_net[0].pt.z; n.x = a.y*b.z - a.z*b.y; n.y = -a.x*b.z + a.z*b.x; n.z = a.x*b.y - a.y*b.x; c.x = n.y*a.z - n.z*a.y; c.y = -n.x*a.z + n.z*a.x; c.z = n.x*a.y - n.y*a.x; /******** c.x = a.y*n.z - a.z*n.y; c.y = -a.x*n.z + a.z*n.x; c.z = a.x*n.y - a.y*n.x; *********/ /**************************************************************************/ /* Transformation: the origin of the old coordinates system K^0 is */ /* transformed to the point 'origin_K1'. */ /* --> point 'origin_K1' = origin of the coordinate system K^1 */ /* */ /* v.x VERTEX_net[0].pt.x origin_K1.x */ /* transformation vector v = v.y = VERTEX_net[0].pt.y = origin_K1.y */ /* v.z VERTEX_net[0].pt.z origin_K1.z */ /* */ /* transformation node[].x_neu = node[].x_alt - v.x */ /* (in general) node[].y_neu = node[].y_alt - v.y */ /* node[].z_neu = node[].z_alt - v.z */ /* */ /**************************************************************************/ origin_K1 = VERTEX_net[0].pt; for (i=0; i<nvertex_net; i++) { VERTEX_net[i].pt.x = VERTEX_net[i].pt.x - origin_K1.x; VERTEX_net[i].pt.y = VERTEX_net[i].pt.y - origin_K1.y; VERTEX_net[i].pt.z = VERTEX_net[i].pt.z - origin_K1.z; } origin_K1.x = 0.0; /*new coordinate values for the origin point of K^1*/ origin_K1.y = 0.0; origin_K1.z = 0.0; /**************************************************************************/ /* Rotation: cartesian coordinate system K^1 is rotated into the new */ /* cartesian coordinate system K^2. */ /* */ /* Rotation of the point node[] around the origin 'origin_K1' */ /* with the inverse matrix of the rotation matrix ROT[][]. */ /* */ /* 1.) Calculation of the rotation matrix ROT[][] */ /* */ /* Comment to the calculation of the rotation matrix: */ /* Calculate the spherical rotation matrix of a cartesian coordinate */ /* system around its origin. Therefor, nine angles has to be calculated. */ /* (see: Bronstein, p. 217) */ /* */ /* 2.) Calculation of the inverse rotation matrix ROT[][] */ /* Applying the Gauss-Jordan elimination method. */ /* --> Hereby, the matrix ROT[][] is replaced by its inverse matrix */ /* */ /* 3.) Rotation of all points node[] */ /* */ /**************************************************************************/ RotationMatrix3D(origin_K1, a, c, n, ROT); n_gj = m_gj = 3; GaussJordan(ROT, B_GJ, n_gj, m_gj); /*Gauss-Jordan elimination method*/ for (i=0; i<nvertex_net; i++) { hpt = VERTEX_net[i].pt; VERTEX_net[i].pt.x = hpt.x*ROT[0][0] + hpt.y*ROT[0][1] + hpt.z*ROT[0][2]; VERTEX_net[i].pt.y = hpt.x*ROT[1][0] + hpt.y*ROT[1][1] + hpt.z*ROT[1][2]; VERTEX_net[i].pt.z = hpt.x*ROT[2][0] + hpt.y*ROT[2][1] + hpt.z*ROT[2][2]; } }