double getResidualNorm(int id, matrix a, vector x, vector y, double c, int size) { vector v1, v2; multiplyMatrixVector(a, x, size, v1); multiplyVectorConst(y, c, size); subVectors(v1, y, size, v2); return getVectorNorm(id, v2, size); }
void conjugateGradientMethod(double**matrix, double *rightPart, double *outVector, int number, double precision, int maxIteration, bool periodic, int rank, int nprocs) { printf("start conjugate gradient\n"); double* residual = new double[number]; double* prevResidual = new double[number]; double* z = new double[number]; double* tempVector = new double[number]; for(int i = 0; i < number; ++i) { outVector[i] = 0; prevResidual[i] = rightPart[i]; z[i] = rightPart[i]; tempVector[i] = 0; } int iteration = 0; double prevResidualNorm2 = scalarMultiplyLargeVectors(prevResidual, prevResidual, number, periodic, rank, nprocs); double residualNorm2 = prevResidualNorm2; double rightPartNorm2 = scalarMultiplyLargeVectors(rightPart, rightPart, number, periodic, rank, nprocs); double relativeError = sqrt(residualNorm2/rightPartNorm2); while((iteration < maxIteration) && (iteration < number) && (relativeError > (precision/number))){ printf("conjugate gradient iteration %d\n", iteration); multiplyMatrixVector(tempVector, matrix, z, number, periodic, rank, nprocs); double alpha = prevResidualNorm2/scalarMultiplyLargeVectors(tempVector, z, number, periodic, rank, nprocs); for(int i = 0; i < number; ++i){ outVector[i] += alpha*z[i]; residual[i] = prevResidual[i] - alpha*tempVector[i]; } residualNorm2 = scalarMultiplyLargeVectors(residual, residual, number, periodic, rank, nprocs); double beta = residualNorm2/prevResidualNorm2; for(int i = 0; i < number; ++i){ z[i] = residual[i] + beta*z[i]; } prevResidualNorm2 = residualNorm2; relativeError = sqrt(residualNorm2/rightPartNorm2); iteration++; } delete[] residual; delete[] prevResidual; delete[] z; delete[] tempVector; }
double getRayleighQuotient(int id, matrix a, matrix eigen_vectors, int size) { vector v1, e; for (int i = 0; i < size; i++) e[i] = eigen_vectors[i][id]; multiplyMatrixVector(a, e, size, v1); double n = getDotProduct(e, v1, size); double d = getDotProduct(e, e, size); return n / d; }
int main() { // Initialize the GPU and print information as done in the first step. agile::GPUEnvironment::allocateGPU(0); agile::GPUEnvironment::printInformation(std::cout); std::cout << std::endl; unsigned int test_nr = 3; switch(test_nr) { case 1: multiplyMatrixVector(); break; case 2: multiplyMatrixVectorHermitian(); break; case 3: multiplyMatrixScalar(); } }
void biconjugateStabilizedGradientMethod(double **matrix, double *rightPart, double *outVector, int number, double precision, int maxIteration, bool periodic, int rank, int nprocs) { printf("start biconjugate gradient\n"); double* residual = new double[number]; double* firstResidual = new double[number]; double* p = new double[number]; double* v = new double[number]; double* s = new double[number]; double* t = new double[number]; double alpha = 1; double rho = 1; double omega = 1; for(int i = 0; i < number; ++i){ outVector[i] = 0; firstResidual[i] = rightPart[i]; residual[i] = rightPart[i]; v[i] = 0; p[i] = 0; s[i] = 0; t[i] = 0; } int iteration = 0; double prevResidualNorm2 = scalarMultiplyLargeVectors(residual, residual, number, periodic, rank, nprocs); double residualNorm2 = prevResidualNorm2; double rightPartNorm2 = scalarMultiplyLargeVectors(rightPart, rightPart, number, periodic, rank, nprocs); double relativeError = sqrt(residualNorm2/rightPartNorm2); while((iteration < maxIteration) && (iteration < number+1) && (relativeError > (precision/(number)))){ printf("biconjugate gradient iteration %d\n", iteration); double newRho = scalarMultiplyLargeVectors(firstResidual, residual, number, periodic, rank, nprocs); double beta = (newRho/rho)*(alpha/omega); if(fabs(rho)<1E-200){ if(fabs(newRho)<1E-200){ beta = alpha/omega; //beta = 0; } else { printf("denominator = 0\n"); } } rho = newRho; for(int i = 0; i < number; ++i){ p[i] = residual[i] + beta*(p[i]- omega*v[i]); } multiplyMatrixVector(v, matrix, p, number, periodic, rank, nprocs); double denominator = scalarMultiplyLargeVectors(firstResidual, v, number, periodic, rank, nprocs); if(fabs(denominator) < 1E-200){ if(fabs(rho)<1E-200){ alpha = 1; } else { alpha = 1; printf("denominator = 0\n"); } } else { alpha = rho/denominator; } for(int i = 0; i < number; ++i){ s[i] = residual[i] - alpha*v[i]; } multiplyMatrixVector(t, matrix, s, number, periodic, rank, nprocs); omega = scalarMultiplyLargeVectors(t, s, number, periodic, rank, nprocs)/scalarMultiplyLargeVectors(t, t, number, periodic, rank, nprocs); for(int i = 0; i < number; ++i){ outVector[i] = outVector[i] + omega*s[i] + alpha*p[i]; residual[i] = s[i] - omega*t[i]; } residualNorm2 = scalarMultiplyLargeVectors(residual, residual, number, periodic, rank, nprocs); prevResidualNorm2 = residualNorm2; relativeError = sqrt(residualNorm2/rightPartNorm2); iteration++; } delete[] residual; delete[] firstResidual; delete[] v; delete[] p; delete[] s; delete[] t; }