//---------------------------------------------------------------------------- void snl_fei::LinearSystem_General::enforceEssentialBC_step_2(fei::CSVec& essBCs) { //to enforce essential boundary conditions, we do the following: // // 1. for each eqn (== essBCs.indices()[n]), { // put zeros in row A[eqn], but leave 1.0 on the diagonal // set b[eqn] = essBCs.coefs()[n] // } // // 2. for i in 1..numRows (i.e., all rows) { // if (i in bcEqns) continue; // b[i] -= A[i,eqn] * essBCs.coefs()[n] // A[i,eqn] = 0.0; // } // //It is important to note that for step 1, essBCs need only contain //local eqns, but for step 2 it should contain *ALL* bc eqns. // //This function performs step 2. int numBCeqns = essBCs.size(); if (numBCeqns < 1) { return; } int* bcEqns = &(essBCs.indices())[0]; double* bcCoefs = &(essBCs.coefs())[0]; fei::SharedPtr<fei::Reducer> reducer = matrixGraph_->getReducer(); bool haveSlaves = reducer.get()!=NULL; if (haveSlaves) { for(int i=0; i<numBCeqns; ++i) { bcEqns[i] = reducer->translateFromReducedEqn(bcEqns[i]); } } int firstBCeqn = bcEqns[0]; int lastBCeqn = bcEqns[numBCeqns-1]; std::vector<double> coefs; std::vector<int> indices; int insertPoint; int nextBCeqnOffset = 0; int nextBCeqn = bcEqns[nextBCeqnOffset]; for(int i=firstLocalOffset_; i<=lastLocalOffset_; ++i) { if (haveSlaves) { if (reducer->isSlaveEqn(i)) continue; } bool should_continue = false; if (i >= nextBCeqn) { if (i == nextBCeqn) { ++nextBCeqnOffset; if (nextBCeqnOffset < numBCeqns) { nextBCeqn = bcEqns[nextBCeqnOffset]; } else { nextBCeqn = lastLocalOffset_+1; } should_continue = true; } else { while(nextBCeqn <= i) { if (nextBCeqn == i) should_continue = true; ++nextBCeqnOffset; if (nextBCeqnOffset < numBCeqns) { nextBCeqn = bcEqns[nextBCeqnOffset]; } else { nextBCeqn = lastLocalOffset_+1; } } } } if (should_continue) continue; int err = getMatrixRow(matrix_.get(), i, coefs, indices); if (err != 0 || indices.size() < 1) { continue; } int numIndices = indices.size(); int* indicesPtr = &indices[0]; double* coefsPtr = &coefs[0]; bool modifiedCoef = false; fei::insertion_sort_with_companions(numIndices, indicesPtr, coefsPtr); if (indicesPtr[0] > lastBCeqn || indicesPtr[numIndices-1] < firstBCeqn) { continue; } double value = 0.0; int offset = 0; for(int j=0; j<numIndices; ++j) { int idx = indicesPtr[j]; offset = fei::binarySearch(idx, bcEqns, numBCeqns, insertPoint); if (offset > -1) { value -= bcCoefs[offset]*coefsPtr[j]; coefsPtr[j] = 0.0; modifiedCoef = true; } } if (modifiedCoef) { err = matrix_->copyIn(1, &i, numIndices, indicesPtr, &coefsPtr); if (err != 0) { FEI_OSTRINGSTREAM osstr; osstr <<"snl_fei::LinearSystem_General::enforceEssentialBC_step_2 ERROR: " << "err="<<err<<" returned from matrix_->copyIn, row="<<i; throw std::runtime_error(osstr.str()); } } const double fei_eps = 1.e-49; if (std::abs(value) > fei_eps) { rhs_->sumIn(1, &i, &value); if (output_level_ >= fei::FULL_LOGS && output_stream_ != 0) { FEI_OSTREAM& os = *output_stream_; os << "enfEssBC_step2: rhs["<<i<<"] += "<<value<<FEI_ENDL; } } } }
void LDAPrediction(matrix *mx, LDAMODEL *lda, matrix **pfeatures, matrix **probability, matrix **mnpdf, uivector **classprediction) { /* probability function: * f = mu_class * inv_cov * mx.T - 1/2. * mu_class * inv_cov * mu_class.T + ln(prior_probability_class) */ size_t i, j, argmax, id; matrix *mx_T; dvector *x, *mu, *C_x_T, *C_mu_T, *ldfeature, *evect_; NewMatrix(&mx_T, mx->col, mx->row); MatrixTranspose(mx, mx_T); NewDVector(&C_x_T, lda->inv_cov->row); NewDVector(&C_mu_T, lda->inv_cov->row); ResizeMatrix(probability, mx->row, lda->nclass); for(i = 0; i < mx_T->col; i++){ x = getMatrixColumn(mx_T, i); /* object k*/ for(j = 0; j < lda->nclass; j++){ mu = getMatrixRow(lda->mu, j); /*each row correspond to a class of objects*/ MatrixDVectorDotProduct(lda->inv_cov, x, C_x_T); MatrixDVectorDotProduct(lda->inv_cov, mu, C_mu_T); (*probability)->data[i][j] = DVectorDVectorDotProd(mu, C_x_T) - (0.5 * DVectorDVectorDotProd(mu, C_mu_T)) + log(lda->pprob->data[j]); DVectorSet(C_x_T, 0.f); DVectorSet(C_mu_T, 0.f); DelDVector(&mu); } DelDVector(&x); } for(i = 0; i < (*probability)->row; i++){ argmax = 0; for(j = 1; j < (*probability)->col; j++){ if((*probability)->data[i][j] > (*probability)->data[i][argmax]){ argmax = j; } else{ continue; } } if(lda->class_start == 0){ UIVectorAppend(classprediction, argmax); } else{ UIVectorAppend(classprediction, argmax+1); } } /* Predict the the new projection in the feature space */ ResizeMatrix(mnpdf, mx->row, lda->evect->col); NewDVector(&ldfeature, mx->row); for(i = 0; i < lda->evect->col; i++){ evect_ = getMatrixColumn(lda->evect, i); DVectorMatrixDotProduct(mx_T, evect_, ldfeature); DelDVector(&evect_); MatrixAppendCol(pfeatures, ldfeature); for(j = 0; j < ldfeature->size; j++){ id = (*classprediction)->data[j]; if(lda->class_start == 1) id -= 1; (*mnpdf)->data[j][i] = 1./sqrt(2 * pi* lda->fsdev->data[id][i]) * exp(-square((ldfeature->data[j] - lda->fmean->data[id][i])/lda->fsdev->data[id][i])/2.f); } DVectorSet(ldfeature, 0.f); } DelDVector(&ldfeature); DelMatrix(&mx_T); DelDVector(&C_x_T); DelDVector(&C_mu_T); }
//---------------------------------------------------------------------------- void snl_fei::LinearSystem_General::enforceEssentialBC_step_1(fei::CSVec& essBCs) { //to enforce essential boundary conditions, we do the following: // // 1. for each eqn (== essBCs.indices()[n]), { // put zeros in row A[eqn], but leave 1.0 on the diagonal // set b[eqn] = essBCs.coefs()[n] // } // // 2. for i in 1..numRows (i.e., all rows) { // if (i in bcEqns) continue; // b[i] -= A[i,eqn] * essBCs.coefs()[n] // A[i,eqn] = 0.0; // } // //It is important to note that for step 1, essBCs need only contain //local eqns, but for step 2 it should contain *ALL* bc eqns. // //This function performs step 1. int numEqns = essBCs.size(); int* eqns = &(essBCs.indices())[0]; double* bcCoefs = &(essBCs.coefs())[0]; std::vector<double> coefs; std::vector<int> indices; fei::SharedPtr<fei::Reducer> reducer = matrixGraph_->getReducer(); bool haveSlaves = reducer.get()!=NULL; try { for(int i=0; i<numEqns; i++) { int eqn = eqns[i]; //if slave-constraints are present, the incoming bc-eqns are in //the reduced equation space. so we actually have to translate them back //to the unreduced space before passing them into the fei::Matrix object, //because the fei::Matrix object has machinery to translate unreduced eqns //to the reduced space. //Also, our firstLocalOffset_ and lastLocalOffset_ attributes are in the //unreduced space. if (haveSlaves) { eqn = reducer->translateFromReducedEqn(eqn); } if (eqn < firstLocalOffset_ || eqn > lastLocalOffset_) continue; //put gamma/alpha on the rhs for this ess-BC equation. double bcValue = bcCoefs[i]; int err = rhs_->copyIn(1, &eqn, &bcValue); if (err != 0) { FEI_OSTRINGSTREAM osstr; osstr <<"snl_fei::LinearSystem_General::enforceEssentialBC_step_1 ERROR: " << "err="<<err<<" returned from rhs_->copyIn row="<<eqn; throw std::runtime_error(osstr.str()); } err = getMatrixRow(matrix_.get(), eqn, coefs, indices); if (err != 0 || indices.size() < 1) { continue; } int rowLen = indices.size(); int* indPtr = &indices[0]; //first, put zeros in the row and 1.0 on the diagonal... for(int j=0; j<rowLen; j++) { if (indPtr[j] == eqn) coefs[j] = 1.0; else coefs[j] = 0.0; } double* coefPtr = &coefs[0]; err = matrix_->copyIn(1, &eqn, rowLen, indPtr, &coefPtr); if (err != 0) { FEI_OSTRINGSTREAM osstr; osstr <<"snl_fei::LinearSystem_General::enforceEssentialBC_step_1 ERROR: " << "err="<<err<<" returned from matrix_->copyIn row="<<eqn; throw std::runtime_error(osstr.str()); } }//for i } catch(std::runtime_error& exc) { FEI_OSTRINGSTREAM osstr; osstr << "fei::LinearSystem::enforceEssentialBC: ERROR, caught exception: " << exc.what(); throw std::runtime_error(osstr.str()); } }