#include #include #include #include #include using namespace std; // single Jacobi iteration step double single_jacobi_iteration(double** A, double** B, int n, int m) { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { B[i][j] = 0.25 * (A[i-1][j] + A[i][j-1] + A[i][j+1] + A[i+1][j]); } } double maxdiff = 0; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { double diff = fabs(A[i][j] - B[i][j]); if (diff > maxdiff) maxdiff = diff; A[i][j] = B[i][j]; } } return maxdiff; } void initialize_A(double& Aij, int i, int j, int N) { const static double E_POWER_MINUS_PI = pow(M_E, -M_PI); if (j == 0) { Aij = sin(M_PI * ((double)i/(N-1))); } else if (j == N-1) { Aij = sin(M_PI * ((double)i/(N-1))) * E_POWER_MINUS_PI; } else { Aij = 0; } } double** run_jacobi_iteration(int N, double eps) { int n = N-2; double** A = new double*[N]; assert(A); for (int i = 0; i < N; ++i) { A[i] = new double[N]; assert(A[i]); for (int j = 0; j < N; ++j) { initialize_A(A[i][j], i, j, N); } } double** B = new double*[N-1]; for (int i = 1; i < N-1; ++i) { B[i] = new double[N-1]; assert(B[i]); } double maxdiff; do { maxdiff = single_jacobi_iteration(A, B, n, n); } while (maxdiff > eps); for (int i = 1; i < N-1; ++i) { delete[] B[i]; } delete[] B; return A; } char* cmdname; void usage() { cerr << "Usage: " << cmdname << " [N [eps]] " << endl; exit(1); } int main(int argc, char** argv) { int N = 10; double eps = 1e-6; cmdname = *argv++; --argc; if (argc > 2) usage(); if (argc > 0) { istringstream arg(*argv++); --argc; if (!(arg >> N) || N < 3) usage(); } if (argc > 0) { istringstream arg(*argv++); --argc; if (!(arg >> eps) || eps <= 0) usage(); } cout << N << endl; double** A = run_jacobi_iteration(N, eps); for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { cout << " " << A[i][j]; } cout << endl; delete[] A[i]; } delete[] A; }