質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • C

    3991questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    3768questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Mathematica

    12questions

連立方程式の計算の演算回路での過程について。

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 450

carnage0216

score 124

連立方程式の計算過程は紙に書けば解くことができるのでわかるのですが、プログラムの計算の過程が紙に書いて計算してみたのですがうまく理解できません。
質問は3つあります。
{ 1.0, -2.0,  3.0, -4.0,  5.0}(1)
{-2.0,  5.0,  8.0, -3.0,  9.0}(2)
{ 5.0,  4.0,  7.0,  1.0, -1.0}(3)
{ 9.0,  7.0,  3.0,  5.0,  4.0}(4)
(2)-(1)*-2/1,(3)-(1)*-5/1より
{0,9,0,5,-1}{0, 1, 14, -11, 19}(5)
{0,14,-8,21,-26}(6)が得られますが、{0,9,0,5,-1}{0, 1, 14, -11, 19},{0,14,-8,21,-26}の置いてある位置、というか保存先は{0=(1,0),9=(1,1),0=(1,2),5=(1,3),-1=(1,4)}(2)´
{0=(2,0),14=(2,1),-8=(2,2),21=(2,3),-26=(2,4)}(3)´となっているのでしょうか?
計算後の係数のデータがどこにいくのかわかりませんでした。
その後の計算は
{0,14,-8,21,-26}-{0,9,0,5,-1}*-14/9を行うのでしょうか?

最後にプログラムのfor (j = k + 1; j <= N; j++)
a[i][j] -= a[k][j] * d;
の部分がi行-k行*aik/akkを表していると思うのですが、for (j = k + 1; j <= N; j++)によって a[i][j] -= a[k][j] * d;のa[k][j]のjが変化してある行に存在する係数すべてにaik/akkを掛けられるということでしょうか?

過程の計算処理がわからないプログラムは以下の部分です。

// 前進消去
    for (k = 0; k < N -1; k++) {
        for (i = k + 1; i < N; i++) {
            d = a[i][k] / a[k][k];
            for (j = k + 1; j <= N; j++)
                a[i][j] -= a[k][j] * d;
        }
    }

全体のプログラムはこちらです。

/*********************************************
 * 連立方程式の解法 ( ガウスの消去法 )
 *********************************************/
#include <iostream>  // for cout
#include <stdio.h>   // for printf()

// 元の数定義
#define N 4  // 3

using namespace std;

/*
 * 計算クラス
 */
class Calc
{
    double a[N][N + 1];

    // 各種変数
    double d;     // ダミー
    int i, j, k;  // LOOP インデックス

    public:
        // 連立方程式を解く(ガウスの消去法)
        void calcGaussElimination();
};

/*
 * 連立方程式を解く(ガウスの消去法)
 */
void Calc::calcGaussElimination()
{
    // 係数
    static double a[N][N + 1] = {
        //{ 2.0, -3.0,  1.0,  5.0},
        //{ 1.0,  1.0, -1.0,  2.0},
        //{ 3.0,  5.0, -7.0,  0.0}
        { 1.0, -2.0,  3.0, -4.0,  5.0},
        {-2.0,  5.0,  8.0, -3.0,  9.0},
        { 5.0,  4.0,  7.0,  1.0, -1.0},
        { 9.0,  7.0,  3.0,  5.0,  4.0}
    };

    // 元の連立方程式をコンソール出力
    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++)
            printf("%+fx%d ", a[i][j], j + 1);
        printf("= %+f\n", a[i][N]);
    }

    // 前進消去
    for (k = 0; k < N -1; k++) {
        for (i = k + 1; i < N; i++) {
            d = a[i][k] / a[k][k];
            for (j = k + 1; j <= N; j++)
                a[i][j] -= a[k][j] * d;
        }
    }

    // 後退代入
    for (i = N - 1; i >= 0; i--) {
        d = a[i][N];
        for (j = i + 1; j < N; j++)
            d -= a[i][j] * a[j][N];
        a[i][N] = d / a[i][i];
    }

    // 結果出力
    for (k = 0; k < N; k++)
        printf("x%d = %f\n", k + 1, a[k][N]);
}

/*
 * メイン処理
 */
int main()
{
    try
    {
        // 計算クラスインスタンス化
        Calc objCalc;

        // 連立方程式を解く(ガウスの消去法)
        objCalc.calcGaussElimination();
    }
    catch (...) {
        cout << "例外発生!" << endl;
        return -1;
    }

    // 正常終了
    return 0;
}


参考にしたサイトはこちらです。
https://www.mk-mode.com/octopress/2013/09/24/cpp-simultaneous-equation-by-gauss-elimination/

7/25(16:54)<編集>

for (k = 0; k < N -1; k++) {
        for (i = k + 1; i < N; i++) {
            d = a[i][k] / a[k][k];
            for (j = k + 1; j <= N; j++)
                a[i][j] -= a[k][j] * d;
        }
    }


の部分での過程の処理を実際に書いてみたのですが、うまく計算過程が書けませんでした。

k=0,i=1,d = a[1][0] / a[0][0],a[1][1] =a[1][1] - a[0][1] * a[1][0] / a[0][0]

となります。
この後a[0][1]に a[1][0] / a[0][0]を掛けているということは(0,0)は0として無いもののように扱いa[i][j] -= a[k][j] * dのjの値を(j <= Nの範囲で)変えながら計算してi行に存在する項を消して計算しているのでしょうか?
わかりにくくて申し訳ありません。どうしても理解したいと思い、何度も紙に書いて計算を行っています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2018/07/25 09:19

    https://mathtrain.jp/gausssyokyo ガウスの消去法についてプログラミング言語を使わず何も見ずに自分の言葉で説明できますか? できなければプログラム以前の問題になりますから、まずそこを目指してください。

    キャンセル

回答 1

+3

(2)-(1)*-2/1,(3)-(1)*-5/1より
{0,9,0,5,-1}(5)
{0,14,-8,21,-26}(6)が得られますが

(6)式はあっていますが、(5)式は{0, 1, 14, -11, 19} です。


a[1][0] = 0
a[1][1] = 1
a[1][2] = 14
a[1][3] = -11
a[1][4] = 19
a[2][0] = 0
a[2][1] = 14
a[2][2] = -8
a[2][3] = 21
a[2][4] = -26
が代入されます。

なお、このプログラムでは0になることが確定しているa[1][0]およびa[2][0]は計算および代入をサボっています。

その後の計算は
{0,14,-8,21,-26}-{0,9,0,5,-1}*-14/9を行うのでしょうか?

(4)式も同様に先頭の係数を0にした後に
(6) - (5) * 14 / 1
を行います


サボってる計算を行いつつ計算過程を表示させると
https://wandbox.org/permlink/8NOijeLGjtDs6ang
こうなります


追記分への回答

d = a[i][k] / a[k][k]なので
a[k][k] * d = a[k][k] * a[i][k] / a[k][k] = a[i][k] となり
a[i][k] -= a[k][k] * dは常に0になります。(というか、0にしようとしているわけです。)
よって j = k の場合はサボって計算せずに
for(j = k + 1; j <= N; j++)でループさせています。

やってる事を一口で言うと
i行目の式のk項の係数を0にした係数行列を生成しています。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/25 16:40

    どうもありがとうございます。じっくり読ませて頂きます。

    キャンセル

  • 2018/07/25 21:49

    https://teratail.com/questions/136220 の回答で計算過程を示したぞ。少なくとも前進消去までは大差ないはず。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    3991questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    3768questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Mathematica

    12questions