2015年10月11日日曜日

累乗和の公式をプログラムで導出してみる(分数編)[C#]

 こっちのプログラムに,こっちで実装したFractionクラスを適用してみる。と言っても一昨日のやつのdoubleをFractionに変えてちょこっと調整しただけだけれども。

 ソースコードの前に実行結果を出しておきます。
 一乗和の公式:(1/2)*n^1+(1/2)*n^2
 二乗和の公式:(1/6)*n^1+(1/2)*n^2+(1/3)*n^3
 三乗和の公式:(0/1)*n^1+(1/4)*n^2+(1/2)*n^3+(1/4)*n^4
 四乗和の公式:(-1/30)*n^1+(0/1)*n^2+(1/3)*n^3+(1/2)*n^4+(1/5)*n^5
 五乗和の公式:(0/1)*n^1+(-1/12)*n^2+(0/1)*n^3+(5/12)*n^4+(1/2)*n^5+(1/6)*n^6
 六乗和の公式:(1/42)*n^1+(0/1)*n^2+(-1/6)*n^3+(0/1)*n^4+(1/2)*n^5+(1/2)*n^6+(1/7)*n^7
 七乗和の公式:(0/1)*n^1+(1/12)*n^2+(0/1)*n^3+(-7/24)*n^4+(0/1)*n^5+(7/12)*n^6+(1/2)*n^7+(1/8)*n^8
 八乗和の公式:出力はされるものの,間違っている。オーバーフローしてるっぽい。
 九乗和の公式:例外が発生する

 本当は100乗和の公式とか出してみたかったんだけれどなぁ。残念。int型は2^31-1までしか扱えないから,おそらくそのせい。BigInteger使うのもありかもしれないけれど,それをやるのはまた今度かな。

 ソースコード。昨日のFractionクラスは省略しています。必ず追加してくださいね。
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("何乗和の公式を求めますか?");
        var N = int.Parse(Console.ReadLine()) + 1;
        // 係数を求める連立方程式の拡大係数行列を作る
        var formula = MakeFormula(N);
        // 連立方程式をガウス消去法で計算
        Solve(formula, N);
        // 結果を表示
        Show(formula, N);
    }

    // 連立方程式を解くメソッド
    static void Solve(Fraction[,] formula, int N)
    {
        Fraction temp;

        // ガウス消去法

        // 前進消去
        for (int i = 0; i < N; i++)
        {
            // 対角対角成分をを1にする
            temp = formula[i, i];
            for (int j = 0; j < N + 1; j++)
                formula[i, j] /= temp;

            // i+1行以降のi列目を0にする
            for (int j = i + 1; j < N; j++)
            {
                temp = formula[j, i];
                for (int k = 0; k < N + 1; k++)
                    formula[j, k] -= temp * formula[i, k];
            }
        }

        // 後進消去
        for (int i = N - 1; i >= 0; i--)
        {
            // 対角成分以外を0にする
            for (int j = i - 1; j >= 0; j--)
            {
                formula[j, N] -= formula[j, i] * formula[i, N];
                formula[j, i] = 0;
            }
        }
    }

    // 累乗和の公式を表示するメソッド
    static void Show(Fraction[,] d, int N)
    {
        Console.WriteLine("{0}乗和の公式は……", N - 1);
        for (int i = 0; i < N; i++)
        {
            Console.Write("({0})*n^{1}", d[i, N], i + 1);
            if (i + 1 < N)
                Console.Write("+");
        }
        Console.WriteLine();
    }

    // 累乗和の公式を求める連立方程式の拡大係数行列を作るメソッド
    static Fraction[,] MakeFormula(int N)
    {
        var ret = new Fraction[N, N + 1];
        var sum = 0;

        for (int i = 0; i < N; i++)
        {
            // 係数部分を作る
            for (int j = 0; j < N; j++)
                ret[i, j] = (int)(Math.Pow(i + 1, j + 1));

            // 答えの部分を作る
            sum = sum + (int)(Math.Pow(i + 1, N - 1));
            ret[i, N] = sum;
        }

        return ret;
    }
}

 ソースコードほぼ同じじゃねーか。ページ数稼ぎかよ,とは言わないで。

追記:
 255乗和の公式のような,任意のべき乗和を求めるプログラムが完成しました→BigIntegerを使って累乗和の公式を計算[C#]

0 件のコメント:

コメントを投稿