double SpinAdapted::rowdoubleproduct(Matrix& a, int rowa, Matrix& b, int rowb) { assert(a.Ncols() == b.Ncols()); double* aptr = a.Store() + a.Ncols() * rowa; double* bptr = b.Store() + b.Ncols() * rowb; return DDOT(a.Ncols(), aptr, 1, bptr, 1); }
void QRZ(const Matrix& X, Matrix& Y, Matrix& M) { REPORT Tracer et("QRZ(2)"); int n = X.Nrows(); int s = X.Ncols(); int t = Y.Ncols(); if (Y.Nrows() != n) { Throw(ProgramException("Unequal column lengths",X,Y)); } M.resize(s,t); M = 0;Real* m0 = M.Store(); Real* m; Real* xi0 = X.Store(); int j, k; int i = s; while (i--) { Real* xj0 = Y.Store(); Real* xi = xi0; k = n; if (k) for (;;) { m = m0; Real Xi = *xi; Real* xj = xj0; j = t; while(j--) *m++ += Xi * *xj++; if (!(--k)) break; xi += s; xj0 += t; } xj0 = Y.Store(); xi = xi0++; k = n; if (k) for (;;) { m = m0; Real Xi = *xi; Real* xj = xj0; j = t; while(j--) *xj++ -= *m++ * Xi; if (!(--k)) break; xi += s; xj0 += t; } m0 += t; } }
double SpectClust::calcNormalizedCut(const Matrix &D, const std::vector<std::pair<double,int> > &indices, int cut) { double assocA = 0, assocB = 0, cutAB = 0; // count up weight of A nodes connected to B nodes. for(int aIx = 0; aIx < cut; aIx++) { int Aindex = indices[aIx].second; for(int colIx = cut; colIx < indices.size(); colIx++) { int Bindex = indices[colIx].second; if(Aindex == Bindex) { Err::errAbort("How can " +ToStr(Aindex) + " be in both the a and b index?"); } cutAB += D.element(Aindex,Bindex); } } // Count up connectivity of A to entire graph. for(int aIx = 0; aIx < cut; aIx++) { int Aindex = indices[aIx].second; for(int colIx = 0; colIx < D.Ncols(); colIx++) { assocA += D.element(Aindex, colIx); } } // Count up connectivity of B to entire graph. for(int bIx = cut; bIx < D.Nrows(); bIx++) { int Bindex = indices[bIx].second; for(int colIx = 0; colIx < D.Ncols(); colIx++) { assocB += D.element(Bindex, colIx); } } double nCut = DBL_MAX; if(assocA != 0 && cutAB != 0 && assocB != 0) nCut = (cutAB/assocA + cutAB/assocB); return nCut; }
int Rank(Matrix A) { // The SVD routine in NEWMAT assume #rows >= #cols in A // if #rows < #cols, then we compute the SVD of the transpose of A if (A.Nrows() >= A.Ncols()) { DiagonalMatrix D(A.Ncols()); SVD(A, D); int rank = 0; for (int i = 1; i <= A.Ncols(); i++) if (abs(D(i)) > EPSILON) rank++; return (rank); } else { DiagonalMatrix D(A.Nrows()); SVD(A.t(), D); int rank = 0; for (int i = 1; i <= A.Nrows(); i++) if (abs(D(i)) > EPSILON) rank++; return (rank); } }
double SpectClust::rowMedian(const Matrix &M, int rowIx) { std::vector<double> r(M.Ncols(),0); for(int i = 0; i < M.Ncols(); i++) { r[i] = M.element(rowIx,i); } double med = median_in_place(r.begin(), r.end()); return med; }
double SpinAdapted::MatrixDotProduct(const Matrix& a, const Matrix& b) { assert((a.Nrows() == b.Nrows()) && (a.Ncols() == b.Ncols())); #ifdef BLAS return DDOT(a.Storage(), a.Store(), 1, b.Store(), 1); #else abort(); #endif }
//Predict on a chunk of data. ReturnMatrix SOGP::predictM(const Matrix& in, ColumnVector &sigconf,bool conf){ //printf("SOGP::Predicting on %d points\n",in.Ncols()); Matrix out(alpha.Ncols(),in.Ncols()); sigconf.ReSize(in.Ncols()); for(int c=1;c<=in.Ncols();c++) out.Column(c) = predict(in.Column(c),sigconf(c),conf); out.Release(); return out; }
Matrix argpermute(const Matrix& m, const int* indices) { Matrix newm(m.Nrows(),m.Ncols()); newm=0.; for (int i=0;i<m.Nrows();++i) for (int j=0;j<m.Ncols();++j) newm.element(i,j)=m.element(indices[i],indices[j]); return newm; }
void SpectClust::fillInDistance(SymmetricMatrix &A, const Matrix &M, const DistanceMetric &dMetric, bool expon) { A.ReSize(M.Ncols()); for(int i = 1; i <= M.Ncols(); i++) { for(int j = i; j <= M.Ncols(); j++) { if(expon) A(j,i) = A(i,j) = exp(-1 * dMetric.dist(M,i,j)); else A(j,i) = A(i,j) = dMetric.dist(M,i,j); } } }
void copy(const Matrix& a, Matrix& b) { if ((b.Nrows() != a.Nrows()) || (b.Ncols() != a.Ncols())) b.ReSize(a.Nrows(), a.Ncols()); #ifdef BLAS DCOPY((FORTINT) a.Storage(), a.Store(), (FORTINT) 1, b.Store(), (FORTINT) 1); #else b = a; #endif }
void SpinAdapted::MatrixMultiply (double d, const Matrix& a, Matrix& b) { // b += d * a; #ifdef BLAS assert ((a.Nrows () == b.Nrows ()) && (a.Ncols () == b.Ncols ())); int n = a.Nrows () * a.Ncols (); GAXPY (n, d, a.Store (), 1, b.Store (), 1); #else b += d * a; #endif }
void SpinAdapted::MatrixScaleAdd (double d, const Matrix& a, Matrix& b) { assert (a.Nrows () == b.Nrows () && a.Ncols () == b.Ncols ()); #ifdef BLAS int n = a.Nrows () * a.Ncols (); assert (n == (b.Nrows () * b.Ncols ())); DAXPY (n, d, a.Store (), 1, b.Store (), 1); #else b += d * a; #endif }
/** Mutilply each element individually and return matrix. */ Matrix elementMultiplication(Matrix &x, Matrix &y) { assert(x.Nrows() == y.Nrows()); assert(x.Ncols() == y.Ncols()); Matrix m(x.Nrows(), x.Ncols()); for(unsigned int i = 0; i < x.Nrows(); i++) { for(unsigned int j = 0; j < x.Ncols(); j++) { m.element(i,j) = x.element(i,j) * y.element(i,j); } } return m; }
void SpectClust::multByMatrix(ColumnVector &N, ColumnVector &O, const Matrix &M) { int nRow = M.Nrows(), nCol = M.Ncols(); if(!(N.Nrows() == O.Nrows() && M.Nrows() == M.Ncols() && M.Nrows() == N.Nrows())) { Err::errAbort("wrong dimensions: " + ToStr(O.Nrows()) + " " + ToStr(N.Nrows()) + " " + ToStr(M.Nrows())); } for(int rowIx = 0; rowIx < nRow; rowIx++) { N[rowIx] = 0; for(int colIx = 0; colIx < nCol; colIx++) { N[rowIx] += O[colIx] * M[rowIx][colIx]; } } }
void SpinAdapted::CatenateProduct (const ObjectMatrix<Matrix*>& a, Matrix& b, bool allocate) { try { std::vector<int> indexRows (a.Nrows ()); std::vector<int> indexCols (a.Ncols ()); int rowLength = 0; int colLength = 0; for (int i = 0; i < indexRows.size (); ++i) { indexRows [i] = (i > 0) ? a (i - 1,0)->Nrows () + indexRows [i - 1] : 1; rowLength += a (i,0)->Nrows (); } for (int i = 0; i < indexCols.size (); ++i) { indexCols [i] = (i > 0) ? a (0,i - 1)->Ncols () + indexCols [i - 1] : 1; colLength += a (0,i)->Ncols (); } if (!allocate) assert (b.Nrows () == rowLength && b.Ncols () == colLength); // precondition else b.ReSize (rowLength, colLength); for (int i = 0; i < a.Nrows (); ++i) for (int j = 0; j < a.Ncols (); ++j) { #ifdef BLAS int bcols = b.Ncols(); double* bptr = b.Store() + bcols * (indexRows[i] - 1) + (indexCols[j] - 1); Matrix* aij = a(i, j); double* aptr = aij->Store(); int nrows = aij->Nrows(); int ncols = aij->Ncols(); for (int r = 0; r < nrows; ++r) { DCOPY(ncols, aptr, 1, bptr, 1); aptr += ncols; bptr += bcols; } #else b.SubMatrix (indexRows [i], indexRows [i] + a (i,j)->Nrows () - 1, indexCols [j], indexCols [j] + a (i,j)->Ncols () - 1) = *(a (i,j)); #endif } } catch (Exception) { pout << Exception::what () << endl; abort (); } }
void SpectClust::partitionClusters(const Matrix &D, const Matrix &E, std::vector<Numeric> &eVals, int numClusters, std::vector<int> &clusters, int hardMin, double cutVal, double margin) { clusters.clear(); clusters.resize(D.Ncols(), -1); std::vector<std::pair<double,int> > indices; /* Load up all the values and their indexes. */ for(int i = 0; i < D.Ncols(); i++) { std::pair<double,int> p; p.first = E.element(i,1); p.second = i; indices.push_back(p); } std::sort(indices.begin(), indices.end(), PairLess()); vector<double> indexNVals; calcNormalizedCutValues(D, indices, indexNVals); double minNormCut = DBL_MAX; int minNCutIx = 0; if(cutVal == DBL_MAX) { for(int i = 0; i < indexNVals.size(); i++) { double nCutI = indexNVals[i]; if(nCutI < minNormCut) { minNCutIx = i; minNormCut = nCutI; } } cutVal = minNormCut; } else { for(int i = 0; i < indices.size() - 1; i++) { if(indices[i].first <= cutVal && indices[i+1].first >= cutVal) { minNCutIx = i; } } } clusters.resize(indices.size()); fill(clusters.begin(), clusters.end(), -1); int maxNCutIx = minNCutIx; int diff = indices.size() - minNCutIx; diff = (int) (margin*diff); maxNCutIx = Max((int)indices.size() - diff, maxNCutIx); if(minNCutIx >= hardMin) minNCutIx = Max((int)(margin*minNCutIx), hardMin); for(int i = 0; i < indices.size(); i++) { if(i <= minNCutIx) { clusters[indices[i].second] = 0; } else if(i > maxNCutIx) { clusters[indices[i].second] = 1; } } }
void Print(const Matrix& X) { ++PCN; cout << "\nMatrix type: " << X.Type().Value() << " ("; cout << X.Nrows() << ", "; cout << X.Ncols() << ")\n\n"; if (X.IsZero()) { cout << "All elements are zero\n" << flush; return; } int nr=X.Nrows(); int nc=X.Ncols(); for (int i=1; i<=nr; i++) { for (int j=1; j<=nc; j++) cout << X(i,j) << "\t"; cout << "\n"; } cout << flush; ++PCZ; }
bool LinearConstraint::dimMatch(Matrix& A) { bool match = true; if (numOfCons_ != A.Nrows() || numOfVars_ != A.Ncols() ) match = false; return match; }
void SpectClust::calcNormalizedCutValues(const Matrix &D, const std::vector<std::pair<double,int> > &indices, std::vector<double> &cutVals) { cutVals.resize(indices.size()); std::fill(cutVals.begin(), cutVals.end(), DBL_MAX); double assocA = 0; double assocB = D.Sum(); double currentNCut = 0; double lastNCut = 0; int nCol = D.Ncols(); for(int cut = 0; cut < indices.size() -1; cut++) { double rowSum = 0; for(int colIx = 0; colIx < nCol; colIx++) { rowSum += D.element(indices[cut].second, colIx); } assocA += rowSum; assocB -= rowSum; double cutChange = 0; for(int colIx = 0; colIx < cut; colIx++) { cutChange -= D.element(indices[colIx].second, indices[cut].second); } for(int colIx = cut+1; colIx < nCol; colIx++) { cutChange += D.element(indices[cut].second, indices[colIx].second); } currentNCut = lastNCut + cutChange; if(assocA == 0 || assocB == 0 || currentNCut == 0) { cutVals[cut] = DBL_MAX; } else { double nVal = (currentNCut / assocA) + (currentNCut / assocB); cutVals[cut+1] = nVal; // +1 is to be compatible with existing calcNormalizedCut() conventions } lastNCut = currentNCut; } }
Matrix Find_T_BFS(queue<vector<bool>> q, Matrix S_BFS) { int rank_S = Rank(S_BFS); int nrow_S = S_BFS.Nrows(); int ncol_S = S_BFS.Ncols(); int size = q.size(); Matrix T(nrow_S, rank_S); T = 0; while (size > 0) { int r = 1; for (int i = 1; i < ncol_S; i++) { if (q.front().at(i) == true) { T.Column(r) = S_BFS.Column(i); r++; } } q.pop(); size--; if (Rank(T) == rank_S) break; } return T; }
queue<vector<bool>> Filter_Indep_Col(queue<vector<bool>> q, Matrix A) { queue<vector<bool>> indep_q; int nrow_A = A.Nrows(); int ncol_A = A.Ncols(); int rank_A = Rank(A); int size = q.size(); while (size > 0) { Matrix B(nrow_A, rank_A); int k = 1; for (int j = 0; j < ncol_A; j++) { if (q.front().at(j) == true) { B.Column(k) = A.Column(j+1); k++; } } // see if columns of B are indepenent if (Rank(B) == min(B.Ncols(), B.Nrows())) { indep_q.push(q.front()); } q.pop(); size--; } return indep_q; }
void accumulate_onepdm(Matrix& onepdm) { #ifndef SERIAL Matrix tmp_recv; mpi::communicator world; if (world.size() == 1) return; if (!mpigetrank()) { for(int i=1;i<world.size();++i) { world.recv(i, i, tmp_recv); for(int k=0;k<onepdm.Nrows();++k) for(int l=0;l<onepdm.Ncols();++l) if(tmp_recv(k+1,l+1) != 0.) { onepdm(k+1,l+1) = tmp_recv(k+1,l+1); } } } else { world.send(0, mpigetrank(), onepdm); } #endif }
void save_onepdm_text(const Matrix& onepdm, const int &i, const int &j) { //the spatial has a factor of 1/2 in front of it if(!mpigetrank()) { std::vector<int> reorder; reorder.resize(onepdm.Nrows()/2); for (int k=0; k<onepdm.Nrows()/2; k++) { reorder.at(dmrginp.reorder_vector()[k]) = k; } char file[5000]; sprintf (file, "%s%s%d.%d", dmrginp.save_prefix().c_str(),"/onepdm.", i, j); ofstream ofs(file); ofs << onepdm.Nrows() << endl; for(int k=0;k<onepdm.Nrows()/2;++k) for(int l=0;l<onepdm.Ncols()/2;++l) { int K = reorder.at(k), L = reorder.at(l); double opdm = onepdm(2*K+1, 2*L+1) ; ofs << boost::format("%d %d %20.14e\n") % (2*k) % (2*l) % opdm; opdm = onepdm(2*K+2, 2*L+2); ofs << boost::format("%d %d %20.14e\n") % (2*k+1) % (2*l+1) % opdm; } ofs.close(); } }
void SpinAdapted::diagonalise(Matrix& sym, DiagonalMatrix& d, Matrix& vec) { int nrows = sym.Nrows(); int ncols = sym.Ncols(); assert(nrows == ncols); d.ReSize(nrows); vec.ReSize(nrows, nrows); Matrix workmat; workmat = sym; vector<double> workquery(1); int info = 0; double* dptr = d.Store(); int query = -1; DSYEV('V', 'L', nrows, workmat.Store(), nrows, dptr, &(workquery[0]), query, info); // do query to find best size int optlength = static_cast<int>(workquery[0]); vector<double> workspace(optlength); DSYEV('V', 'U', nrows, workmat.Store(), nrows, dptr, &(workspace[0]), optlength, info); // do query to find best size if (info > 0) { pout << "failed to converge " << endl; abort(); } for (int i = 0; i < nrows; ++i) for (int j = 0; j < ncols; ++j) vec(j+1,i+1) = workmat(i+1,j+1); }
void SpinAdapted::svd(Matrix& M, DiagonalMatrix& d, Matrix& U, Matrix& V) { int nrows = M.Nrows(); int ncols = M.Ncols(); assert(nrows >= ncols); int minmn = min(nrows, ncols); int maxmn = max(nrows, ncols); int eigenrows = min(minmn, minmn); d.ReSize(minmn); Matrix Ut; Ut.ReSize(nrows, nrows); V.ReSize(ncols, ncols); int lwork = maxmn * maxmn + 100; double* workspace = new double[lwork]; // first transpose matrix Matrix Mt; Mt = M.t(); int info = 0; DGESVD('A', 'A', nrows, ncols, Mt.Store(), nrows, d.Store(), Ut.Store(), nrows, V.Store(), ncols, workspace, lwork, info); U.ReSize(nrows, ncols); SpinAdapted::Clear(U); for (int i = 0; i < nrows; ++i) for (int j = 0; j < ncols; ++j) U(i+1,j+1) = Ut(j+1,i+1); delete[] workspace; }
void SpectClustTest::testNCutDynamicProgram() { Matrix Dist; RFileToMatrix(Dist, "data/spike-in.norm.angleDist.b12.txt"); bool converged; vector<double> eVals; Matrix EVec; converged = SpectClust::findNLargestEvals(Dist, 2, eVals, EVec, 200); vector<double> cutVals; std::vector<std::pair<double,int> > indices; for(int i = 0; i < Dist.Ncols(); i++) { std::pair<double,int> p; p.first = EVec.element(i,1);// / E.element(i,0) ; p.second = i; indices.push_back(p); } std::sort(indices.begin(), indices.end(), SpectClust::PairLess()); SpectClust::calcNormalizedCutValues(Dist, indices, cutVals); for(int i = 0; i < cutVals.size(); i++) { double nCut = SpectClust::calcNormalizedCut(Dist, indices, i); double diff = nCut - cutVals[i]; // cout << "\t" << nCut << "\t" << cutVals[i] << "\t" << diff << endl; if(fabs(diff) > .000001) { CPPUNIT_ASSERT(false); } } }
LinearConstraint::LinearConstraint(const Matrix& A, const ColumnVector& b, const bool rowFlag): numOfCons_( A.Nrows() ), numOfVars_( A.Ncols() ), nnzl_(0), nnzu_(0), A_(A), Ax_( A.Nrows() ), lower_( A.Nrows() ), upper_( A.Nrows() ), cvalue_( A.Nrows()), cviolation_( A.Nrows() ), constraintMappingIndices_(0), stdForm_(rowFlag) { int i; cvalue_ = 1.0e30; cviolation_ = 0.0; if( stdForm_ ){ lower_ = b; upper_ = MAX_BND; for(i = 1; i <= numOfCons_; i++){ if (lower_(i) > -BIG_BND){ constraintMappingIndices_.append(i); nnzl_++; } } } else{ upper_ = b; lower_ = MIN_BND; for(i = 1; i <= numOfCons_; i++){ if (upper_(i) < BIG_BND){ constraintMappingIndices_.append(i); nnzu_++; } } } numOfCons_ = nnzl_ + nnzu_; }
void QRZT(Matrix& X, LowerTriangularMatrix& L) { REPORT Tracer et("QRZT(1)"); int n = X.Ncols(); int s = X.Nrows(); L.resize(s); if (n == 0 || s == 0) { L = 0.0; return; } Real* xi = X.Store(); int k; for (int i=0; i<s; i++) { Real sum = 0.0; Real* xi0=xi; k=n; while(k--) { sum += square(*xi++); } sum = sqrt(sum); if (sum == 0.0) { REPORT k=n; while(k--) { *xi0++ = 0.0; } for (int j=i; j<s; j++) L.element(j,i) = 0.0; } else { L.element(i,i) = sum; Real* xj0=xi0; k=n; while(k--) { *xj0++ /= sum; } for (int j=i+1; j<s; j++) { sum=0.0; xi=xi0; Real* xj=xj0; k=n; while(k--) { sum += *xi++ * *xj++; } xi=xi0; k=n; while(k--) { *xj0++ -= sum * *xi++; } L.element(j,i) = sum; } } } }
void QRZ(Matrix& X, UpperTriangularMatrix& U) { REPORT Tracer et("QRZ(1)"); int n = X.Nrows(); int s = X.Ncols(); U.ReSize(s); U = 0.0; Real* xi0 = X.Store(); Real* u0 = U.Store(); Real* u; int j, k; int J = s; int i = s; while (i--) { Real* xj0 = xi0; Real* xi = xi0; k = n; if (k) for (;;) { u = u0; Real Xi = *xi; Real* xj = xj0; j = J; while(j--) *u++ += Xi * *xj++; if (!(--k)) break; xi += s; xj0 += s; } Real sum = sqrt(*u0); *u0 = sum; u = u0+1; if (sum == 0.0) Throw(SingularException(U)); int J1 = J-1; j = J1; while(j--) *u++ /= sum; xj0 = xi0; xi = xi0++; k = n; if (k) for (;;) { u = u0+1; Real Xi = *xi; Real* xj = xj0; Xi /= sum; *xj++ = Xi; j = J1; while(j--) *xj++ -= *u++ * Xi; if (!(--k)) break; xi += s; xj0 += s; } u0 += J--; } }
double SpinAdapted::CheckSum (Matrix& a) { double val = 0.; for (int i = 0; i < a.Nrows (); ++i) for (int j = 0; j < a.Ncols (); ++j) val += a.element (i, j); return val; }