C言語関係掲示板

過去ログ

No780 複素数の逆行列

[戻る] [ホームページ]
No.9680

複素数について
投稿者---あやこ(2003/10/09 22:15:25)


学校の課題で、複素数の逆行列を求める課題が出されたのですが、私には、手も足も出ません。
どなたか教えて下さいませんか?
よろしくお願いします。

No.9686

Re:複素数について
投稿者---YuO(2003/10/10 00:25:43)


>学校の課題で、複素数の逆行列を求める課題が出されたのですが、私には、手も足も出ません。

とりあえず,
・実数の逆行列を求めることができる
・複素数の四則演算ができる
必要があります。

まずはそれらができるようにとにかく調べましょう。
数値計算に関する本を探せば,どっちも載っていると思います。

まぁ,C99の処理系使ってdouble _Complexあたりを使えば,
複素数も実数とほとんど変わらないですが……。
#演算子がそのまま使える。


No.9699

Re:複素数について
投稿者---たか(2003/10/10 21:32:47)


>学校の課題で、複素数の逆行列を求める課題が出されたのですが、私には、手も足も出ません。
>どなたか教えて下さいませんか?
>よろしくお願いします。

複素数の四則演算はわかりますよね。+,−,×,÷。
そしたらそれをそのままガウス・ジョルダン消去法(掃き出し法)に当て
はめるだけです。
掃き出し法の具体的なプログラムはここ当たりを参考に。
これは実数の逆行列を求めるプログラムですが、四則演算を複素数にする
だけでそのまま使えます。

No.9700

Re:複素数について
投稿者---たか(2003/10/10 21:36:30)


なお、C++には complexクラスが標準ライブラリにありますので、それを
使ってもよいなら"複素数の四則演算を知らなくても"そのまま掃き出し法
が適用できます。ほとんど意味ないですけど。

No.9701

Re:複素数について
投稿者---たか(2003/10/10 22:07:49)


強いて言えば、あからさまな関数コールやその場での四則演算の展開を
せずとも演算子の多重定義によってほとんど元のプログラムに手を加えず
に使えるのがcomplexクラスの強みですね。

No.9702

Re:複素数について
投稿者---あやこ(2003/10/10 22:49:47)


たかさん、YuOさん
本当にありがとうございます!!!
今から試みてみます!!!

本当にカンシャです。

No.9764

Re:複素数について
投稿者---あやこ(2003/10/14 17:26:17)


すみません、再び質問です。

実数の逆行列のプログラム、複素数の四則演算はおかげさまで、できるようになりました。
それで、実数の逆行列の計算部分を複素数の計算にそっくりそのまま変えてやってみたのですが、どうも出てくる結果がおかしいのです。
何度もエラーを探してみたのですが、どこもおかしくないみたい。

複素数の逆行列って実数の逆行列と同じ計算でいいんですか?

No.9770

Re:複素数について
投稿者---たか(2003/10/14 19:10:28)


>それで、実数の逆行列の計算部分を複素数の計算にそっくりそのまま変えてやってみたのですが、どうも出てくる結果がおかしいのです。
>何度もエラーを探してみたのですが、どこもおかしくないみたい。
>
>複素数の逆行列って実数の逆行列と同じ計算でいいんですか?

線形計算の大部分は実数をそのまま複素数に置き換えても正しい結果が
出ます。逆行列を掃き出し法で求めるのもその一つです。

よろしかったらソースを貼っていただけませんか?

No.9771

Re:複素数について
投稿者---たか(2003/10/14 20:41:21)


式がややこしくなるのを避けるために、C++でcomplexクラスを使って
例題を解いてみました。Cではこんなスマートには書けませんが、
Complex構造体でも作って自前で四則演算をすれば全く同じ結果に
なるはずです。

#include <iostream>
#include <complex>

void inv_complex(std::complex<double> a[2][2], int n);
void mul_complex(std::complex<double> a[2][2], std::complex<double> b[2][2], std::complex<double> c[2][2], int n);

int main()
{
  std::complex<double> A[2][2], invA[2][2], res[2][2];
  
//  A = |1-i 2-i|
//      |2+i 3+i|
  
  A[0][0] = std::complex<double>(1, -1);
  A[0][1] = std::complex<double>(2, -1);
  A[1][0] = std::complex<double>(2,  1);
  A[1][1] = std::complex<double>(3,  1);

  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++)
      invA[i][j] = A[i][j];
      
  inv_complex(invA, 2);

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++)
      std::cout << invA[i][j] << " ";
    std::cout << std::endl;
  }

  mul_complex(A, invA, res, 2);

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++)
      std::cout << res[i][j] << " ";
    std::cout << std::endl;
  }
}

void inv_complex(std::complex<double> a[2][2], int n)
{
  std::complex<double> p, q;
  
  for (int k = 0; k < n; k++) {
    p = a[k][k];
    a[k][k] = std::complex<double>(1, 1);
    for (int j = 0; j < n; j++) a[k][j] /= p;
    for (int i = 0; i < n; i++)
      if (i != k) {
        q = a[i][k];
        a[i][k] = std::complex<double>(0, 0);
        for (int j = 0; j < n; j++) a[i][j] -= q * a[k][j];
      }
  }
}

void mul_complex(std::complex<double> a[2][2], std::complex<double> b[2][2], std::complex<double> c[2][2], int n)
{
  std::complex<double> s;

  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      s = std::complex<double>(0, 0);
      for (int k = 0; k < n; k++) s += a[i][k] * b[k][j];
      c[i][j] = s;
    }
}


No.9772

Re:複素数について
投稿者---あやこ(2003/10/14 21:18:57)


たかさん
ご丁寧にありがとうございます!!

でも、たかさんが書いてくださったプログラム、私の環境ではうまく動かないみたいです。うーーーん・・・。

VC++を使っているのですが・・・。

それから、以前たかさんが教えてくださった、ページのinvの意味が理解できず、

http://mukun_mmg.at.infoseek.co.jp/mmg/bncpp/al050.html

のページを参考にして逆行列を作ってみました。
分かりにくいかも知れませんが、どうぞお願いします。

#include<stdio.h>
#include<iostream>
using namespace std;

struct complex {
     	double real;
     	double imaginary;
 };


int main(void)
{
               int dim, i, j, k;          /* counter */      
	struct complex **a, temp, pivot, erase;

	printf( "the dimension is=" );
               scanf( "%d", &dim);

                /* secure the memory */
             	a = new struct complex*[dim];                      
    	for(i=0;i<dim;i++)a[i] = new struct complex[dim*2];
  
   	 /* put in the number */
   	for( i = 0; i < dim; i++ ){
       		for( j = 0; j < dim; j++ ){
			scanf("%lf %lf",&temp.real,&temp.imaginary);
           			a[i][j]=temp;   
        		}
   	 }
    
    	for(i=0;i<dim;i++){                       /* It is unit procession substitution to a right half */
       		for(j=dim;j<dim*2;j++){
            			a[i][j].real = 0;
			a[i][j].imaginary = 0;
			if(i==j-dim) {
				a[i][j].real = 1;
				a[i][j].imaginary = 0;
			}
        		}
    	}
    
    	for(i=0;i<dim;i++){                                                   /* It sweeps out and is a part */
        		pivot.real = a[i][i].real;                               /* The number of pivots is acquired */
		pivot.imaginary = a[i][i].imaginary;
		for(j=i;j<dim*2;j++){                                 /* n formula is broken by the pivot */
		           /*a[i][j]/=pivot*/
	          a[i][j].real=( (a[i][j].real*pivot.real) + (a[i][j].imaginary*pivot.imaginary) )/( (pivot.real*pivot.real) + (pivot.imaginary*pivot.imaginary) );
		          a[i][j].imaginary=( (a[i][j].real*(-pivot.imaginary)) + (a[i][j].imaginary*pivot.real) )/( (pivot.real*pivot.real) + (pivot.imaginary*pivot.imaginary) );
		}
		for(k=0;k<dim;k++){                                   /* n clause is eliminated */
            			erase.real=a[k][i].real;                   /* The coefficient of the formula to eliminate */
			erase.imaginary=a[k][i].imaginary;
		    	for(j=i;j<dim*2;j++){                   /* It sweeps out in the fruit case and processes */
                			if(k!=i){
					/*a[k][j]-=erase*a[i][j];*/
					a[k][j].real=a[k][j].real - ( (erase.real * a[i][j].real) - (erase.imaginary * a[i][j].imaginary) );
					a[k][j].imaginary=a[k][j].imaginary - ( (erase.real * a[i][j].imaginary) + (erase.imaginary * a[i][j].real) );
				}
            			}
        		}
    	}
    
    	for(i=0;i<dim;i++){                       /* display result  */
        		 for(j=dim;j<dim*2;j++){
           			printf( "%10lf %10lfi ", a[i][j].real, a[i][j].imaginary );	
		}
	putchar( '\n' );
            	}
    	return 0;
}







No.9774

Re:複素数について
投稿者---たか(2003/10/14 21:54:58)


>でも、たかさんが書いてくださったプログラム、私の環境ではうまく動かないみたいです。うーーーん・・・。
>
>VC++を使っているのですが・・・。

このプログラムは今から見てみます。今日中にバグが見つかるかどうか
わかりませんが・・・・できれば四則演算はその場で展開せず関数にし
た方がずっと見通しがよくなりますよ。

それからこれは計算精度を上げるためにピボット選択をしていますから
なおさらプログラムが複雑になっています。

また、私のプログラムはVC++では動きません。それはなぜかというと、
for (int i = 0; の部分でVC++はfor文の条件部内で定義した変数の寿命
が標準C++ではなく古いC++と同じ、関数が終わるまで続いてしまうからで
す。

ですからVC++で私のプログラムを動かすには int i, j, k; と初めに定義
しておいてfor文内での変数の定義をやめれば動くはずです。

また、newを使っておいでですが、deleteお忘れですよ。減点の対象となる
かもしれません。普通C++では汎用の配列にはstd::vectorを使います。
二次元配列なら次のようにすればnewもdeleteも不要です。

#include <vector>
#include <complex>

typedef std::complex<double> Cs;

int main()
{
  const int n = 2;
  
  std::vector<std::vector<Cs> > A(n, std::vector<Cs>(n));
  
  A[0][0] = Cs(0, 0);
  ....
}


No.9778

Re:複素数について
投稿者---たか(2003/10/14 23:16:14)


一つバグを見つけましたが、これでも結果はおかしいです。
それと私のプログラムにもバグがありましたので正しいプログラムをup
しておきます。今度はVC++でも動く形で。

48行目
a[i][j].imaginary=( (a[i][j].real*(-pivot.imaginary)) + (a[i][j].imaginary*pivot.real) )/( (pivot.real*pivot.real) + (pivot.imaginary*pivot.imaginary) );
->
a[i][j].imaginary=(a[i][j].real*pivot.imaginary - a[i][j].imaginary*pivot.real)/(pivot.real*pivot.real + pivot.imaginary*pivot.imaginary);

VC++でも動くと思われるプログラム

#include <iostream>
#include <complex>

typedef std::complex<double> Csd;

void inv_complex(Csd a[2][2], int n);
void mul_complex(Csd a[2][2], Csd b[2][2], Csd c[2][2], int n);

int main()
{
  Csd A[2][2], invA[2][2], res[2][2];
  int i, j;
  
//  A = |1+i 1-2i|
//      |2-i 1-2i|
  
  A[0][0] = Csd(1,  1);
  A[0][1] = Csd(1, -2);
  A[1][0] = Csd(2, -1);
  A[1][1] = Csd(1, -2);

  for (i = 0; i < 2; i++)
    for (j = 0; j < 2; j++)
      invA[i][j] = A[i][j];
      
  inv_complex(invA, 2);

  for (i = 0; i < 2; i++) {
    for (j = 0; j < 2; j++)
      std::cout << invA[i][j] << " ";
    std::cout << std::endl;
  }

  mul_complex(A, invA, res, 2);

  for (i = 0; i < 2; i++) {
    for (j = 0; j < 2; j++)
      std::cout << res[i][j] << " ";
    std::cout << std::endl;
  }
}

void inv_complex(Csd a[2][2], int n)
{
  Csd p, q;
  int i, j, k;
  
  for (k = 0; k < n; k++) {
    p = a[k][k];
    a[k][k] = Csd(1, 0);
    for (j = 0; j < n; j++) a[k][j] /= p;
    for (i = 0; i < n; i++)
      if (i != k) {
        q = a[i][k];
        a[i][k] = Csd(0, 0);
        for (j = 0; j < n; j++) a[i][j] -= q * a[k][j];
      }
  }
}

void mul_complex(Csd a[2][2], Csd b[2][2], Csd c[2][2], int n)
{
  Csd s;
  int i, j, k;

  for (i = 0; i < n; i++)
    for (j = 0; j < n; j++) {
      s = Csd(0, 0);
      for (k = 0; k < n; k++) s += a[i][k] * b[k][j];
      c[i][j] = s;
    }
}


No.9779

Re:複素数について
投稿者---たか(2003/10/14 23:40:25)


これだと正しい結果が出るので、やはりどこか複素数の四則演算の展開
が間違っていると思われます。済みませんもう寝ますのでもし間違いを
見つけられた方はご指摘お願いします。

#include<iostream>
#include<complex>
using namespace std;

typedef complex<double> Complex;

int main(){
    int dim, i, j, k;          /* カウンタ */
    Complex pivot,erase;        /* ピボット数、消去係数 */
    Complex** a;                /* 連立方程式の各係数 */
    
    cout << "行列の次数は : ";   /* 次元数の入力 */
    cin >> dim;
    
    a = new Complex*[dim];                      /* メモリ確保 */
    for(i=0;i<dim;i++)a[i] = new Complex[dim*2];
    
    for(i=0;i<dim;i++){                        /* 係数入力部 */
        for(j=0;j<dim;j++){
            cout << "a[" << i << "][" << j << "] : ";
            cin >> a[i][j];
        }
    }
    
    for(i=0;i<dim;i++){                       /* 右半分に単位行列代入 */
        for(j=dim;j<dim*2;j++){
            a[i][j] = Complex(0,0);
            if(i==j-dim) a[i][j] = Complex(1,0);
        }
    }
    
    for(i=0;i<dim;i++){                       /* 掃き出し部 */
        pivot = a[i][i];                      /* ピボット数を取得 */
        for(j=i;j<dim*2;j++) a[i][j]/=pivot;  /* n式をピボットで割る */
        for(k=0;k<dim;k++){                   /* n項を消去する */
            erase=a[k][i];                    /* 消去する式の係数 */
            for(j=i;j<dim*2;j++){             /* 実際の掃き出し処理 */
                if(k!=i) a[k][j]-=erase*a[i][j];
            }
        }
    }
    
    for(i=0;i<dim;i++){                       /* 結果表示 */
        cout << " ( ";
        for(j=dim;j<dim*2;j++){
            cout << a[i][j] << ' ';
        }
        cout << " ) " << endl;
    }
    
    for(i = 0; i < dim; i++) delete[] a[i];
    delete[] a;
    
    return 0;
}


No.9780

Re:複素数について
投稿者---あやこ(2003/10/14 23:40:53)


本当にありがとうございます!!!
たかさんすごいですね!!
すぐにこんなプログラムが書けてしまうなんて。
私は初心者なのでたかさんのプログラムをすぐには理解できそうにありませんが、頑張ってみます。

すみませんが、ここでまた質問してもよいですか?
4行目の
typedef std::complex<double> Csd;
ですが、
"std::", "Csd"
って何を意味しているのですか?

教えていただけますか?お願いします。



No.9781

Re:複素数について
投稿者---たか(2003/10/14 23:49:38)


>私は初心者なのでたかさんのプログラムをすぐには理解できそうにありませんが、頑張ってみます。

C++の標準ライブラリについて勉強してみて下さい。必ず理解できます。

>すみませんが、ここでまた質問してもよいですか?
>4行目の
>typedef std::complex<double> Csd;
>ですが、
>"std::", "Csd"
>って何を意味しているのですか?

もしtypedef しないと、あらゆる場所でstd::complex<double>をCsdの
代わりにタイプしないといけないので楽するためです^^;。

stdはC++標準ライブラリの名前空間(namespace)名です。標準ライブラ
リをstd名前空間に包み込むことによって他の同じ名前の関数との曖昧
さを防いでいるのです。

No.9784

Re:複素数について
投稿者---たか(2003/10/15 09:22:04)


おはよう御座います。昨晩の謎が起きると同時にひらめいたので書いて
起きます。

47行目以降にバグがあったのです。a[i][j].realを一度更新したのに、
そのa[i][j].realをそのままa[i][j].imaginaryを求めるのに使っていま
した。これじゃあ正しい値が出るわけないですよね。

というわけでtempが余っていたので一度tempに代入した後、a[i][j].imaginary
を求めた後でtempをa[i][j]に代入した所ようやく正しい答えが出てきま
した。さてバリバリ仕事するぞー!!

#include<stdio.h>
#include<iostream>
using namespace std;

struct complex {
 	double real;
 	double imaginary;
 };


int main(void)
{
  int dim, i, j, k;          /* counter */      
	struct complex **a, temp, pivot, erase;

	printf( "the dimension is=" );
  scanf( "%d", &dim);

  /* secure the memory */
 	a = new struct complex*[dim];                      
 	for(i=0;i<dim;i++)a[i] = new struct complex[dim*2];
  
  /* put in the number */
 	for( i = 0; i < dim; i++ ){
 		for( j = 0; j < dim; j++ ){
			scanf("%lf %lf",&temp.real,&temp.imaginary);
 			a[i][j]=temp;   
 		}
  }
    
 	for(i=0;i<dim;i++){                       /* It is unit procession substitution to a right half */
 		for(j=dim;j<dim*2;j++){
 			a[i][j].real = 0;
			a[i][j].imaginary = 0;
			if(i==j-dim) {
				a[i][j].real = 1;
				a[i][j].imaginary = 0; 
			}
 		}
 	}
    
 	for(i=0;i<dim;i++){                                                   /* It sweeps out and is a part */
 		pivot.real = a[i][i].real;                               /* The number of pivots is acquired */
		pivot.imaginary = a[i][i].imaginary;
		for(j=i;j<dim*2;j++){                                 /* n formula is broken by the pivot */
      /*a[i][j]/=pivot*/
      temp.real=(a[i][j].real*pivot.real + a[i][j].imaginary*pivot.imaginary)/(pivot.real*pivot.real + pivot.imaginary*pivot.imaginary); /* Here was *WRONG! */
      temp.imaginary=-(a[i][j].real*pivot.imaginary - a[i][j].imaginary*pivot.real)/(pivot.real*pivot.real + pivot.imaginary*pivot.imaginary);
		  a[i][j]=temp;
    }
		for(k=0;k<dim;k++){                                   /* n clause is eliminated */
 			erase.real=a[k][i].real;                   /* The coefficient of the formula to eliminate */
			erase.imaginary=a[k][i].imaginary;
     	for(j=i;j<dim*2;j++){                   /* It sweeps out in the fruit case and processes */
   			if(k!=i){
  				/*a[k][j]-=erase*a[i][j];*/
	  			a[k][j].real=a[k][j].real - (erase.real * a[i][j].real - erase.imaginary * a[i][j].imaginary); 
		  		a[k][j].imaginary=a[k][j].imaginary - (erase.real * a[i][j].imaginary + erase.imaginary * a[i][j].real);
  			}
	  	}
  	}
	}
    
 	for(i=0;i<dim;i++){                       /* display result  */
 		 for(j=dim;j<dim*2;j++){
  			printf( "%10lf %10lfi ", a[i][j].real, a[i][j].imaginary );	
  	}
	putchar( '\n' );
 	}

 	for(i=0;i<dim;i++) delete[] a[i];
  delete[] a;
  
 	return 0;
}


No.9795

Re:複素数について
投稿者---あやこ(2003/10/15 16:45:03)


たかさん
本当に、本当に、ありがとうございました!!!
昨日も夜遅くまでほんとうにごめんなさい。

たかさんが、組んでくれたプログラムも理解できるように頑張ります。
本当にありがとうございました。

No.9796

Re:複素数について
投稿者---たか(2003/10/15 17:03:00)


>たかさんが、組んでくれたプログラムも理解できるように頑張ります。
>本当にありがとうございました。

いえいえ。お互い様です。
今日の昼休みに会社の同僚と2人で簡易Complexクラスを書いてみました。
これなら標準C++のcomplexクラスと違い、何をやっているのか一目瞭然
だと思うので参考にupしておきます。

#include<iostream>
#include<vector>
using namespace std;

class Complex;

void mul_complex(const vector<vector<Complex> >& a, const vector<vector<Complex> >& b, vector<vector<Complex> >& c, int dim);

class Complex {
  double re, im;
public:
  Complex(double x = 0, double y = 0) : re(x), im(y) {}
  Complex& Complex::operator/=(const Complex& a)
  {
    double re2, im2;
    
    re2 = (re * a.re + im * a.im) / (a.re * a.re + a.im * a.im);
    im2 = (-re * a.im + im * a.re) / (a.re * a.re + a.im * a.im); 
    
    re = re2;
    im = im2;
    
    return *this;
  }
  Complex& Complex::operator+=(const Complex& a)
  {
    re += a.re;
    im += a.im; 
    
    return *this;
  }
  Complex& Complex::operator-=(const Complex& a)
  {
    re -= a.re;
    im -= a.im; 
    
    return *this;
  }
  Complex& Complex::operator=(const Complex& a)
  {
    re = a.re;
    im = a.im;
    
    return *this;
  }
  friend Complex operator*(const Complex& a, const Complex& b);
  friend istream& operator>>(istream& is, Complex& a);
  friend ostream& operator<<(ostream& os, const Complex& a);
};

Complex operator*(const Complex& a, const Complex& b)
{
  Complex c;
  
  c.re = a.re * b.re - a.im * b.im;
  c.im = a.re * b.im + a.im * b.re;
  
  return c;
}

istream& operator>>(istream& is, Complex& a)
{
  is >> a.re >> a.im;
  
  return is;
}

ostream& operator<<(ostream& os, const Complex& a)
{
  os << a.re << ((a.im >= 0 ? "+" : "")) << a.im << 'i';
  
  return os;
}

int main(){
  int dim, i, j, k;          /* カウンタ */
  Complex pivot,erase;        /* ピボット数、消去係数 */
//  Complex** a;                /* 連立方程式の各係数 */
    
  cout << "行列の次数は : ";   /* 次元数の入力 */
  cin >> dim;
    
//  a = new Complex*[dim];                      /* メモリ確保 */
//  for(i=0;i<dim;i++)a[i] = new Complex[dim*2];
  
  vector<vector<Complex> > a(dim, vector<Complex>(dim * 2));
    
  for(i=0;i<dim;i++){                        /* 係数入力部 */
    for(j=0;j<dim;j++){
      cout << "a[" << i << "][" << j << "] : ";
      cin >> a[i][j];
    }
  }

  vector<vector<Complex> > b(a), c(a); // 列数をaに合わせる
    
    for(i=0;i<dim;i++){                       /* 右半分に単位行列代入 */
        for(j=dim;j<dim*2;j++){
            a[i][j] = Complex(0);
            if(i==j-dim) a[i][j] = Complex(1);
            b[i][j] = a[i][j - dim]; // bの右半分にaをコピー
        }
    }
    
    for(i=0;i<dim;i++){                       /* 掃き出し部 */
        pivot = a[i][i];                      /* ピボット数を取得 */
        for(j=i;j<dim*2;j++) a[i][j]/=pivot;  /* n式をピボットで割る */
        for(k=0;k<dim;k++){                   /* n項を消去する */
            erase=a[k][i];                    /* 消去する式の係数 */
            for(j=i;j<dim*2;j++){             /* 実際の掃き出し処理 */
                if(k!=i) a[k][j]-=erase*a[i][j];
            }
        }
    }
    
    for(i=0;i<dim;i++){                       /* 結果表示 */
        cout << " ( ";
        for(j=dim;j<dim*2;j++){
            cout << a[i][j] << ' ';
        }
        cout << " ) " << endl;
    }
    
    mul_complex(a, b, c, dim);

    for(i=0;i<dim;i++){                       /* 結果表示 */
        cout << " ( ";
        for(j=dim;j<dim*2;j++){
            cout << c[i][j] << ' ';
        }
        cout << " ) " << endl;
    }
    
    return 0;
}

void mul_complex(const vector<vector<Complex> >& a, const vector<vector<Complex> >& b, vector<vector<Complex> >& c, int dim)
{
  Complex s;

  for (int i = 0; i < dim; i++)
    for (int j = dim; j < dim*2; j++) {
      s = Complex();
      for (int k = dim; k < dim*2; k++) s += a[i][k] * b[k - dim][j];
      c[i][j] = s;
    }
}


No.9806

Re:複素数について
投稿者---あやこ(2003/10/15 22:55:56)


たかさん、いろいろとありがとうございます。
今の私には少し難しいですが、頑張って理解してみます。
本当にありがとうございました。