複素数

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
キリコ

複素数

#1

投稿記事 by キリコ » 18年前

どうもはじめまして。
わからないことがあって質問させていただきます。
複素数の割り算についてなのですが、まず
#include <stdio.h>
#include <math.h>
void xy_rt(double x,double y,double *pr,double *pt)
{
*pr=sqrt(x*x+y*y);
*pt=atan(y/x);
}

main()
{
double x1,y1,x2,y2,r1,t1,r2,t2;

if (scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2)!=4){
printf("4つ数字をいれてください\n");exit(1);
}

xy_rt(x1,y1,&r1,&t1);
xy_rt(x2,y2,&r2,&t2);
printf("答え=%6.2lf,%6.2lf\n",(r1/r2)*cos(t1-t2),
(r1/r2)*sin(t1-t2));
}
というプログラムができるのですが、atanは値域が-2/πから2/πでx>0,y>0またはx>0,y<0という制限があるのでx,yの符号から判断し、0から2πの角度を出力する2変数関数を新たに定義して書き換えてほしいのです。
本や、検索してもわからなかったので、自分なりにかんがえてz=a+biと考えて、やるのかとか、sinとcosの逆関数から判断するのかと思ったのですが、どうも角度を出力することができませんでした。
どなたかわかる方がいらしたら教えてください、お願いします。

ついでなのですが、実数部がゼロの場合に対応させるしかたも組み込んでくれるとありがたいです。

box

Re:複素数

#2

投稿記事 by box » 18年前

> 複素数の割り算

三角関数を使わずに、
a+bi   (a+bi)(c-di)   (ac+bd)+(bc-ad)i
---- = ------------ = ----------------
c+di   (c+di)(c-di)       c^2+d^2
という式(cとdの少なくとも一方は0でない)で
計算してもいいのですか?

キリコ

Re:複素数

#3

投稿記事 by キリコ » 18年前

返信ありがとうございます。

「ライブラリ関数atanのかわりにx,yの符号から判断し、0から2πの範囲の角度を出力する2変数関数を新たに定義」となっていたので、そのような角度が出ればいいと思います。
多分*pt=atan(y/x); を新たにするのかな?と思うのですが・・・どうもまだわかりません。

mas

Re:複素数

#4

投稿記事 by mas » 18年前

>「ライブラリ関数atanのかわりにx,yの符号から判断し、0から2πの範囲の角度を出力する2変数関数を新たに定義」

これを見る限り複素数でなくても良さそうですね。

x, y, atan(y/x)の正負に注目しましょう。
x  y  atan(y/x) θ
正 正 正        0~π/2
負 負 正        π~3π/2
となりますね。
つまりatanの正負に加えてx, yの正負で場合分けすれば良いのです。
以下サンプルです。
double theta = atan(y, x);
if(theta >= 0) {
  if(x >= 0)
    return theta;
  else
    return theta + M_PI;
}
atan(y/x)が負のときは自分で考えてみてください。

mas

Re:複素数

#5

投稿記事 by mas » 18年前

何かいろいろ間違えてしまったような…
サンプルとして挙げたソース
× atan(y, x)
○ atan(y/x)

そもそもatanやacos等を使ってはいけないのかな?
だとしたらすみません。

キリコ

Re:複素数

#6

投稿記事 by キリコ » 18年前

返信ありがとうございます。使ってよいとか悪いとかは書いてなく、2変数関数を新たに定義とかしか書いていないのですが、「ライブラリ関数atanのかわりに」のかわりという意味は使わないということでしょうかねぇ。微妙です。とりあえず、atanを使って角度を求める方法しかわかっていないのでなんともいえないのですが。
>acos等
これは私の勝手な思いつきなのですがacos asinでできそうな気がするのですがどうでしょう?

キリコ

Re:複素数

#7

投稿記事 by キリコ » 18年前

すみませんacos asinじゃ値域0~πと-π/2~π/2ですね。
うーん難しいです。

mas

Re:複素数

#8

投稿記事 by mas » 18年前

acos, asinを使っても良いのなら簡単にできますよ。
上のほうにatanの例を挙げましたが、x, yの正負に注目してπを足せばよいので。

キリコ

Re:複素数

#9

投稿記事 by キリコ » 18年前

返信ありがとうございます。

>acos, asinを使っても良いのなら簡単にできますよ。
>上のほうにatanの例を挙げましたが、x, yの正負に注目してπを足せばよいので。

すみませんがよければacos, asinのときどういった感じになるのか示してくれませんか?ちょっと自分の知識不足で理解できていないので・・・。

「atanのかわり」となると今のところacos, asinしか思い浮かびませんよねぇ、うーん。

キリコ

Re:複素数

#10

投稿記事 by キリコ » 18年前

ほんとうにいろいろとすみませんでした。ある情報によるとatanを使ってよいと人伝えに聞きました。
まだ考えていませんが、もし私より早くできそうだったら教えてくださると助かります。よろしくお願いします。

管理人

Re:複素数

#11

投稿記事 by 管理人 » 18年前

入力した2点から角度さえ求めたらいいんですか?
でしたらatan2ですぐ出来るんじゃないでしょうか。
実現しようとさせていることが違ったらごめんなさい。

管理人

Re:複素数

#12

投稿記事 by 管理人 » 18年前

↑クリックで画像拡大↑

標準関数を使っていいということなんですが、めちゃそれだと簡単じゃないですか?
#include <stdio.h>
#include <math.h>
int main(void){
	double x1=4.0,y1=1.0,x2=5.0,y2=3.0;
	printf("%fラジアン\n",atan2(y2-y1,x2-x1));
    return 0;
}
こういうことじゃなかったですか?(_ _||)

mas

Re:複素数

#13

投稿記事 by mas » 18年前

昨日レスしようと思ってたのに忘れてました。

> 管理人さん
atan2は私も考えてましたけど、どうですかね。
おそらくatan(やacos,asin)を使ってatan2相当の関数を自前で実装するという課題かと予想しているのですが。

> キリコさん
atanを使った方法は上で挙げてるのものを少し改良するだけなので、
もしわからないのなら、どこがわからないのかを教えてください。

管理人

Re:複素数

#14

投稿記事 by 管理人 » 18年前

なるほど、2は使ってはいけないのですね m(_ _)m

http://www.adobe.com/jp/support/flash/t ... l0189.html

キリコ

Re:複素数

#15

投稿記事 by キリコ » 18年前

atan2(y,x)と動作が同じになるか検討するのが、その次の問題でした。masさん、管理人さん、私の説明不足で申し訳ないです。
今は、とりあえず前にmasさんが場合わけした例を使って、作ってみています。

キリコ

Re:複素数

#16

投稿記事 by キリコ » 18年前

{double z,f; z=atan(y/x);
if(z >0) { if(x >0) return (z);
if(x < 0) z=z + pi; return (z); }
if(z < 0) { if(x > 0) f= pi*2; z=z + f; return (z);
if(x < 0) z=z + pi; return (z); }
if(z ==0) { if(x >0) return (0);
if(x < 0) return (pi); }
if(x == 0){ if(y>0) return (pi/2);
if(y<0) return (pi*3)/2; } }
としたのですが、どうも270度のときが二分の3πがでません。この場わけであっているでしょうか?どなたか教えてください。お願いします。
そもそもこのプログラムでいいのでしょうか?

管理人

Re:複素数

#17

投稿記事 by 管理人 » 18年前

ちょっとプログラムがごちゃごちゃしすぎて、どこに括弧がどこで閉じているかわからなくなっていませんか?
きちんと字下げしてみたほうがいいですよ。
間違いを減らすためにも。

前にも聞いたかもしれませんが、どうやって字下げしています?
{
	{
		double z,f; z=atan(y/x); 
		if(z >0) {
			if(x >0) 
				return (z);
            
			if(x < 0)
				z=z + pi; 
			
			return (z);
		}

		if(z < 0) {
			if(x > 0)
				f= pi*2;
			
			z=z + f;
			return (z);

			if(x < 0)
				z=z + pi;
			
			return (z);
		}

		if(z ==0) {
			if(x >0)
				return (0);
			
			if(x < 0)
				return (pi); 
		}

		if(x == 0){ 
			if(y>0) 
				return (pi/2);

			if(y<0) 
				return (pi*3)/2; 
		} 
	} 
	return 0;
}
このように綺麗に書いて対応を確認してみてください。

indent

Re:複素数

#18

投稿記事 by indent » 18年前

インデントは、gnu indent などを使うと、楽にチェック出来ますよ。
ただ、スタイルはいくつかのパタンに制限されるけど。

キリコ

Re:複素数

#19

投稿記事 by キリコ » 18年前

if(y<0)
return (pi*3)/2;
のところだと思うのですが・・・πは定義しているのでいいと思います。x=0でy<0が270度にちゃんと対応しているとおもうのですが・・・。なぜ3π/2が出ないのか 

<管理人さん
< このように綺麗に書いて対応を確認してみてください。
おっしゃるとおり見にくいですね。今度から気をつけたいと思います。

<indent
<gnu indent
どう使うのかわかりませんが、がんばってみます。ありがとうございます。

mas

Re:複素数

#20

投稿記事 by mas » 18年前

x == 0 のときはy/xを計算してしまうとまずいので、atan(y/x)の前に条件分岐させましょう。
if(z < 0) のときの一つ目のreturn以降は実行されません。

キリコ

Re:複素数

#21

投稿記事 by キリコ » 18年前

masさん返信ありがとうございます。
<atan(y/x)の前に条件分岐させましょう。
なるほど。ありがとうございます。

<if(z < 0) のときの一つ目のreturn以降は実行されません。
どうすればよいのでしょうか?

管理人

Re:複素数

#22

投稿記事 by 管理人 » 18年前

return を行うと、そこ以降の処理は行われません。

インデントしたプログラムをみて、処理を確認してくださいと言うのは、その部分をみてほしかったのですが、
if文は括弧をつけないとその直後、;、までしか条件の処理が行われないことはご存知ですよね?
条件文による複数の処理を行いたい場合は括弧で囲む必要があります。

キリコ

Re:複素数

#23

投稿記事 by キリコ » 18年前

管理人さんありがとうございます。
<ご存知ですよね?
実は知りませんでした。

つまりif(z < 0) のときのは

if(z < 0) {
if(x > 0){
f= pi*2;

z=z + f;
return (z);
}

if(x < 0){
z=z + pi;

return (z);
}
}


とやって初めの部分は
double z,f;

if(x == 0){
if(y>0)
return (pi/2);

if(y<0)
return (pi*3)/2;
}


         z=atan(y/x);


とやればいいでしょうか?

キリコ

Re:複素数

#24

投稿記事 by キリコ » 18年前

字下げしているのですが、表示すると、上記のようになってしまうみたいなんですが・・・。Windowsだから?

管理人

Re:複素数

#25

投稿記事 by 管理人 » 18年前

ウェブならどこの掲示板でもHPでも半角スペースやタブインデントは省略されてしまうんです。
これはHTMLの仕様なのだと思います。

半角スペースやタブインデントを有効にして表示したければ
<pre>と</pre>で囲んでやってください。

きれいに表示されます。ちなみに<>は半角で入力してください。
今半角で入力してしまうとそれ自体見えないタグになってしまうので全角で書いています。

括弧の対応についてはそれで大丈夫だと思います。

キリコ

Re:複素数

#26

投稿記事 by キリコ » 18年前

管理人さんいろいろとありがとうございます。

管理人

Re:複素数

#27

投稿記事 by 管理人 » 18年前

またお気軽にお聞きくださいませ☆

閉鎖

“C言語何でも質問掲示板” へ戻る