//Usa strncpy para substituir um trecho de uma string por outro, preechendo as diferenças de tamanho com espaços //AVISO: strncpy preenche as diferenças de espaços com '\0', por isso o uso de espaços para sanar o problema bool strReplace(ConstPointerString text, ConstStaticString oldkey, ConstStaticString newkey) { String found, filler; int oldkeysize, newkeysize, textsize, count; bool result; oldkeysize = strlen(oldkey); newkeysize = strlen(newkey); textsize = strlen(text); found = strstr(text, oldkey); if(found == NULL) { result = false; } else { if(oldkeysize > newkeysize) { filler = (String) malloc(oldkeysize + 1); strcpy(filler, newkey); fillWith(filler, ' ', newkeysize, oldkeysize); //Preenche a diferença entre as duas strings com espaço strncpy(found, filler, oldkeysize); free(filler); } else { strncpy(found, newkey, oldkeysize); } result = true; } return result; }
void drawShape::clear() { fillWith(Qt::white); ox = -1; showPicture(); setEnabled(true); }
//------------------------------------------------------------------------------ // getQR // Returns pre-ref'd pointers to the lower QR (pQ) and upper QR (pR) matrices // of 'this' matrix, or zero if the matrix can not be QR-ized //------------------------------------------------------------------------------ bool Matrix::getQR(Matrix* const pQ, Matrix* const pR) const { //------------------------------------------------------- // initial compatibility and error checks //------------------------------------------------------- bool b1 = isGoodMatrix(); bool b2 = isSquare(); if (!b1 || !b2) return false; //------------------------------------------------------- // Initialize intermediate R matrix to 'this' matrix //------------------------------------------------------- const auto pRI = new Matrix(*this); //------------------------------------------------------- // Initialize intermediate Q matrix to 'identity' matrix //------------------------------------------------------- const int N = getRows(); const auto pQI = new Matrix(N,N); pQI->makeIdent(); //------------------------------------------------------- // X and V are intermediate vectors //------------------------------------------------------- const auto pX = new CVector(N); const auto pV = new CVector(N); //------------------------------------------------------- // Begin loop //------------------------------------------------------- for (int k = 0; k < N-1; k++) { pX->fillWith(0.0); for (int i = k; i<N ; i++) { (*pX)[i] = (*pRI)(i,k); } double g = pX->getNorm(); (*pV) = (*pX); (*pV)[k] += g; double s = pV->getNorm(); if (s == 0.0) { pQI->unref(); pRI->unref(); pX->unref(); pV->unref(); return false; } CVector* pW = base::multiply((*pV), 1.0/s); RVector* pWT = pW->getTranspose(); { //---------------------------------------------------- // U' = (2*R'*W)' //---------------------------------------------------- Matrix* pRIT = pRI->getTranspose(); CVector* pU0 = base::multiply((*pRIT), (*pW)); CVector* pU = base::multiply((*pU0), 2.0); RVector* pUT = pU->getTranspose(); pU0->unref(); pU->unref(); pRIT->unref(); //---------------------------------------------------- // R = R - W*U' //---------------------------------------------------- Matrix* pM1 = outerProduct(*pW, *pUT); pRI->subtract(*pM1); pM1->unref(); pUT->unref(); } //---------------------------------------------------- // Q = Q - 2*Q*W*W' //---------------------------------------------------- { Matrix* pM2 = outerProduct(*pW, *pWT); Matrix* pM3 = base::multiply(*pQI, *pM2); Matrix* pM4 = base::multiply(*pM3, 2.0); pQI->subtract(*pM4); pM2->unref(); pM3->unref(); pM4->unref(); } //------------------------------------------------------- // Unref pointers //------------------------------------------------------- pW->unref(); pWT->unref(); } //------------------------------------------------------- // Assign results to argument list variables for output //------------------------------------------------------- *pQ = *pQI; *pR = *pRI; //------------------------------------------------------- // Unref pointers //------------------------------------------------------- pQI->unref(); pRI->unref(); pX->unref(); pV->unref(); return true; }
//------------------------------------------------------------------------------ // Dominant Eigenvalue Power Method //------------------------------------------------------------------------------ bool Matrix::getEigenPower(const double maxErr, const int maxIter, double* const pEigenVal, CVector* const pEigenVec) { //------------------------------------------------------- // initial compatibility and error checks //------------------------------------------------------- if (!isGoodMatrix() || !isSquare()) return false; //------------------------------------------------------- // initialize variables //------------------------------------------------------- int Iter = 0; // iterator initialized to zero double Err = 10.0*maxErr; // make Err > maxErr on entry const auto pA = new Matrix(*this); // A is a buffer matrix for 'this' matrix const int N = pA->getRows(); // pA->getCols works too since A is square double alfa = 0.0; // current eigenvalue estimate const auto pZ = new CVector(N); // current eigenvector estimate pZ->fillWith(1.0); // all 1's in initial estimate //------------------------------------------------------- // iterate solutions to desired accuracy or iteration limit //------------------------------------------------------- while ((Err > maxErr) && (Iter < maxIter)) { { //---------------------------------------------------- // get estimate of eigenvector //---------------------------------------------------- CVector* pW = base::multiply(*pA, *pZ); // get new estimate (W) based on old estimate (Z) const double Wmag = pW->getMaxMag(); // max mag value from elements of vector W if (Wmag == 0.0) { // mag value is zero; cleanup and leave pW->unref(); pZ->unref(); pA->unref(); return false; } pW->multiply(1.0/Wmag); // normalize eigenvector with max element of W //---------------------------------------------------- // get estimate of eigenvalue //---------------------------------------------------- alfa = Wmag; // save Wmag eigenvalue estimate //---------------------------------------------------- // refine eigenvalue estimate by using Rayleigh quotient // (may or may not be worth the additional calculations) //---------------------------------------------------- #if 0 { RVector* pZT = pZ->getTranspose(); double num = base::dotProduct(*pZT, *pW); double den = base::dotProduct(*pZT, *pZ); alfa *= (num / den); // save Rayleigh eigenvalue estimate pZT->unref(); } #endif //---------------------------------------------------- // save eigenvector W estimate in vector Z to begin next loop //---------------------------------------------------- *pZ = *pW; // save eigenvector estimate for next iteration pW->unref(); } //---------------------------------------------------- // calculate error of estimate: Err = ||A*Z - alfa*Z|| //---------------------------------------------------- { CVector* pE = base::multiply(*pA, *pZ); CVector* pW1 = base::multiply(*pZ, alfa); // pW1 used here as intermediate vector pE->subtract(*pW1); Err = pE->getNorm(); // magnitude of error vector pE->unref(); pW1->unref(); } //---------------------------------------------------- // increment iterator for next loop //---------------------------------------------------- Iter++; } //------------------------------------------------------- // copy eigenvalue and eigenvector results to output //------------------------------------------------------- *pEigenVal = alfa; *pEigenVec = *pZ; //------------------------------------------------------- // unref pointers //------------------------------------------------------- pZ->unref(); pA->unref(); return true; }