Bruce Eckel: Using C++, Osborne McGraw-Hill(1989)のソースコードを使うことにした.しかしながら,C++ は発展途上の言語である からバージョンによる変化も激しく Bruce のテキストは今や古い感じを与える. GNU のgcc は3.0 からISO C++(文献[7]に相当)に準拠したので,gcc でコンパイルできなければならない.しかし,Bruce のソースコードにはVisual C++ v.6 でコンパイル可能であってもLinux のgcc v.3.0以上でエラーになる箇所がある.そこで必要な箇所のみ採用し,C++ のバイブルである
Bjarne Stroustrup: プログラミング言語C++ 第3版,アジソン・ウェスレイ(1998)を参考にして書き換えた.
ベクトルは行列の特殊であるから継承関係にある.Vectorクラスを Matrixクラ
スのサブクラスとして定義するのが数学から見ても素直な考え方である.しかし
内積の定義に問題が生じる.内積は行列の積を使って
で定義される.ここで
は
の転置行列である.しかし転置はC++の演算子でないので,プログラムの中では内積を関数形で
const int VLEN = 3;
vector a, b;
double x;
x = transpose(a)* b
と書かざるをえない.ここで ``*'' は行列の積を表す.内積はしばしば
現れる演算なので,もっと簡潔に表したい.そこでVectorクラスとMatrixクラス
をおのおの独立なクラスとして定義した.行列の四則演算はMatrixクラスの定義
の中で
matrix operator+(const matrix& rval); // matrix addition
matrix operator-(const matrix& rval); // matrix subtraction
matrix operator-(); // unary minus
matrix operator*(const matrix& rval); // matrix multiplication
matrix operator*(const double rval); // scalar multiplication
//引数の値に基づいて新しい値を生成するだけの演算子
matrix operator+(const matrix& a, const matrix& b);
matrix operator-(const matrix& a, const matrix& b);
matrix operator*(const matrix& a, double b);
matrix operator*(double a, const matrix& b);
matrix operator/(const matrix &a, double b);
matrix operator/(double a, const matrix& b);
とプロトタイプ宣言してある.一方ベクトルの四則演算はVectorクラスの中で
// Unary -
const vector operator-(){
vector v;
for(int i=0;i<VLEN;i++) v.element[i] = -element[i];
return v;
}
//Binary operator +,-,*,/
friend const vector operator+(const vector&, const vector&);
friend const vector operator-(const vector&, const vector&);
friend vector operator*(double, const vector&);
friend double operator*(const vector&, const vector&);
friend vector operator*(const matrix&, const vector&);
friend vector operator*(const vector&, double);
friend vector operator/(const vector&, double);
// Binary operator +=, -=, *=, /=
vector& operator+=(const vector& b){
for(int i=0;i<VLEN;i++)element[i] += b.element[i];
return *this;
}
vector& operator-=(const vector& b){
for(int i=0;i<VLEN;i++)element[i] -= b.element[i];
return *this;
}
vector& operator*=(double b){
for(int i=0;i<VLEN;i++)element[i] *= b;
return *this;
}
vector& operator/=(double b){
for(int i=0;i<VLEN;i++)element[i] /= b;
return *this;
}
と定義している.行列
friend double operator*(const matrix& A, const vector& b);
である,これにより,ベクトルの内績と行列の績に同じシンボル''*''が使え,ま
たベクトルと行列の積も A*b と表現できる.
勿論演算子の多重定義を用いることはいいことばかりでなく,一時オブジェクト
の生成と消滅にコストが掛かり,効率を損ねる.今回は処理能力はそれほど要求されな
いと考え,一時オブジェクトは問題にならないと判断した.