メッセージパッシングと問題2.75
メッセージパッシングだとこんなにコンパクトになるのかー。
ただ、関数で複素数を表現している分、基礎の部分をしっかり作っていないと、
この上にさらにモノを載せるのは、C++では結構大変かもしれない。
メッセージパッシングは3章で頻繁に使うだけに、
自前のListのコードを見なおしておかないとなあ。
実部、虚部といった内部パラメターをもったデータの表現というと、
配列なり構造体なりクラスなり作って、そのメンバにデータを入れるというのしか、
今まで考えたことがなかった。
内部パラメターはクロージャのキャプチャで取得される。
さらっと短く書かれているが、実は全然新しい考え方だ。
Schemeで最初勉強していて、3章で特に回路シミュレータとか始まった途端に、
何をやっているのかがわからなくなった。
感じたのは、初めて学ぶSchemeというかlispに不慣れであることと、
根本にあるらしい発想の飛躍とが、自分の中で分離できていないこと。
そこで言語自体は慣れているC++でやってみるかと始めた
(C++11の勉強もしたいというのもある)わけだが、
どうも重要なポイントはこの、関数とクロージャによるデータ表現にあるか?
問題2.76はコードを書くわけでないのでパス
----
typedef
double Field;
typedef
function<List(string)> Complex;
const
List applyGeneric
(const
string operation, const Complex& argument)
{return(argument(operation));}
template<typename
XType,typename YType>
const
Complex makeFromRealImag(const XType& x,const YType& y)
{
const Complex dispatch
=[x,y](const string operation){
const List xList(makeLeaf(x));
const List yList(makeLeaf(y));
if(operation=="real-part"){
return(xList);}
else
if(operation=="imag-part"){
return(yList);}
else
if(operation=="magnitude"){
return(makeLeaf
(squareRoot
(value<Field>(square(xList)+square(yList)))));
}
else if(operation=="angle"){
return(makeLeaf
(arcTangent2(value<Field>(yList),
value<Field>(xList))));
}
cerr<<"No method for these
types --- make-from-real-imag"
<<listString(makeList(operation,xList,yList))<<endl;
exit(1);
return(makeLeaf(0.0));
};
return(dispatch);
}
template<typename
RType,typename AType>
const
Complex makeFromMagAng(const RType& r,const AType& a)
{
const Complex dispatch
=[r,a](const string operation){
const List rList(makeLeaf(r));
const List aList(makeLeaf(a));
if(operation=="real-part"){
return(makeLeaf(value<Field>(rList)*
cosine(value<Field>(aList))));
}
else
if(operation=="imag-part"){
return(makeLeaf(value<Field>(rList)*
sine(value<Field>(aList))));
}
else
if(operation=="magnitude"){return(rList);}
else
if(operation=="angle"){return(aList);}
cerr<<"No method for these
types --- make-from-mag-ang"
<<listString(makeList(operation,rList,aList))<<endl;
exit(1);
return(makeLeaf(0.0));
};
return(dispatch);
}
//---------abstraction
barrier---------
const
List realPart(const Complex& z)
{return(applyGeneric("real-part",z));}
const
List imagPart(const Complex& z)
{return(applyGeneric("imag-part",z));}
const
List magnitude(const Complex& z)
{return(applyGeneric("magnitude",z));}
const
List angle(const Complex& z)
{return(applyGeneric("angle",z));}
//---------abstraction
barrier---------
int
main(int argc, char** argv)
{
const Complex c1(makeFromRealImag(1.0,2.0));
cout<<"c1 (rectangular) = "
<<listString(makeList(realPart(c1),imagPart(c1)))<<endl;
cout<<"(magnitude c1) =
"<<listString(magnitude(c1))<<endl;
cout<<endl<<"Excersize2.75:"<<endl;
const Complex c2(makeFromMagAng(1.0,M_PI/4.0));
cout<<"c2 (polar) = "
<<listString(makeList(magnitude(c2),angle(c2)))<<endl;
cout<<"(real-part c2) =
"<<listString(realPart(c2))<<endl;
return(0);
}
----
出力
----
c1
(rectangular) = (1 2)
(magnitude
c1) = 2.23606797749979
Excersize2.75:
c2
(polar) = (1 0.7853981633974483)
(real-part
c2) = 0.7071067811865476
0 件のコメント :
コメントを投稿