int KrylovAccelerator2::accelerate(Vector &vStar, LinearSOE &theSOE, IncrementalIntegrator &theIntegrator) { const Vector &R = theSOE.getB(); int k = dimension; // Store residual for differencing at next iteration *(Av[k]) = R; // If subspace is not empty if (dimension > 0) { // Compute Av_k = f(y_{k-1}) - f(y_k) = r_{k-1} - r_k Av[k-1]->addVector(1.0, R, -1.0); int i,j; // Put subspace vectors into AvData Matrix A(AvData, numEqns, k); for (i = 0; i < k; i++) { Vector &Ai = *(Av[i]); for (j = 0; j < numEqns; j++) A(j,i) = Ai(j); } for (i = 0; i < k; i++) { for (int j = i+1; j < k; j++) { double sum = 0.0; double sumi = 0.0; double sumj = 0.0; for (int ii = 0; ii < numEqns; ii++) { sum += A(ii,i)*A(ii,j); sumi += A(ii,i)*A(ii,i); sumj += A(ii,j)*A(ii,j); } sumi = sqrt(sumi); sumj = sqrt(sumj); sum = sum/(sumi*sumj); //if (fabs(sum) > 0.99) //opserr << sum << ' ' << i << ' ' << j << " "; } } // Put residual vector into rData (need to save r for later!) Vector B(rData, numEqns); B = R; // No transpose char *trans = "N"; // The number of right hand side vectors int nrhs = 1; // Leading dimension of the right hand side vector int ldb = (numEqns > k) ? numEqns : k; // Subroutine error flag int info = 0; // Call the LAPACK least squares subroutine #ifdef _WIN32 unsigned int sizeC = 1; DGELS(trans, &sizeC, &numEqns, &k, &nrhs, AvData, &numEqns, rData, &ldb, work, &lwork, &info); #else //SUBROUTINE DGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK, // $ INFO ) dgels_(trans, &numEqns, &k, &nrhs, AvData, &numEqns, rData, &ldb, work, &lwork, &info); #endif // Check for error returned by subroutine if (info < 0) { opserr << "WARNING KrylovAccelerator2::accelerate() - \n"; opserr << "error code " << info << " returned by LAPACK dgels\n"; return info; } Vector Q(numEqns); Q = R; // Compute the correction vector double cj; for (j = 0; j < k; j++) { // Solution to least squares is written to rData cj = rData[j]; // Compute w_{k+1} = c_1 v_1 + ... + c_k v_k vStar.addVector(1.0, *(v[j]), cj); // Compute least squares residual // q_{k+1} = r_k - (c_1 Av_1 + ... + c_k Av_k) Q.addVector(1.0, *(Av[j]), -cj); } theSOE.setB(Q); //opserr << "Q: " << Q << endln; } theSOE.solve(); vStar.addVector(1.0, theSOE.getX(), 1.0); // Put accelerated vector into storage for next iteration *(v[k]) = vStar; dimension++; return 0; }
/* return 0 if ok * otherwise return !=0 */ int solveLeastSquareProblem(LinearSystemProblem* problem, double *z , SolverOptions* options) { /* Checks inputs */ if (problem == NULL || z == NULL) numericsError("EqualityProblem", "null input for EqualityProblem and/or unknowns (z)"); /* Output info. : 0: ok - >0: problem (depends on solver) */ int info = -1; int n = problem->size; int n2 = n * n; double * Maux = 0; int * ipiv = 0; if (options && options->dWork) Maux = options->dWork; else Maux = (double *) malloc(LinearSystem_getNbDwork(problem, options) * sizeof(double)); if (options && options->iWork) ipiv = options->iWork; else ipiv = (int *) malloc(LinearSystem_getNbIwork(problem, options) * sizeof(int)); int LAinfo = 0; //displayLS(problem); assert(problem->M->matrix0); assert(problem->q); memcpy(Maux, problem->M->matrix0, n2 * sizeof(double)); // memcpy(z,problem->q,n*sizeof(double)); for (int ii = 0; ii < n; ii++) z[ii] = -problem->q[ii]; printf("LinearSystem : solveLeastSquareProblem LWORK is :%d\n", LWORK); DGELS(LA_NOTRANS,n, n, 1, Maux, n, z, n, &LAinfo); if (LAinfo) { printf("LinearSystem_driver: DGELS failed:\n"); goto __fin; } int ii; for (ii = 0; ii < n; ii++) { if (isnan(z[ii]) || isinf(z[ii])) { printf("DGELS FAILED\n"); goto __fin; } } info = 0; printf("LinearSystem_driver: computeError of LinearSystem : %e\n", LinearSystem_computeError(problem, z)); __fin: if (!(options && options->dWork)) free(Maux); if (!(options && options->iWork)) free(ipiv); return info; }