以下の手順に従って,プログラミングを行ってみよう.
いずれも計算結果が画面で確認できるようにすること.
まず,実数2つの配列からなるVec型を定義する.
(要素数は後から変更する可能性あり)
const int dim = 2;
typedef double Vec[dim];
以下の手順に従って,ベクトルを操作する各種関数を作成してみよう.
printVec()
関数を作成,main
関数も作成して動作確認を行う.
#include <stdio.h>
const int dim = 2; /* ベクトルの次元(=要素数), dimensionの略 */
typedef double Vec[dim]; /* typedefにより別名を定義.Vecはdouble型がdim個 = dim 次元の配列 */
void printVec(const Vec v)
{
printf("%lf , %lf\n", v[0], v[1]); /* %lfに関しては%fとも記述可能 */
}
int main()
{
Vec v1, v2;
/* 以下の値は一例.いろいろと変化させよ.*/
/* Vec型は,配列のtypedefなので,このような初期化が可能 */
Vec v1 = { 1.0, 3.0}; /* 初期化,初期値代入は初めの宣言でも可能 */
Vec v2 = {-2.0, 1.0}; /* 初期化,初期値代入は初めの宣言でも可能 */
printVec(v1);
printVec(v2);
return 0;
}
Vadd
を作成せよ.作成した関数が正しく動作するか,動作確認すること.Vsub
も作成せよ.
void Vadd(Vec p, const Vec v1, const Vec v2)
/*
* p : 計算結果を入れる.(アドレス参照であることに注意)
* v1,v2 : 計算するベクトル.変更しないので,const 指定
*/
{
p[0] = ...
p[1] = ...
}
int main()
{
Vec v1, v2, v3;
...
Vadd(v3, v1, v2); /* v3 = v1 + v2 の計算 */
print(v3); /* 計算結果の表示 */
return 0;
}
実行例
v1 : 1.000000 , 3.000000
v2 : -2.000000 , 1.000000
和 = -1.000000 , 4.000000
差 = 3.000000 , 2.000000
double Vabs(const Vec v)
およびプログラムを作成しよう.sqrt()
関数を用いる.要ヘッダーファイル:math.h
実行例 v1 : 1.000000 , 3.000000 abs = 3.162278
double inner_product(const Vec v1, const Vec v2)
およびプログラムを作成しよう.
実行例
v1 : 1.000000 , 3.000000
v2 : -2.000000 , 1.000000
内積 = 1.000000
上記,各関数および関数のテストコードは,単一のソースコードに順次まとめて記述すれば良い.
ソースファイル名を 153R000000-05-1.cpp とする.(000000の部分は各自の学生番号)
前問で作成した関数群を利用して,(正規化された)相互相関係数の計算を行ってみよう.
2つのベクトル x,y の相互相関係数は,上記の内積および絶対値を組み合わせて,
R = x・y / (|x||y|)
と表すことができる.
相互相関は,信号の類似度合いを決定したり,画像中から特定のパターンを検索する処理に非常に広く用いられている.
相互相関係数は,2つのベクトルの類似度を表し,完全に一致するときは 1.0,全く異なる(=直交する)ときは 0.0,ベクトルの向きが真逆の場合は -1.0 となるような係数である.
相互相関係数は,幾何的には,2つのベクトルのなす角 θ の余弦 cosθを表す.
相互相関係数=0(即ち,内積=0)となる2ベクトルは,「直交する」という.( cosθ=0 即ち θ=90度であるため)
それでは,実際にベクトルの相互相関係数を計算してみよう.
以下の4本のベクトルの中から任意の2つのベクトルの相互相関係数を計算し,
プログラムを作成せよ.
ここでは簡単のために,全ての組み合わせの相関係数を計算し,表として表示してみよう.
相関関数を計算する関数を double corr(const Vec v1, const Vec v2)
とせよ.
上に示した式の通り,inner_product()
および Vabs()
を用いれば,簡単である.
const int dim = 8;
typedef double Vec[dim];
int main(void)
{
Vec v1 = { 1, 2, 4, 5, 4, 1, -1, -2 };
Vec v2 = { 3, 3, 4, 6, 3, 2, 1, 1 };
Vec v3 = {-1, 2, 0, 2, -2, -1, 3, 1 };
Vec v4 = { 2, 1, 3, -9, 2, 8, 2, 8 };
....
return 0;
}
実行例.相関値のテーブルを全て計算. この実行例では,printf
関数の書式指定文字列に,%+2.2lf
を用いている.(符号付,小数点第2位まで表示) | v1 v2 v3 v4 ---+------------------------- v1 | +1.00 +0.87 -0.02 -0.25 v2 | +0.87 +1.00 +0.24 -0.01 v3 | -0.02 +0.24 +1.00 -0.21 v4 | -0.25 -0.01 -0.21 +1.00
図1:ベクトル v1-v4までの視覚的表示.
ソースコードを提出すること.ファイル名は,153R000000-05-2.cpp とする.