int is_mirror_image(double* X, int X_dim0, int X_dim1, int X_dim1_mem, double* Y, int Y_dim0, int Y_dim1, int Y_dim1_mem) { // Check if two configurations X and Y are mirror images // (i.e. does their optimal superposition involve a reflection?) // // Parameters // ---------- // X : double*, shape=(X_dim0, X_dim1) // Pointer to the upper left corner of matrix X. // X_dim0 : int // The number of rows in matrix X. Should be 3. // X_dim1 : int // The number of columns in matrix X. Corresponds to number of atoms // X_dim1_mem : int // number of columns of X in memory. corresponds to the number of padded atoms. // such that the (i,j)-th element of X is accessed at X[i*X_dim1*mem + j] // Y : double*, shape=(X_dim0, X_dim1) // Pointer to the upper left corner of matrix X. // Y_dim0 : int // The number of rows in matrix Y. Should be 3. // Y_dim1 : int // The number of columns in matrix Y. Corresponds to number of atoms // Y_dim1_mem : int // number of columns of Y in memory. corresponds to the number of padded atoms. // such that the (i,j)-th element of Y is accessed at Y[i*Y_dim1*mem + j] // // // Returns // ------- // mirror : int // = 1 if they are mirror images // = 0 if they are not mirror images if ((X_dim0 != Y_dim0) || (X_dim1 != Y_dim1) || (X_dim0 != 3)){ fprintf(stderr, "is_mirror_image called with wrong shape\n"); exit(1); } // covariance = np.dot(X, Y.T) gsl_matrix* covariance = gsl_matrix_alloc(3, 3); gsl_matrix_view mX = gsl_matrix_view_array_with_tda(X, X_dim0, X_dim1, X_dim1_mem); gsl_matrix_view mY = gsl_matrix_view_array_with_tda(Y, Y_dim0, Y_dim1, Y_dim1_mem); gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, &mX.matrix, &mY.matrix, 0.0, covariance); gsl_matrix* U = gsl_matrix_alloc(3, 3); gsl_vector* S = gsl_vector_alloc(3); gsl_vector* work = gsl_vector_alloc(3); gsl_linalg_SV_decomp(covariance, U, S, work); double determinant = ddet(covariance->data) * ddet(U->data); gsl_matrix_free(covariance); gsl_matrix_free(U); gsl_vector_free(S); gsl_vector_free(work); return determinant < 0; }
/* Multivariate Normal density */ double dMVN( double *Y, /* The data */ double *MEAN, /* The parameters */ double **SIG_INV, /* inverse of the covariance matrix */ int dim, /* dimension */ int give_log){ /* 1 if log_scale 0 otherwise */ int j,k; double value=0.0; for(j=0;j<dim;j++){ for(k=0;k<j;k++) value+=2*(Y[k]-MEAN[k])*(Y[j]-MEAN[j])*SIG_INV[j][k]; value+=(Y[j]-MEAN[j])*(Y[j]-MEAN[j])*SIG_INV[j][j]; } value=-0.5*value-0.5*dim*log(2*M_PI)+0.5*ddet(SIG_INV, dim, 1); if(give_log) return(value); else return(exp(value)); }