#include #include #include #include "convergence.h" #include "muller.h" #include "nr.h" void dbessj0(float x, float *y, float *dy) { *y = bessj0(x); *dy = -bessj1(x); } float test_func(float x) { return x * sin(x) - 1; } float test_func_derivative(float x) { return sin(x) + x * cos(x); } void test_funcd(float x, float *y, float *dy) { *y = test_func(x); *dy = test_func_derivative(x); } int main() { /* 1. using zbrak, find all possible intervals with roots. 2. and use routines and enumerate all roots. */ printf("===============================\n"); printf("A report of root-finding\n"); printf("student name: Hajin Ju, id: 2024062806\n"); printf("--------------------------------\n"); printf("=== A Program that find bessj0 roots in [1, 10] ===\n"); printf("--------------------------------\n"); float a = 1.0, b = 10.0; float xacc = 0.000001; int n = 23; float *xb1 = calloc(sizeof(float), n); float *xb2 = calloc(sizeof(float), n); int nb; int i; zbrak(bessj0, a, b, n, xb1, xb2, &nb); float *roots_bisect = calloc(sizeof(float), nb); float *roots_linter = calloc(sizeof(float), nb); float *roots_secant = calloc(sizeof(float), nb); float *roots_newt = calloc(sizeof(float), nb); float *roots_newtsafe = calloc(sizeof(float), nb); float *roots_muller = calloc(sizeof(float), nb); for (i = 0; i < nb; i++) { float l = xb1[i + 1]; float r = xb2[i + 1]; roots_bisect[i] = rtbis(bessj0, l, r, xacc); roots_linter[i] = rtflsp(bessj0, l, r, xacc); roots_secant[i] = rtsec(bessj0, l, r, xacc); roots_newt[i] = rtnewt(dbessj0, l, r, xacc); roots_newtsafe[i] = rtsafe(dbessj0, l, r, xacc); roots_muller[i] = rtmuller(bessj0, l, r, xacc); } printf("besection roots: "); for (i = 0; i < nb; i++) { printf("%f ", roots_bisect[i]); } printf("\n"); printf("lin-interpoalation roots: "); for (i = 0; i < nb; i++) { printf("%f ", roots_linter[i]); } printf("\n"); printf("secant roots: "); for (i = 0; i < nb; i++) { printf("%f ", roots_secant[i]); } printf("\n"); printf("newton-raphson roots: "); for (i = 0; i < nb; i++) { printf("%f ", roots_newt[i]); } printf("\n"); printf("newton with bracketing roots: "); for (i = 0; i < nb; i++) { printf("%f ", roots_newtsafe[i]); } printf("\n"); printf("muller method roots: "); for (i = 0; i < nb; i++) { printf("%f ", roots_muller[i]); } printf("\n"); /* free */ free(xb1); free(xb2); free(roots_bisect); free(roots_linter); free(roots_secant); free(roots_newt); free(roots_newtsafe); free(roots_muller); printf("\n"); printf("=== Solve one interesting nonlinear equation ===\n"); printf(": using the routine of rtsafe.c in NR in C\n"); printf("--------------------------------\n"); n = 21; xb1 = calloc(sizeof(float), n); xb2 = calloc(sizeof(float), n); nb = 0; zbrak(test_func, a, b, n, xb1, xb2, &nb); float *roots_interesting = calloc(sizeof(float), nb); for (i = 0; i < nb; i++) { float l = xb1[i + 1]; float r = xb2[i + 1]; roots_interesting[i] = rtsafe(test_funcd, l, r, xacc); } printf("I want to find roots of `x * sin(x) - 1`\nwhere x in [%.02f, %.02f]\n", a, b); printf("-------------------------------\n"); printf("roots: "); for (i = 0; i < nb; i++) { printf("%f ", roots_interesting[i]); } printf("\n"); free(xb1); free(xb2); free(roots_interesting); printf("\n"); printf("=== Discuss the convergence speed ===\n"); printf("--------------------------------\n"); a = 2.0f; b = 3.0f; printf("Find a root of bessj0(x) where x in [%.02f, %.02f].\n", a, b); printf("We want to get convergence speed(iteration count).\n"); printf("-------------------------------\n"); ConvergenceData conv_bisect = rtbis_with_conv(bessj0, a, b, xacc); ConvergenceData conv_flsp = rtflsp_with_conv(bessj0, a, b, xacc); ConvergenceData conv_secant = rtsec_with_conv(bessj0, a, b, xacc); ConvergenceData conv_newt = rtnewt_with_conv(dbessj0, a, b, xacc); ConvergenceData conv_newtsafe = rtsafe_with_conv(dbessj0, a, b, xacc); ConvergenceData conv_muller = rtmuller_with_conv(bessj0, a, b, xacc); printf("Convergence History(where root ~ 2.404825):\n"); printf("bisect iteration count: %d\n", conv_bisect.size); printf("bisect iteration history: "); for (i = 0; i < conv_bisect.size; i++) { printf("%f ", conv_bisect.data[i]); } printf("\n"); printf("lin-interpoalation iteration count: %d\n", conv_flsp.size); printf("lin-interpoalation iteration history: "); for (i = 0; i < conv_flsp.size; i++) { printf("%f ", conv_flsp.data[i]); } printf("\n"); printf("secant iteration count: %d\n", conv_secant.size); printf("secant iteration history: "); for (i = 0; i < conv_secant.size; i++) { printf("%f ", conv_secant.data[i]); } printf("\n"); printf("newton-raphson iteration count: %d\n", conv_newt.size); printf("newton-raphson iteration history: "); for (i = 0; i < conv_newt.size; i++) { printf("%f ", conv_newt.data[i]); } printf("\n"); printf("newton with bracketing iteration count: %d\n", conv_newtsafe.size); printf("newton with bracketing iteration history: "); for (i = 0; i < conv_newtsafe.size; i++) { printf("%f ", conv_newtsafe.data[i]); } printf("\n"); printf("muller method iteration count: %d\n", conv_muller.size); printf("muller method iteration history: "); for (i = 0; i < conv_muller.size; i++) { printf("%f ", conv_muller.data[i]); } printf("\n"); printf("-------------------------------\n"); printf("Convergence Error\n"); float res; printf("bisect convergence error: "); res = conv_bisect.data[conv_bisect.size - 1]; for (i =0;i < conv_bisect.size; i++) { printf("%f ", fabs(conv_bisect.data[i] - res) / res); } printf("\n"); printf("flsp convergence error: "); res = conv_flsp.data[conv_flsp.size - 1]; for (i =0;i < conv_flsp.size; i++) { printf("%f ", fabs(conv_flsp.data[i] - res) / res); } printf("\n"); printf("secant convergence error: "); res = conv_secant.data[conv_secant.size - 1]; for (i =0;i < conv_secant.size; i++) { printf("%f ", fabs(conv_secant.data[i] - res) / res); } printf("\n"); printf("newton-raphson convergence error: "); res = conv_newt.data[conv_newt.size - 1]; for (i =0;i < conv_newt.size; i++) { printf("%f ", fabs(conv_newt.data[i] - res) / res); } printf("\n"); printf("newton with bracketing convergence error: "); res = conv_newtsafe.data[conv_newtsafe.size - 1]; for (i =0;i < conv_newtsafe.size; i++) { printf("%f ", fabs(conv_newtsafe.data[i] - res) / res); } printf("\n"); printf("muller method convergence error: "); res = conv_muller.data[conv_muller.size - 1]; for (i =0;i < conv_muller.size; i++) { printf("%f ", fabs(conv_muller.data[i] - res) / res); } printf("\n"); printf("-------------------------------\n"); printf("Convergence Iteration Counts Table:\n"); printf("--------------------------------------------------------------\n"); printf("| Method | Iter |\n"); printf("--------------------------------------------------------------\n"); printf("| Bisection | %-04d |\n", conv_bisect.size); printf("| Linear Interpolation | %-04d |\n", conv_flsp.size); printf("| Secant | %-04d |\n", conv_secant.size); printf("| Newton-Raphson | %-04d |\n", conv_newt.size); printf("| Newton with Bracketing | %-04d |\n", conv_newtsafe.size); printf("| Muller | %-04d |\n", conv_muller.size); printf("--------------------------------------------------------------\n"); printf("As a result, In order of performance(faster convergence speed),\n"); printf("Newton-Raphson, Newton with Bracketing, Muller, Secant, Linear Interpolation, Bisection\n"); printf("-------------------------------\n"); printf("===============================\n"); return 0; }