/** * int main() * * Descricao: * Funcao principal do programa que contem um loop (do-while) contendo a chamada * das funcoes que calculam as variaveis utilizadas pelo algoritmo Gauss-Legendre * a cada iteracao. * * Parametros de entrada: * - * * Parametros de retorno: * - * */ int main(){ /* Variaveis utilizadas para calcular o tempo de execucao do programa */ time_t begin, end; double time_spent; time(&begin); /* Inicialicazao das variaveis globais utilizadas no algoritmo */ initAttributes(); /* Loop principal que calcula o valor do "pi" */ do{ //printf("Iteracao: %ld\n", n_count); calculate_a(); calculate_b(); calculate_t(); calculate_p(); calculate_pi(); filePrint(); n_count++; } while(mpf_cmp(pi[n_count-2], pi[n_count-1])!=0); /* Condicao de parada: o "pi" recem calculado deve ser igual ao seu antecessor, garantindo assim a sua convergencia com 10 milhoes de casas decimais */ time(&end); time_spent = difftime(end, begin); printf("Tempo de execucao: %lf segundos\nIteracoes: %ld\n", time_spent, n_count); return 0; }
int calculate(char* pbg, TYPE* res) { char* dummy; return calculate_p(pbg, &dummy, res, 1, FALSE); }
void calculate() { int j; init_process(&p); double dstnc = 0.0; double step = 0.01; double gold_epsilon = 0.0000001; double dist_epsilon = 0.0000001; double norm_epsilon = 0.0000001; double J1, J2; do { _seperator(); //printX("t", p.t, p.m); calculate_u(&p); calculate_p(&p); //_printM(p.f, p.m, p.n); puts("---"); //_printM(p.u, p.m, p.n); //for (j=0; j<p.m; j++) //{ // for (i=0; i<p.n; i++) // { // p.u1[j][i] = u(p.dx*i, p.dt*j); // } //} //puts("---"); //_printM(p.u1, p.m, p.n); J1 = _JSum(&p); printf("J1 = %.18f\n", J1); double grad_norm = norm_f(&p); //for (j=0; j<p.m; j++) { for (i=0; i<p.n; i++) { p.p[j][i] = p.p[j][i] / grad_norm; } } if (grad_norm < norm_epsilon) { puts("Iteration breaks. Because norm of gradient is less than given epsilon..."); break; } double argmin(double alpha) { int j; double *_f = (double*) malloc(sizeof(double) * p.m*p.n); memcpy(_f, p.f, sizeof(double) * p.m*p.n); for (j=0; j<p.m*p.n; j++) { p.f[j] = p.f[j] - alpha * p.p[j]; } double sum = _JSum(&p); memcpy(p.f, _f, sizeof(double) * p.m*p.n); free(_f); return sum; } double alpha = R1Minimize(argmin, step, gold_epsilon); dstnc = 0.0; for (j=0; j<p.m*p.n; j++) { double f = p.f[j]- alpha * p.p[j]; double df = f - p.f[j]; p.f[j] = f; dstnc = dstnc + df*df; } dstnc = sqrt(dstnc); J2 = _JSum(&p); if (J2 > J1) { puts("Error accure. Then next value of functional is greater than last value..."); exit(-1); } if (dstnc < dist_epsilon) { puts("Iteration breaks. Because distance between last and current point is less than given epsilon..."); break; } } while (1);
int calculate_p(char* pbg, char** pend, TYPE* res, int level, BOOL mul_div_only) { TYPE tmp; *res = 0; char *p = pbg; int ret; if (strlen(pbg) == 0) { return RET_SYNTAX; } while (1) { fprintf(stderr, "%d: *p = \'%c\' (02%02x)\n", __LINE__, *p, *p); if ('0' <= *p && *p <= '9') { *res = 10 * *res + (((TYPE) *p) - 0x30); fprintf(stderr, "%d: *res = %"PLACEHOLDER"\n", __LINE__, *res); ++p; } if ('+' == *p) { if (p == pbg) { if (level > 1) { ++p; } else { fprintf(stderr, "%d\n", __LINE__); *res = 0; return RET_SYNTAX; } } else { if (mul_div_only) { *pend = p; return RET_OK; } if ((ret = calculate_p(p + 1, &p, &tmp, level, FALSE)) != 0) { fprintf(stderr, "%d\n", __LINE__); *res = p - pbg + 1 + tmp; return ret; } *res += tmp; } } if ('-' == *p) { if (p == pbg) { if (level > 1) { if ((ret = calculate_p(p + 1, &p, &tmp, level, TRUE)) != 0) { fprintf(stderr, "%d\n", __LINE__); *res = p - pbg + 1 + tmp; return ret; } *res = -tmp; } else { fprintf(stderr, "%d\n", __LINE__); *res = 0; return RET_SYNTAX; } } else { if (mul_div_only) { *pend = p; return RET_OK; } if ((ret = calculate_p(p + 1, &p, &tmp, level, FALSE)) != 0) { fprintf(stderr, "%d\n", __LINE__); *res = p - pbg + 1 + tmp; return ret; } *res -= tmp; } } if ('*' == *p) { if (p == pbg) { fprintf(stderr, "%d\n", __LINE__); *res = 0; return RET_SYNTAX; } else { if ((ret = calculate_p(p + 1, &p, &tmp, level, TRUE)) != 0) { fprintf(stderr, "%d\n", __LINE__); *res = p - pbg + 1 + tmp; return ret; } *res *= tmp; } } if ('/' == *p) { if (p == pbg) { fprintf(stderr, "%d\n", __LINE__); *res = p - pbg; return RET_SYNTAX; } else { if ((ret = calculate_p(p + 1, &p, &tmp, level, TRUE)) != 0) { fprintf(stderr, "%d\n", __LINE__); *res = p - pbg + 1 + tmp; return ret; } if (0 == tmp) { fprintf(stderr, "%d: Division by zero\n", __LINE__); return RET_DIVZERO; } else { *res /= tmp; } } } if ('(' == *p) { if ((ret = calculate_p(p + 1, &p, &tmp, level + 1, FALSE)) != 0) { fprintf(stderr, "%d\n", __LINE__); *res = p - pbg + 1 + tmp; return ret; } *res = tmp; ++p; // eat ')' } if (')' == *p) { if (level == 1) { fprintf(stderr, "%d\n", __LINE__); *res = p - pbg; return RET_SYNTAX; } else { *pend = p; // return ')' to the caller } return RET_OK; } if (' ' == *p || '\n' == *p || '\r' == *p) { ++p; } if ('\0' == *p) { if (level > 1) { fprintf(stderr, "%d\n", __LINE__); *res = p - pbg; return RET_SYNTAX; } else { fprintf(stderr, "%d\n", __LINE__); *pend = p; break; } } else { } } if (1 != level) { *res = 0; return RET_SYNTAX; } return RET_OK; }