近似的に3×3行列を求める方法とExcelでの計算方法について

このQ&Aのポイント
  • 3行3列の行列(近似値)を求めるためには、A,B,C,I,J,Kの6つの既知の変数に対して行列式を成立させるa1~a3, b1~b3, c1~c3を求める必要があります。
  • A,B,C,I,J,Kが1通りであれば3×3行列は決定できますが、複数の組み合わせが存在する場合は完全に条件を満たす行列が存在するとは限らず、近似値になる可能性があります。
  • 近似的に3×3行列を求めるには、Excelを使用する方法があります。Excelの行列計算機能を利用して、既知の変数の値と行列式を入力し、求めたい行列の値を計算することができます。また、フリーソフトでも同様の行列計算が可能です。
回答を見る
  • ベストアンサー

3行3列の行列(近似値)を求めたい

A,B,C,I,J,Kの6つの既知の変数に対して 以下の行列式を成立させるa1~a3, b1~b3, c1~c3が 存在するとします。 (A B C) | ※求めたい行列 | = (I J K) ※求めたい行列 | a1 a2 a3 | | b1 b2 b3 | | c1 c2 c3 | A,B,C,I,J,Kが1通りであれば3×3行列は決定できると思いますが、 A,B,C,I,J,Kの組が複数ある場合、完全に条件を満たす3×3行列が あるとは限らず、実際のところ近似値になると思います。 A,B,C,I,J,Kは、幾通りあるにせよ既知の定数です。 例としてデータの組は添付ファイルのように複数あるとします。 近似的に3×3行列を求めるには、どのような計算を行えば 良いのでしょうか? そのような計算をExcelで行う方法、又はそれが可能なフリーソフトなど ありましたら教えて頂けませんでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • ramayana
  • ベストアンサー率75% (215/285)
回答No.2

データが4組以上あるときは、最小2乗法による回帰分析が使えます。 たとえば、データを(A,B,C,I,J,K)で表すとして、   データ1=(3,2,6,5,9,8)   データ2=(8,9,6,2,5,4)   データ3=(1,9,8,5,4,7)   データ4=(1,2,3,4,5,6) のとき、次の3種類の回帰分析(定数項がないモデル)を実行します。 1 非説明変数は(5,2,5,4)。説明変数は(3,8,1,1)、(2,9,9,2)、(6,6,8,3)の3系列。    ⇒ 計算された3個の係数パラメータは、a1,b1,c1の近似値 2 非説明変数は(9,5,4,5)。説明変数は(3,8,1,1)、(2,9,9,2)、(6,6,8,3)の3系列。    ⇒ 計算された3個の係数パラメータは、a2,b2,c2の近似値 3 非説明変数は(8,4,7,6)。説明変数は(3,8,1,1)、(2,9,9,2)、(6,6,8,3)の3系列。    ⇒ 計算された3個の係数パラメータは、a3,b3,c3の近似値 (Excelで実行する場合) Excelで実行する場合は、「分析ツール」の中の「回帰分析」が使えます。この場合、「定数に0を使用」というオプションをオンに設定します。 なお、Excelのリボンやツールバーに「分析ツール」が見つからないときは、まず、アドオンを有効にする必要があります。詳しい方法は、Excelのヘルプを参照してください。

kagiyo
質問者

お礼

ご回答ありがとうございます。 Excelで出来る、とのことで安心しました。 MATLABやMathmaticaなど、高価な学術用ソフトが必要なのかと心配していました。 さっそくやってみようと思います。

その他の回答 (1)

  • Mr_Holland
  • ベストアンサー率56% (890/1576)
回答No.1

 データが4セット以上ある場合は分かりませんが、例のようにちょうど3セットあるときは、求めたい行列を唯一に決めることができると思います。  ちょうど3セットの場合は、データA,B,Cで作った行列の逆行列を データI,J,Kで作った行列に左から掛けてやれば 求めたい行列が得られます。  参考までに、例のときの「求めたい行列」を表計算ソフトで計算したものを示します。  この行列に左から(A B C)を掛けてやれば厳密に(I J K)が得られます。 0.227848101, -0.006329114, 0.946202532 0.481012658, 0.208860759, 0.275316456 0.46835443, 0.348101266, -0.041139241 >A,B,C,I,J,Kが1通りであれば3×3行列は決定できると思いますが、  1セットだけでは、いくらでも自由度が生じまい、一意に決定できません。  例えば例のデータ1のセットでしたら、勝手に次のように作れますが、これは他のデータセットには当てはまりません。 (3)(1,1,0) (5) (2)(1,0,1)=(9) (6)(0,1,1) (8)

kagiyo
質問者

お礼

ご回答ありがとうございます。 3セットまでなら一意に決定できるのですか。行列についての知識は、学生時代の古い記憶のみを頼りに考えていました。もう少し勉強しなおそうと思います。

kagiyo
質問者

補足

データが1セットだけでは、確かに一意には決定できませんね。 実際のデータ数は、数十~数百を想定しています。

関連するQ&A

  • 数学 可換な行列

    A=a 2 0 a と可換な行列をすべて求めよ。という問題なのですが、答えは b c 0 b となるらしいです。しかし、画像の計算をみると、d=0,b=eとなっているので、 b c 0 e では駄目なのでしょうか?また、 a 1 0 0 a 1 1 0 a と可換な行列をすべて求めよ。という問題ではBを b c d e f g h i j とおき、AB=BAで計算しますが、答えが b=f=j=k1,c=g=h=k2,… B= k1 k2 k3 k3… といった感じに任意定数におきかえています。 最初の問題に戻りますが、b=e=任意定数 にならない理由はなんでしょうか?お願いします。

  • 行列の計算について。

    こんにちは。 JAVAで行列の計算をするプログラムを作っていますが、なかなかうまくいきません。 自分で考えたのはfor文を使った物です。行列数を入力するとその数だけの行列を作る、という物なのですが、どうもうまくいきません。 「2」を入力すると、 │1 2││5 6│ │   ││   │ │3 4││7 8│ こんな2行2列の行列の計算をする、というものです。 for (int i =0; i < 2; i++){ for (int j = 0; j<2; j++){ for (int k = 0; k<2; k++){ C[i][j]=C[i][j]+a[i][k]*b[k][j]; } } } 上のようなプログラムを考えました。 JAVAには行列の計算をする専用の関数(クラス?)などあるのでしょうか? また、ソースなど教えていただけると、とても助かります。 CからJAVAに急に移ったので、つまづくことが非常に多いです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 行列の計算

    お恥ずかしいながら、行列の計算でてこずっております。 以下の問題です。 行列A、Bをn×n行列とする。 また行列Aのi,j成分をa(i,j)とし、行列Bのi,j成分をb(i,j)とする。 ここで a(i,j) = {n-i+1 (1≦j≦i), n-j+1(i+1≦j≦n)} b(i,j) = {1(i=j=1), 0(i≠j-1, j, j+1), -1(i=j-1, j+1), 2(j=k)} である。 このとき、行列A×Bのi,j成分を求めよ。 という問題です。 答えはi=jのとき1,i≠jのとき0 (つまり、A×B=I(n×nの単位行列)) なのですが、そこまでの計算のプロセスが分かりません。 分かり易いご解答をお待ちしております。

  • 行列の積について

    3行3列の行列AとB、およびその和と積を表示するものです #include <stdio.h> int main (void) { int i,j,k; double a[3][3] = {{2.4, 5.5, -8.5},{0.8, 3.7, 1.1},{3.5, -9.1, 2.6}}; double b[3][3] = {{-5.1, 9.8, 2.3},{-4.1, 0.2, -0.3},{3.3, 6.1, -1.3}}; double c[3][3] = {0}; printf(" 行列A\n"); for (i = 0; i < 3; i++){ for (j = 0; j < 3; j++) printf("%5.1f", a[i][j]); printf("\n"); } printf("\n 行列B\n"); for (i = 0; i < 3; i++){ for (j = 0; j < 3; j++) printf("%5.1f", b[i][j]); printf("\n"); } printf("\n 行列A+B\n"); for (i = 0; i < 3; i++){ for (j = 0; j < 3; j++) c[i][j] = a[i][j] + b[i][j]; } for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) printf("%5.1f", c[i][j]); printf("\n"); } for (i=0; i<3 ; i++){ for (j=0; j<3; j++) for (k=0; k<3; k++) c[i][j] =c[i][j]+ a[i][k]* b[k][j]; } printf("\n 行列AB\n"); for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) printf("%7.2f", c[i][j]); printf("\n"); } return 0; } これだと積だけが異なった値が出てしまいます。 試しに、積の部分だけで組んでみると正しい答えが出ました。 for文のブロックの組み方がまずいのかなと思っていますが、これ以外だと、行列のレイアウトが崩れてしまいます どのように直したらいいのか、ご教示お願いします

  • 転置行列 証明 行列の積

    転置行列の証明について疑問点があるので 質問させて頂きます。 t(AB)=t(B)t(A) の証明について。以下に示します。 行列 A の (i,j) 成分を A[i,j] と書くことにします。 行列Bも同様。 (t(AB))[i,j] = (AB)[j,i] = Σ A[j,k] B[k,i] = Σ (tA)[k,j] (tB)[i,k]  …(1) = Σ (tB)[i,k] (tA)[k,j]  …(2) = ((tB)(tA))[i,j] よって、 t(AB) = (tB)(tA) (1)についてよくわかりません。 行列の積は、 (l,m)行列と(m,n)行列の積は(l,n)行列と定義されますが (1)は(m,l)行列と(n,m)行列の積を計算することに ならないのでしょうか? (m,l)行列と(n,m)行列の積は定義されないので等式でつないでは いけないのでは?と考えた次第です。 以上、ご指摘、ご回答よろしくお願い致します。

  • 行列の計算

    #include<stdio.h> #define N 2 #define M 3 void hyoji(float[][M]); int main(){ int i,j,k; float a[N][M] = {{2.0,2.0,2.0},{2.0,2.0,2.0}}; float b[M][M] = {{1.0,1.0,1.0},{2.0,2.0,2.0},{1.0,1.0,1.0}}; float c[N][N]; for(i=0; i<N; i++){ for(j=0; j<M; j++){ c[i][j] = 0; for(k=0; k<M; k++){ c[i][j] += a[i][k] * b[k][j]; } } } hyoji(c); return(0); } void hyoji(float x[][M]){ int i,j; for(i=0; i<N; i++){ for(j=0; j<M; j++){ printf("%4.1f ",x[i][j]); } printf("\n"); } } 以上のプログラムで 行列aと行列bをかけ合せた行列cを求めるのですが コンパイルすると 8 8 8 8 8 1 となり、正しい結果がでません。 なにが間違っているのでしょうか?? よろしくお願いします。

  • 行列の問題でわからないところが。

    (1)成分に実数を含む行列を以下のように定義する。 │a 1 1 1│ │1 a 1 1│ │1 1 a 1│ │1 1 1 a│ rank(a)=3となるようなaの値を求めよ。 どのように計算したら良いのかわかりません… どなたか計算例等を説明いただけないでしょうか? (2) Aはn次正則行列で、n次正方行列BはAの逆行列である。またn次正方行列CはBの第i行と第j行を交換してできる行列であるとする。 このとき、Cの逆行列の第(i,j)成分はAの成分を用いて表すことができる。 答えはaiiになるんですが過程がわかりません… もし、過程がわかる方いましたらご教授下さい。 よろしくお願いします。

  • 行列 積 定義

    行列 積 定義 A=(a_ij) を (l,m) 行列,B=(b_ij) を (m,n) 型の行列とする.このとき C = AB の (i, j) 成分 cij は、    m c_ij = Σ a_ik*b_kj=(a_i1*b_1j)+(a_i2*b_2j)・・・(a_im*b_mk)で与えられる.    k=1 と有るのですが・・・・ 式の意味がさっぱり分かりません・・・ kってなんでしょうか? なぜ、 a_ik*b_kjの総和を考えているのでしょうか? 2×2行列を具体的に考えて良く分からなかったので、ご教示頂けるとありがたいです。 ご回答よろしくお願い致します。

  • 近似式の証明

    (1+i)a=(1+j)b が成立する時、任意のi,j,a,bに対し j-i≒a-b であることを級数を使って証明出来るという人がいます。 変数の条件等は一切無しです。私は出来ないと思ったのですが、もし出来るなら教えて下さい。 (2つ目の式は近似式です)

  • 行列の積を関数を使って求める・・?

    2つの行列の行と列を入力し、積を計算するプログラムを関数を使って書きたいのですが、上手く行きません。どこをどのように直したらよいか教えてください!お願いします!! 以下が私が書いたプログラムです。 #include<stdio.h> #define NUMBER 10 int first(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; do{ printf("2つの行列の行と列を入力してください\n"); scanf("%d", &x1); scanf("%d", &x2); scanf("%d", &y1); scanf("%d", &y2); if(x1 != y2){ printf("行列の積は計算できません\n"); } }while(x1 != y2); printf("行列Aの要素を入力してください\n"); for(i=0; i<x1; i++){ for(j=0; j<x2; j++) scanf("%d", &a[i][j]); } printf("行列Bの要素を入力してください\n"); for(j=0; j<y1; j++){ for(k=0; k<y2; k++) scanf("%d", &b[j][k]); } } int second(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; for(i=0; i<x1; i++){ for(k=0; k<y2; k++){ for(j=0; j<x2; j++) c[i][k] = c[i][k] + a[i][j]*b[j][k]; } } for(i=0; i<x2; i++){ for(k=0; k<y2; k++) printf("%3d", c[i][k]); printf("\n"); } } int main(void) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; printf("行列の積を計算します\n %d\n", first(x1,x2,y1,y2,i,j,k)); printf("行列Aと行Bの積は\n %3d",second(x1,x2,y1,y2,i,j,k)); }