//We can split this into a part for each l and just build the subspaces, and we already have the permutation matrix so msym_error_t findProjection(CharacterTable *ct, int sopsl, msym_symmetry_operation_t sops[sopsl], msym_permutation_t perm[sopsl], int l, msym_orbital_t *basis[2*l+1]){ msym_error_t ret = MSYM_SUCCESS; int kdim = ipow(3,l), setl = perm[0].p_length; double (*mkron)[kdim] = malloc(sizeof(double[kdim][kdim])); double (*mperm)[setl] = malloc(sizeof(double[setl][setl])); for(int m = 0; m < 2*l+1;m++){ permutationMatrix(&perm[m], mperm); } free(mperm); free(mkron); return ret; }
arma::mat OneSampleGetPermutationMatrix(int nPermutations, int N) { arma::arma_rng::set_seed_random(); // set the seed to a random value int cutoff; bool cutoffOne = false; arma::mat indexList; arma::mat permutationMatrix(nPermutations, N, arma::fill::ones); indexList = arma::linspace<arma::mat>(0, N-1, N); indexList = arma::shuffle(indexList); for(int i = 0;i < nPermutations;i++) { cutoff = indexList(0,0); indexList = arma::shuffle(indexList); for(int j = 0;j < cutoff;j++) { permutationMatrix(i, indexList(j,0)) = -1; } } return permutationMatrix; }
bool InvertMatrix(const floatMatrix& inputMatrix, floatMatrix& inverseMatrix) { typedef ublas::permutation_matrix<std::size_t> permutation_matrix_t; ublas::matrix<float> matrix(inputMatrix); permutation_matrix_t permutationMatrix(matrix.size1()); auto det = ublas::lu_factorize(matrix, permutationMatrix); if (det != 0) { return false; } inverseMatrix.assign(ublas::identity_matrix<float>(matrix.size1())); ublas::lu_substitute(matrix, permutationMatrix, inverseMatrix); return true; }
arma::mat OneSamplePermTestingCPU(arma::mat data, int nPermutations, double maxMemory) { std::string permMatrixPath = "/Users/felipegb94/PermTest/data/face/PermutationMatrix.arma"; int N; // Total number of subjects int V; // Total number of statistics/voxels to be tested int nPermutationsPerIteration; // Number of permutations done at once int numIterations; // nPermutations/nPermutationsPerIteration int lastIteration; int start, end; // Start and end of current interval arma::mat permutationMatrix; arma::mat maxT; // Maximum null distribution arma::mat dataSquared; arma::mat gMean; arma::mat gVar; arma::mat tStatMatrix; /* Set constant values and allocate memory */ N = data.n_rows; V = data.n_cols; //permutationMatrix.load(permMatrixPath); permutationMatrix = OneSampleGetPermutationMatrix(nPermutations, N); dataSquared = data % data; nPermutationsPerIteration = GetIntervalDimension(V, maxMemory); lastIteration = nPermutations % nPermutationsPerIteration; numIterations = floor(nPermutations/nPermutationsPerIteration); maxT = arma::zeros(nPermutations,1); std::cout << "Number of subjects (rows in data matrix): " << N << std::endl; std::cout << "Number of voxels per subject (cols in data matrix and cols in indexMatrix): "; std::cout << V << std::endl; std::cout << "Number of Permutations (rows in permutations matrix):" << nPermutations << std::endl; std::cout << "Rows in permutationMatrix = " << permutationMatrix.n_rows << std::endl; std::cout << "Cols in permutationMatrix = " << permutationMatrix.n_cols << std::endl; std::cout << "Interval Size = " << nPermutationsPerIteration << std::endl; std::cout << "Number of Passes = " << numIterations << std::endl; std::cout << "Last Iteration = " << lastIteration << std::endl; int i = 0; arma::mat varTerm1 = repmat(arma::sum(dataSquared,0), nPermutationsPerIteration,1)/N; arma::mat varTerm1LastItr = repmat(arma::sum(dataSquared,0), lastIteration, 1)/N; std::cout << "VarTerm rows " << varTerm1LastItr.n_rows << std::endl; std::cout << "VarTerm cols " << varTerm1LastItr.n_cols << std::endl; /* Permutation loop */ #if OPENMP_ENABLED #pragma omp parallel for #endif for(i = 0;i < numIterations;i++) { start = nPermutationsPerIteration * i; end = (nPermutationsPerIteration * i) + nPermutationsPerIteration - 1; printf("Iteration %d , start %d, end %d of %d \n", i, start, end, nPermutations-1); gMean = (permutationMatrix(arma::span(start,end), arma::span::all) * data) / N; gVar = (varTerm1) - (gMean % gMean); tStatMatrix = (gMean) / sqrt(gVar/(N-1)); maxT(arma::span(start,end),arma::span::all) = arma::max(tStatMatrix,1); } if(lastIteration != 0) { start = nPermutationsPerIteration * i; end = nPermutations - 1; printf("Iteration %d , start %d, end %d of %d \n", i, start, end, nPermutations-1); gMean = (permutationMatrix(arma::span(start,end), arma::span::all) * data) / N; gVar = varTerm1LastItr - (gMean % gMean); tStatMatrix = (gMean) / sqrt(gVar/(N-1)); maxT(arma::span(start,end),arma::span::all) = arma::max(tStatMatrix,1); } std::string prefix = "OneSampleMaxT_CPU"; SaveMaxT(maxT, nPermutations, prefix); return maxT; }
msym_error_t generateOrbitalSubspaces(msym_point_group_t *pg, int esl, msym_equivalence_set_t *es, msym_permutation_t **perm, int basisl, msym_orbital_t basis[basisl], msym_thresholds_t *thresholds, int *subspacel, msym_subspace_t **subspace, int **pspan){ msym_error_t ret = MSYM_SUCCESS; int lmax = -1, nmax = -1, eslmax = -1; for(int i = 0;i < basisl;i++){ lmax = basis[i].l > lmax ? basis[i].l : lmax; nmax = basis[i].n > nmax ? basis[i].n : nmax; } if(lmax < 0){ret = MSYM_INVALID_ORBITALS; return ret;} //if we goto err here, code will get ugly due to scope for(int i = 0;i < esl;i++) eslmax = es[i].length > eslmax ? es[i].length : eslmax; struct _ltransforms {int d; void *t;} *lts = calloc(lmax+1,sizeof(struct _ltransforms)); double (*mkron)[(2*lmax+1)*pg->order] = malloc(sizeof(double[(2*lmax+1)*pg->order][(2*lmax+1)*pg->order])); double (*mperm)[pg->order] = malloc(sizeof(double[pg->order][pg->order])); double (*mproj)[pg->ct->l+1][(2*lmax+1)*pg->order][(2*lmax+1)*pg->order] = malloc(sizeof(double[lmax+1][pg->ct->l+1][(2*lmax+1)*pg->order][(2*lmax+1)*pg->order])); double (*lspan)[pg->ct->l] = malloc(sizeof(double[lmax+1][pg->ct->l])); int (*ispan) = calloc(pg->ct->l,sizeof(int)); int *aspan = calloc(pg->ct->l,sizeof(int)); int *nl = malloc(sizeof(int[lmax+1])); msym_orbital_t *(*omap)[nmax][lmax][2*lmax+1] = malloc(sizeof(msym_orbital_t *[eslmax][nmax+1][lmax+1][2*lmax+1])); *subspace = NULL; msym_subspace_t *iss = calloc(pg->ct->l, sizeof(msym_subspace_t)); for(int k = 0;k < pg->ct->l;k++){ iss[k].type = ATOMIC_ORBITAL; iss[k].irrep = k; iss[k].subspacel = esl; iss[k].subspace = calloc(esl, sizeof(msym_subspace_t)); } for(int l = 0; l <= lmax;l++){ lts[l].d = 2*l+1; lts[l].t = malloc(sizeof(double[pg->sopsl][lts[l].d][lts[l].d])); if(MSYM_SUCCESS != (ret = generateOrbitalTransforms(pg->sopsl, pg->sops, l, lts[l].t))) goto err; } for(int i = 0; i < esl;i++){ int esilmax = -1, esinmax = -1; memset(nl,0,sizeof(int[lmax+1])); for(int j = 0;j < es[i].elements[0]->aol;j++){ esilmax = esilmax < es[i].elements[0]->ao[j]->l ? es[i].elements[0]->ao[j]->l : esilmax; esinmax = esinmax < es[i].elements[0]->ao[j]->n ? es[i].elements[0]->ao[j]->n : esinmax; nl[es[i].elements[0]->ao[j]->l] += es[i].elements[0]->ao[j]->m == 0; } msym_orbital_t *(*esomap)[esinmax+1][esilmax+1][2*esilmax+1] = omap; memset(esomap,0,sizeof(msym_orbital_t *[es->length][esinmax+1][esilmax+1][2*esilmax+1])); for(int a = 0;a < es[i].length;a++){ for(int ao = 0;ao < es[i].elements[a]->aol;ao++){ msym_orbital_t *o = es[i].elements[a]->ao[ao]; esomap[a][o->n][o->l][o->m+o->l] = o; } } memset(lspan,0,sizeof(double[lmax+1][pg->ct->l])); for(int l = 0;l <= esilmax;l++){ int d = es[i].length*lts[l].d; double (*mlproj)[d][d] = mproj[l]; memset(mlproj,0,sizeof(double[pg->ct->l][d][d])); memset(ispan,0,sizeof(int[pg->ct->l])); for(int s = 0;s < pg->sopsl;s++){ double (*lt)[lts[l].d][lts[l].d] = lts[l].t; permutationMatrix(&perm[i][s], mperm); kron(perm[i][s].p_length,mperm,lts[l].d,lt[s],d,mkron); //printSymmetryOperation(&pg->sops[s]); //printTransform(d, d, mkron); for(int k = 0;k < pg->ct->l;k++){ lspan[l][k] += pg->ct->irrep[k].v[pg->sops[s].cla]*mltrace(d, mkron); mlscale(pg->ct->irrep[k].v[pg->sops[s].cla], d, mkron, mlproj[pg->ct->l]); //mproj[pg->ct.l] is a workspace mladd(d, mlproj[pg->ct->l], mlproj[k], mlproj[k]); //Could do this based on the span later, but it's not a huge amount of work } } memset(mlproj[pg->ct->l],0,sizeof(double[d][d])); int nirrepl = 0; for(int k = 0;k < pg->ct->l;k++){ int lirrepl = nirrepl; msym_subspace_t *ss = &iss[k].subspace[i]; ispan[k] = (((int)round(lspan[l][k]))/pg->order); mlscale(((double) pg->ct->irrep[k].d)/pg->order, d, mlproj[k], mlproj[k]); nirrepl = mgs(d, mlproj[k], mlproj[pg->ct->l], nirrepl, thresholds->orthogonalization/basisl); if(nirrepl - lirrepl != ispan[k]*pg->ct->irrep[k].d){ //printTransform(d, d, mlproj[k]); ret = MSYM_ORBITAL_ERROR; msymSetErrorDetails("Ortogonal subspace of dimension (%d) inconsistent with span (%d) in %s",nirrepl - lirrepl,ispan[k]*pg->ct->irrep[k].d,pg->ct->irrep[k].name); goto err; } ss->type = ATOMIC_ORBITAL; ss->irrep = k; if(ispan[k] > 0){ ss->subspace = realloc(ss->subspace, sizeof(msym_subspace_t[ss->subspacel+nl[l]])); for(int n = l+1; n <= esinmax;n++){ if(esomap[0][n][l][0] == NULL) continue; aspan[k] += ispan[k]*pg->ct->irrep[k].d; msym_subspace_t *nss = &ss->subspace[ss->subspacel]; memset(nss,0,sizeof(msym_subspace_t)); nss->type = ATOMIC_ORBITAL; nss->irrep = ss->irrep; nss->d = ispan[k]*pg->ct->irrep[k].d; double (*space)[d] = malloc(sizeof(double[nss->d][d])); for(int dim = 0; dim < ss->subspace[ss->subspacel].d;dim++){ vlnorm2(d, mlproj[pg->ct->l][lirrepl+dim], space[dim]); } nss->space = (double*) space; nss->basisl = 0; nss->basis.o = malloc(sizeof(msym_orbital_t *[d])); for(int e = 0;e < es[i].length;e++){ for(int m = -l;m <= l;m++){ nss->basis.o[nss->basisl++] = esomap[e][n][l][m+l]; } } ss->subspacel++; if(nss->basisl != d) { ret = MSYM_ORBITAL_ERROR; msymSetErrorDetails("Basis length (%d) inconsistent with projection operator dimensions (%d)",nss->basisl,d); goto err; } } } } } } printf("Subspace span (vectors) = "); for(int k = 0;k < pg->ct->l;k++){ printf(" + %d%s",aspan[k],pg->ct->irrep[k].name); } printf("\n"); msym_subspace_t tss = {.subspacel = pg->ct->l, .subspace = iss, .d = 0, .basisl = 0, .space = NULL}; filterSubspace(&tss); *subspace = tss.subspace; *subspacel = tss.subspacel; *pspan = aspan; free(omap); free(nl); free(ispan); free(lspan); free(mproj); free(mperm); free(mkron); for(int l = 0;l <= lmax;l++){ free(lts[l].t); } free(lts); return ret; err: free(aspan); free(omap); free(nl); free(ispan); free(lspan); free(mproj); free(mperm); free(mkron); for(int l = 0;l < lmax;l++){ free(lts[l].t); } free(lts); for(int k = 0;k < pg->ct->l;k++){ freeSubspace(&iss[k]); } free(iss); return ret; } msym_error_t getOrbitalSubspaces(int ssl, msym_subspace_t ss[ssl], int basisl, msym_orbital_t basis[basisl], double c[basisl][basisl]){ msym_error_t ret = MSYM_SUCCESS; int index = 0; memset(c,0,sizeof(double[basisl][basisl])); for(int i = 0;i < ssl;i++){ if(MSYM_SUCCESS != (ret = getOrbitalSubspaceCoefficients(&ss[i],basisl,basis,&index,c))) goto err; } if(index != basisl){ msymSetErrorDetails("Subspace index (%d) does not match basis length (%d)",index,basisl); ret = MSYM_INVALID_SUBSPACE; goto err; } return ret; err: return ret; }