• ベストアンサー

C言語プログラム

N次の複素正方行列S,Tの積Uを計算するプログラムを作りたいのですが、実数で正方行列を計算するプログラムと 複素数の積、和のプログラム struct complex { double re; double im; }; を作ったのですが、この二つをまとめるとプログラムができるらしいのですがまとめ方が全然わかりません。どのようにしたらいいかヒントなど教えてください。

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

  • ベストアンサー
回答No.1

実数の正方行列の積が計算できているということは、その、S, T, U の要素を表す配列がありますね? おそらく、double の配列になっていると思います。 その配列の型を、struct complex にします。 そして、正方行列の積を計算するということは、配列 S の要素と T の要素の積を、U の要素に足し込むという計算をしているはずです。 その中の、例えば、 U += S * T; を一度、 U = U + S * T; と置き直します。(実際には配列の名前ではなくて、個々の要素のはず) で、複素数の、和と積がそれぞれ関数として準備されているのであれば、それぞれ、 複素数の a + b が struct complex add(strcunt complex a, struct complex b); a * b が struct complex mul(strcunt complex a, struct complex b); などという関数になっているはずです。 そこで、上で書いた、 + と * を add と mul に置き換えて U = add(U, mul(S, T)); と置き換えるだけです。 入出力は、適切な形で処理してください。

その他の回答 (1)

  • Interest
  • ベストアンサー率31% (207/659)
回答No.2

私なら、自分でこういう計算のための関数を作らないで済ませる方法を探します。 具体的には、 (a) C99準拠のCコンパイラを使用しているなら自分で複素計算の関数を作らずに _Complex 型を使う。 (b) C++を使って問題ないのであればC++の標準ライブラリにある complexクラスを使う。 (c) C++でOKなら、さらにBoostライブラリをインストールして、行列演算までライブラリに任せてしまう。 (d) Matlabを使える環境にあるならMatlabをC言語から呼び出して使う。 (e) Matlabクローンでも良ければ Scilab をC言語から呼び出して使う。 複素数演算も行列演算も、自分で作ると時間がかかるし、処理速度も遅く、バグも作りこむことになります。本来の目的に注力するためにも、先人の知恵を使わせてもらうことをおすすめします。

関連するQ&A

  • C言語で

    C言語で複素行列の和と積を計算するプログラムを作りたいのですが、 よくわからないので教えてほしいです。複素数を構造体で定義して、配列を使えば いいと思うのですが・・・。 ちなみに実数の行列の和と積を求めるプログラムはわかっています。

  • c言語の、voidの使い方で困っています

    C言語の問題を教えて下さい。 この問題で困っています。 複素数z1,z2の引き算、掛け算を計算する構造体complexを引数、 戻り値とする関数 complex hikizan(complex z1,complex z2) complex kakezan(complex z1,complex z2) を作成し、 複素数を画面に表示する関数 void show(complex x) で結果を表示するプログラムを作りなさいという問題です。 z1=1+3i z2=2+2i です。 作ってみたのですが、void show(complex x)を使う方法が分かりません。 教えて下さい、お願いします。 以下、作ったプログラムです #include<stdio.h> typedef struct complex{ double re; double im; } complex; complex hikizan(complex z1,complex z2) { complex z; z.re=z1.re-z2.re; z.im=z1.im-z2.im; return z; } complex kakezan(complex z1,complex z2) { complex zz; zz.re=z1.re*z2.re-z1.im*z2.im; zz.im=z1.re*z2.im+z1.im*z2.re; return zz; } int main(void) { complex z1,z2,z,zz; z1.re=1; z1.im=3; z2.re=2; z2.im=2; z=hikizan(z1,z2); zz=kakezan(z1,z2); printf("z1-z2=%f+%fi \n",z.re,z.im); printf("z1*z2=%f+%fi \n",zz.re,zz.im); }

  • C言語の複素数についてです。

    C言語で複素数を使うことになりましたが、複素数をプログラム上でどう使うかわかりません。 粒子の複素屈折率を計算してシミュレーションするというものです。 その複素屈折率は 0.57+2.74i と表されます。iが虚数です。 一般的にCプログラムで複素数を使えるようにする一番簡単な方法はなんでしょうか? 具体的に参考にできるプログラムコードとかあれば是非教えて下さい。 #define complex とか使うのでしょうか? おそらくcomplexというものを使うんだとは思います。実数部と虚数部を分けて考えるのでしょうか。 C言語、いまいちよくわからなくて……どなたか詳しい方、教えて下さい。

  • C言語で

    同名の質問で、 ”C言語で複素行列の和と積を計算するプログラムを作りたいのですが、 よくわからないので教えてほしいです。 ~以下略~” という質問がありました。 それについてnubouさんが答えていましたが、私の 場合は同じことができません。(ANo.1 ANo.2) ボーランドからダウンロードして、indludeファイルに complexというhファイルもあるのです。 しかし、コンパイルしようとすると、 致命的エラー F1003 c:\Borland\Bcc55\include\stdcomp.h 5: error 指令: Must use C++ for STDCOMP.H がでてしまいます。 私の場合はインストールの仕方が違うのでしょうか。 またCとC++が統合されているということも わからないのですが。 (私のは統合されていない?) お手数をおかけしますが、よろしくお願いします。

  • C++についての質問です

    プログラミング初心者です n次正方行列同士の積のプログラムを作成したいのですがどうもうまくいかないです 次元及び成分を入力させて計算させたいです よろしくお願いいたします。

  • 複素正方行列の対数

    複素正方行列の指数関数は、実数域でのマクローリン展開を単純に拡張して xが実数のとき、   exp(x) = 1 + x + x^2/2 + x^3/6 + x^4/24 + ... より、Aが複素正方行列のとき (Eは単位行列)   exp(A) = E + A + A^2/2 + A^3/6 + A^4/24 + ... と、できることがわかりました。 一方、対数関数に関しても同様に、 xが実数のとき、   log(1+x) = x - x^2/2 + x^3/3 - x^4/4 + x^5/5 - x^6/6 + ... より、Aが複素正方行列のとき (Eは単位行列)   log(E+A) = E - A^2/2 + A^3/3 - A^4/4 + A^5/5 - A^6/6 + ... で、単純に可能かと思ったのですが違いました。 例えば、具体的に、実数正方行列  { 2, 3 }  { 4, 5 } の対数は、  { -0.304+2.195i, 1.302-1.248i }  { 1.736-1.664i, 0.997+0.947i } となりますが、前記のように単純にマクローリン展開を拡張した方法では、 実数係数の行列から複素係数が出てくることはありえないことからも、 簡単に間違っていることがわかります。 ということで、複素正方行列のマクローリン展開の方法または、 具体的な計算方法(アルゴリズム)をご存知の方がおられましたら ご教示ください。

  • ”エルミート対称行列と複素対角行列の積”への変換

    ある複素正方行列を  ”エルミート対称行列と複素対角行列の積” へ変換する方法はございますでしょうか?

  • プログラム初心者で以下の問題が検討すらできません。どなたか参考にどのようなプログラムになるか教えてください。

    抵抗とコンデンサからなる並列回路の複素インピーダンスとその絶対値を求めるプログラムを作成。 プログラムは、抵抗の値、コンデンサの容量、周波数を入力すると、複素インピーダンスとその絶対値を求めその結果を表示するものである。 私の解答です /* * mycomplex.c: 複素数関数 */ #include <stdio.h> #include <math.h> #include "mycomplex.h" /* 複素数の文字列を作る */ char *printc(mycomplex z) { static char str[BUFSIZ]; sprintf(str, "(%lf, %lf)", real(z), imag(z)); return str; } /* 実数と虚数を与えて複素数を作る */ mycomplex mkcomplex(double r, double i) { mycomplex z; z.re = r; z.im = i; return z; } /* 絶対値と偏角を与えて複素数を作る */ mycomplex mkcomplex_at(double abs, double theta) { mycomplex z; z.re = abs * cos(theta); z.im = abs * sin(theta); return z; } /* ノルム */ double norm(mycomplex z) { return z.re * z.re + z.im * z.im; } /* 絶対値 */ double cabs(mycomplex z) { return sqrt(norm(z)); } /* 偏角 */ double carg(mycomplex z) { return atan2(z.im, z.re); } /* 共役複素数 */ mycomplex conj(mycomplex a) { mycomplex z; z.re = a.re; z.im = 0.0 - a.im; return z; } /* 逆数 */ mycomplex cinv(mycomplex a) { mycomplex z; double n; n = norm(a); z.re = a.re / n; z.im = 0.0 - a.im / n; return z; } /* 加算 */ mycomplex cadd(mycomplex a, mycomplex b) { mycomplex z; z.re = a.re + b.re; z.im = a.im + b.im; return z; } /* 減算 */ mycomplex csub(mycomplex a, mycomplex b) { mycomplex z; z.re = a.re - b.re; z.im = a.im - b.im; return z; } /* 乗算 */ mycomplex cmul(mycomplex a, mycomplex b) { mycomplex z; z.re = a.re * b.re - a.im * b.im; z.im = a.re * b.im + a.im * b.re; return z; } /* 除算 */ mycomplex cdiv(mycomplex a, mycomplex b) { mycomplex z; double n; n = norm(b); z.re = (a.re * b.re + a.im * b.im) / n; z.im = (a.im * b.re - a.re * b.im) / n; return z; } /* sin */ mycomplex csin(mycomplex a) { mycomplex z; double ep; ep = exp(a.im); z.re = sin(a.re) * (ep + 1.0 / ep) / 2.0; z.im = cos(a.re) * (ep - 1.0 / ep) / 2.0; return z; } /* cos */ mycomplex ccos(mycomplex a) { mycomplex z; double ep; ep = exp(a.im); z.re = cos(a.re) * (ep + 1.0 / ep) / 2.0; z.im = sin(a.re) * (1.0 / ep - ep) / 2.0; return z; } /* tan */ mycomplex ctan(mycomplex a) { return cdiv(csin(a), ccos(a)); } /* exp */ mycomplex cexp(mycomplex a) { mycomplex z; double ep; ep = exp(a.re); z.re = ep * cos(a.im); z.im = ep * sin(a.im); return z; } /* log 自然対数 (natural logarithm) */ mycomplex clog(mycomplex a) { mycomplex z; z.re = log(norm(a)) / 2.0; z.im = atan2(a.im, a.re); return z; } /* log10 常用対数 (logarithm to base 10) */ mycomplex clog10(mycomplex a) { mycomplex z; z.re = M_LOG10E * log(norm(a)) / 2.0; z.im = M_LOG10E * atan2(a.im, a.re); return z; }

  • 構造体

    プログラミングの授業で構造体を習ったのですが、課題がよく分からないので質問させていただきます。その課題ですが、 複素数を表す構造体を、 struct complex{float r;(実部)float i;(虚部)}; の形で定義したとして、2つの複素数を入力し、その2つの絶対値の2乗、和、差、積、商を求めるプログラムを作るというものです。 ただし、条件として、 複素数を入力する関数void inputComp(struct complex*c)、複素数をa+biのような形に表示する関数void printComp(struct complex*c)、複素数の絶対値の2乗を関数値として返す関数float asqrComp(struct complex*c)を作成せよというのがあって困っています。 条件がなければprintfを多用してできないこともないでしょうが、条件を満たすプログラムを教えてください。

  • 複素数の固有値の求めるプログラムについて

    現在、C言語でプログラムを組んでいるのですが、複素数からなる行列の固有値を求めるプログラムがどうしてもつくることができません。 インターネットやプログラムのパッケージなどを調べてみたのですが、実数からなる行列の固有値を求めるプログラムしか載っておらず、勉強不足によりそれを複素数の場合に拡張することもできませんでした。 もしよければ、プログラムの組み方や実数のプログラムから複素数のプログラムへの替え方のこつ、もしくは「この本に載っていたよ」など、どんな情報でもかまいませんので教えて頂けないでしょうか? すいませんがよろしくお願いします。

専門家に質問してみよう