行列計算プログラム



/* matrix.h*/


#include <stdio.h>
#include <stdlib.h>

#include <math.h>



#define RANDOMIZE()	srand(time(NULL))

#define RANDOM(x)	(rand()%(x))		// 0..x-1 間の整数乱数

#define REALRANDOM(x)	(((x)*rand())/RAND_MAX)	// 0..x 間の実数乱数



/* 行列の最大サイズを設定 */

#define MAXSIZE 128


/* 実行対象の行列サイズを設定
 *    (デフォルト値は 3, 主プログラムで指定せよ ) */

int SIZE=3; 



/* MATRIX, VECTOR, ROWVECTOR という型を定義 */

typedef struct { double ent[MAXSIZE]; } VECTOR;

typedef struct { double ent[MAXSIZE]; } ROWVECTOR;

typedef struct { double ent[MAXSIZE][MAXSIZE]; } MATRIX;



/********************************************************

 *

 * VECTOR v;

 * と宣言すると v.ent[i] が列ベクトル v の 第i成分を表す。 

 *

 * ROWVECTOR v;

 * と宣言すると v.ent[i] が行ベクトル v の 第i成分を表す。 

 *

 * MATRIX a;
 * と宣言すると a.ent[i][j] が行列 a の (i,j)-成分を表す。 

 *

 * *********************************************************/



/* 列ベクトルを表示する関数 */

void vecprint(VECTOR v);



/* 行ベクトルを表示する関数 */

void rowvecprint(ROWVECTOR v);



/* 行列を表示する関数 */

void matprint(MATRIX a);



/* 列ベクトル v のスカラー倍 w = c v を返す関数 */

VECTOR vecscmul(double c, VECTOR v);



/* 行ベクトル v のスカラー倍 w = c v を返す関数 */

ROWVECTOR rowvecscmul(double c, ROWVECTOR v);



/* 行列 A のスカラー倍 B = c A を返す関数 */

MATRIX matscmul(double c, MATRIX a);



/* ふたつの列ベクトル u, v の和 w = u + v を返す関数 */

VECTOR vecadd(VECTOR u, VECTOR v);



/* ふたつの列ベクトル u, v の差 w = u - v を返す関数 */

VECTOR vecsub(VECTOR u, VECTOR v);



/* ふたつの行ベクトル u, v の和 w = u + v を返す関数 */

ROWVECTOR rowvecadd(ROWVECTOR u, ROWVECTOR v);



/* ふたつの行ベクトル u, v の差 w = u - v を返す関数 */

ROWVECTOR rowvecsub(ROWVECTOR u, ROWVECTOR v);



/* ふたつの行列 A, B の和 C = A + B を返す関数 */

MATRIX matadd(MATRIX a, MATRIX b);

/* ふたつの行列 A, B の差 C = A - B を返す関数 */

MATRIX matsub(MATRIX a, MATRIX b);



/* 行ベクトル u と列ベクトルv の積 w = u v を返す関数 */

double rowvecvecmul(ROWVECTOR u, VECTOR v);



/* 列ベクトル u と行ベクトル v の積 A = u v を返す関数 */

MATRIX vecrowvecmul(VECTOR u, ROWVECTOR v);



/* 行列 A と列ベクトル v の積 w = A v を返す関数 */

VECTOR matvecmul(MATRIX a, VECTOR v);



/* 行ベクトル v と行列 A の積 w = v A を返す関数 */

ROWVECTOR rowvecmatmul(ROWVECTOR b, MATRIX a);



/* 行列 A, B の積 C = A B を返す関数 */

MATRIX matmul(MATRIX a, MATRIX b);



/* ゼロベクトル(列ベクトル)を返す関数 */

VECTOR zerovec();



/* ゼロベクトル(行ベクトル)を返す関数 */

ROWVECTOR zerorowvec();



/* ゼロ行列を返す関数 */

MATRIX zeromat();



/* 単位行列を返す関数 */

MATRIX unitmat();



/* 第 i,j 座標の角度 x の回転を表す行列を返す関数 */

MATRIX rotmat(int i, int j, double x);



/* 列ベクトル v の転置ベクトルを返す関数 */

ROWVECTOR transvec(VECTOR v);



/* 行ベクトル v の転置ベクトルを返す関数 */

VECTOR transrowvec(ROWVECTOR v);



/* 行列 A の転置行列を返す関数 */

MATRIX transmat(MATRIX a);



/* ふたつのベクトル u, v の標準内積を返す関数 */

double innerprod(VECTOR u, VECTOR v);



/* 行ベクトル v の長さ(ユークリッドノルム)を返す関数 */

double vecnorm(VECTOR v);



/* 列ベクトル v の長さ(ユークリッドノルム)を返す関数 */

double rowvecnorm(ROWVECTOR v);



/* ランダムな列ベクトルを返す関数(成分の最大絶対値 < x) */

VECTOR randomvec(double x);



/* ランダムな整数成分列ベクトルを返す関数(成分の最大絶対値 < x) */

VECTOR randomintvec(int x);



/* ランダムな行ベクトルを返す関数(成分の最大絶対値 < x) */

ROWVECTOR randomrowvec(double x);



/* ランダムな整数成分行ベクトルを返す関数(成分の最大絶対値 < x) */

ROWVECTOR randomintrowvec(int x);



/* ランダムな行列を返す関数(成分の最大絶対値 < x)*/

MATRIX randommat(double x);



/* ランダムな整数成分行列を返す関数(成分の最大絶対値 < x)*/

MATRIX randomintmat(int x);



/********** 以下関数定義 **********/


void vecprint(VECTOR v)

{

	int i;

	for(i=0;i<SIZE;i++) printf("%12.7lf\n",v.ent[i]);

}



void rowvecprint(ROWVECTOR v)

{

	int i;

	for(i=0;i<SIZE;i++) printf("%12.7lf  ",v.ent[i]);

	printf("\n");

}



void matprint(MATRIX a)

{

	int i,j;

	for(i=0;i<SIZE;i++){

		for(j=0;j<SIZE;j++) printf("%12.7lf",a.ent[i][j]);

		printf("\n");

	}

}



VECTOR vecscmul(double c, VECTOR v)

{

	VECTOR w;

	int i;

	for(i=0;i<SIZE;i++) w.ent[i]=c*v.ent[i];

	return w;

}



ROWVECTOR rowvecscmul(double c, ROWVECTOR v)

{

	ROWVECTOR w;

	int i;

	for(i=0;i<SIZE;i++) w.ent[i]=c*v.ent[i];

	return w;

}



MATRIX matscmul(double c, MATRIX a)

{

	MATRIX b;

	int i,j;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++)

			b.ent[i][j]=c*a.ent[i][j];

	return b;

}



VECTOR vecadd(VECTOR u, VECTOR v)

{

	VECTOR w;

	int i;

	for(i=0;i<SIZE;i++) w.ent[i]=u.ent[i]+v.ent[i];

	return w;

}



VECTOR vecsub(VECTOR u, VECTOR v)

{

	VECTOR w;

	int i;

	for(i=0;i<SIZE;i++) w.ent[i]=u.ent[i]-v.ent[i];

	return w;

}



ROWVECTOR rowvecadd(ROWVECTOR u, ROWVECTOR v)

{

	ROWVECTOR w;

	int i;

	for(i=0;i<SIZE;i++) w.ent[i]=u.ent[i]+v.ent[i];

	return w;

}



ROWVECTOR rowvecsub(ROWVECTOR u, ROWVECTOR v)

{

	ROWVECTOR w;

	int i;

	for(i=0;i<SIZE;i++) w.ent[i]=u.ent[i]-v.ent[i];

	return w;

}



MATRIX matadd(MATRIX a, MATRIX b)

{

	MATRIX c;

	int i,j;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++)

			c.ent[i][j]=a.ent[i][j]+b.ent[i][j];

	return c;

}



MATRIX matsub(MATRIX a, MATRIX b)

{

	MATRIX c;

	int i,j;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++)

			c.ent[i][j]=a.ent[i][j]-b.ent[i][j];

	return c;

}



double rowvecvecmul(ROWVECTOR u, VECTOR v)
{

	double x=0.0;

	int k;

	for(k=0;k<SIZE;k++) x+=u.ent[k]*v.ent[k];

	return x;

}



MATRIX vecrowvecmul(VECTOR u, ROWVECTOR v)

{

	MATRIX a;

	int i,j;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++)

			a.ent[i][j]=u.ent[i]*v.ent[j];

	return a;

}

VECTOR matvecmul(MATRIX a, VECTOR v)

{

	VECTOR w;

	int i,k;

	double x;

	for(i=0;i<SIZE;i++){

		x=0.0;

		for(k=0;k<SIZE;k++) x+=a.ent[i][k]*v.ent[k];

		w.ent[i]=x;

	}

	return w;

}



ROWVECTOR rowmatvecmul(ROWVECTOR v, MATRIX a)

{

	ROWVECTOR w;

	int j,k;

	double x;

	for(j=0;j<SIZE;j++){

		x=0.0;

		for(k=0;k<SIZE;k++) x+=v.ent[k]*a.ent[k][j];

		w.ent[j]=x;

	}

	return w;

}



MATRIX matmul(MATRIX a, MATRIX b)

{

	MATRIX c;

	int i,j,k;

	double x;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++){

			x=0.0;

			for(k=0;k<SIZE;k++) x+=a.ent[i][k]*b.ent[k][j];

			c.ent[i][j]=x;

		}

	return c;

}



VECTOR zerovec()

{

	VECTOR v;

	int i;

	for(i=0;i<SIZE;i++) v.ent[i]=0;

	return v;

}



ROWVECTOR zerorowvec()

{

	ROWVECTOR v;

	int i;

	for(i=0;i<SIZE;i++) v.ent[i]=0;

	return v;

}



MATRIX zeromat()

{

	MATRIX a;

	int i,j;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++)

			a.ent[i][j]=0.0;

	return a;

}



MATRIX unitmat()

{

	int i;

	MATRIX a=zeromat();

	for(i=0;i<SIZE;i++) a.ent[i][i]=1.0;

	return a;

}



MATRIX rotmat(int i, int j, double x)

{

	MATRIX a=unitmat();

	a.ent[i][i]=cos(x);

	a.ent[i][j]=-sin(x);

	a.ent[j][i]=sin(x);

	a.ent[j][j]=cos(x);

	return a;

}



ROWVECTOR transvec(VECTOR v)

{

	ROWVECTOR w;

	int k;

	for(k=0;k<SIZE;k++) w.ent[k]=v.ent[k];

	return w;

}



VECTOR transrowvec(ROWVECTOR v)

{

	VECTOR w;

	int k;

	for(k=0;k<SIZE;k++) w.ent[k]=v.ent[k];

	return w;

}



MATRIX transmat(MATRIX a)
{

	int i,j;

	MATRIX b;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++)

			b.ent[j][i]=a.ent[i][j];

	return b;

}



double innerprod(VECTOR u, VECTOR v)

{

	double x=0.0;

	int k;

	for(k=0;k<SIZE;k++) x+=u.ent[k]*v.ent[k];

	return x;

}



double vecnorm(VECTOR v)

{

	return sqrt(innerprod(v,v));

}



double rowvecnorm(ROWVECTOR v)

{

	return vecnorm(transrowvec(v));

}



VECTOR randomvec(double x)

{

	VECTOR v;

	int i;

	for(i=0;i<SIZE;i++) v.ent[i]=2*REALRANDOM(x)-x;

	return v;

}

VECTOR randomintvec(int x)

{

	VECTOR v;

	int i;

	for(i=0;i<SIZE;i++) v.ent[i]=RANDOM(2*x-1)-x+1;

	return v;

}



ROWVECTOR randomrowvec(double x)

{

	ROWVECTOR v;

	int i;

	for(i=0;i<SIZE;i++) v.ent[i]=2*REALRANDOM(x)-x;

	return v;

}



ROWVECTOR randomintrowvec(int x)

{

	ROWVECTOR v;

	int i;

	for(i=0;i<SIZE;i++) v.ent[i]=RANDOM(2*x-1)-x+1;

	return v;

}



MATRIX randommat(double x)

{

	MATRIX a;

	int i,j;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++)

			a.ent[i][j]=2*REALRANDOM(x)-x;

	return a;

}



MATRIX randomintmat(int x)

{

	MATRIX a;

	int i,j;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++)

			a.ent[i][j]=RANDOM(2*x-1)-x+1;

	return a;

}



MATRIX array2mat(int a[SIZE][SIZE])

{

	int i,j;

	MATRIX b;

	for(i=0;i<SIZE;i++)

		for(j=0;j<SIZE;j++)

			b.ent[i][j]=a[i][j];

	return b;

}