#include <stdio.h>
#include <math.h>

#define EPSILON 1e-7   // 変化量の判定基準
#define MAX_ITER 100

// 確定した特性方程式 f(λ)
double f(double lambda) {
    return pow(lambda, 4) + pow(lambda, 3) - 54.0 * pow(lambda, 2) - 224.0 * lambda - 345.0;
}

// 導関数 f'(λ)
double df(double lambda) {
    return 4.0 * pow(lambda, 3) + 3.0 * pow(lambda, 2) - 108.0 * lambda - 224.0;
}

void solve_newton(int attempt, double lambda0) {
    double lambda = lambda0;
    int iter = 0;

    while (iter <= MAX_ITER) {
        double f_val = f(lambda);
        double df_val = df(lambda);

        if (fabs(df_val) < 1e-12) {
            printf("試行 #%d (初期値 %5.1f) -> 傾きが平らなため失敗\n", attempt, lambda0);
            return;
        }

        // 次の修正値を計算
        double delta = f_val / df_val;
        lambda -= delta;
        iter++;

        // 【修正】yの値ではなく、「x（lambda）の移動距離」が基準値以下になったら収束とみなす
        if (fabs(delta) < EPSILON) {
            printf("試行 #%d (初期値 %5.1f) -> 収束成功 (%2d回) | 固有値解 λ = %.10f\n", 
                   attempt, lambda0, iter, lambda);
            return;
        }
    }
    printf("試行 #%d (初期値 %5.1f) -> 未収束\n", attempt, lambda0);
}

int main() {
    // 判定条件を移動距離に変えたため、この素直な初期値で4つの解が綺麗に分かれます
    double initial_lambda[] = {7.0, 1.25, 1.0, 0.0};

    printf("=== ニュートン・ラフソン法による実数解（固有値）の探索結果 ===\n");
    for (int i = 0; i < 4; i++) {
        solve_newton(i + 1, initial_lambda[i]);
    }

    return 0;
}