プログラミング論 I

プログラミング論 I
行列の演算
http://www.ns.kogakuin.ac.jp/~ct13140/Prog
FAQ: #defineとは?
• 文字列を定義して,それ以降置換する.
#define MAX 10
void main(){
int i=MAX;
printf("%d\n", i);
}
#define MAX 2*5
void main(){
int i=10/MAX;
printf("%d\n", i);
}
#define MAX (2*5)
void main(){
int i=10/MAX;
printf("%d\n", i);
}
置換
void main(){
int i=10;
printf("%d\n", i);
}
置換
void main(){
int i=10/2*5;
printf("%d\n", i);
}
置換
void main(){
int i=10/(2*5);
printf("%d\n", i);
}
10/2*5は,
25です.
左から順に
計算
D-2
概要
• 行列の演算
– 簡単
D-3
行列
D-4
行列
• m行n列の行列 (m×n行列)
– 通常,行列の添え字は1から始めて
a11~amnと記すがが,
ここでは0から始め a00~am-1 n-1と記す.
a01
a02  a 0n 1 
 a00


a11
a12
 a10

 




a

a
a
m 11
m 1n 1 
 m 10
D-5
行列の和
• m行n列の行列 と m行n列の行列 の和
a01 a02  a 0n 1   b00
b01 b02  b0n 1 
 a00

 

a11
a12
b11
b12
 a10
  b10


 
  




 

a



a
a
b
b
b
m 11
m 1n 1   m 10
m 11
m 1n 1 
 m 10
=
a01  b01
a02  b02 
a 0n 1  b0n 1 
 a00  b00


a11  b11
a12  b12
 a10  b10







a


b
a

b
a

b
m 11 m 11
m 1n 1
m 1n 1 
 m 10 m 10
D-6
行列の積
• l×m行列 と m×n行列 の積は,l×n行列
b01  b0n 1 
 b00

a01 a02  a 0m 1  
 a00

  b10
b11

a
a
a
 10
 
11
12


b
b
21
 
  20



  


a

al 1m 1  

 l 10 a l 11
b
b
m 1n 1 
 m 10
=
 c00 c01  c 0n 1 


 c10 c11

 




c
cl 1n 1 
 l 10
cij 
m 1
 aikbkj
k 0
ただし,0≦i<l , 0≦j<n
c12  a10b02  a11b12  a1m1bm12
D-7
行列の積
• 4×5行列 と 5×4行列 の積は,4×4行列
=
b
b
b
b
 a00 a01 a02 a03 a04   00 01 02 03 

 b
b11 b12 b13 
10
a
a
a
a
a
 10 11 12
13
14  


b
b
b
b
a

20
21
22
23
a21 a22 a23 a24

 20
 b
a
  30 b31 b32 b33 
a
a
a
a
31
32
33
34  
 30

b
b
b
b
 40 41 42 43 
 c00 c01 c02 c 03 


5 1
 c10 c11 c12 c13 
cij 
aikbkj ただし,0≦i<5 , 0≦j<5
c

c
c
c
k 0
 20 21 22 23 
c

 30 c31 c32 c33  c  a b  a b  a b  a b  a b
12
10 02
11 12
12 22
13 32
14 42

D-8
17
18
19
20
21
22
23
24
25
/* sum.c 行列の加算 */
26
#define COL 3
27
#define ROW 2
28
29
#include <stdio.h>
30
31
void print_matrix(double mat[COL][ROW]){
32
int r, c;
33
for(r=0; r<ROW; r++){
34
for(c=0; c<COL; c++){
35
printf("%6.2lf ", mat[r][c]);
36
}
37
printf("¥n");
38
}
39
}
40
41
42
行列の加算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void main(){
double a[ROW][COL], b[ROW][COL];
double s[ROW][COL];
int r, c;
a[0][0]=0;
a[1][0]=3;
b[0][0]=6;
b[1][0]=9;
a[0][1]= 1;
a[1][1]= 4;
b[0][1]= 7;
b[1][1]=10;
a[0][2]=2;
a[1][2]=5;
b[0][2]=8;
b[1][2]=11;
printf("matrix a=\n");
print_matrix(a);
printf("matrix b=\n");
print_matrix(b);
/* begin : sum, s=a+b */
for(r=0; r<ROW; r++){
for(c=0; c<COL; c++){
s[r][c] = a[r][c] + b[r][c];
}
}
/* end : sum, s=a+b */
printf("matrix s=\n");
print_matrix(s);
}
D-9
行列の乗算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
24
30
31
32
33
#define L 2
34
#define M 3
36
#define N 4
37
38
#include <stdio.h>
39
40
void print_matrix
41
(double *mat, int row, int col){
42
int r, c;
43
for(r=0; r<row; r++){
44
for(c=0; c<col; c++){
45
printf("%6.2lf ", *(mat+col*r+c));
46
}
48
printf("¥n");
49
}
50
}
51
/* pro.c 行列の乗算
(LxM 行列)×(MxN 行列) */
void main(){
double a[L][M], b[M][N], p[L][N];
int l, m, n;
a[0][0]= 0; a[0][1]= 1; a[0][2]= 2;
:省略
printf("matrix a=\n");
print_matrix(a, L, M);
printf("matrix b=\n");
print_matrix(b, M, N);
for(l=0; l<L; l++){
for(n=0; n<N; n++){
/* begin : calc p[l][n] */
double sum = 0.0;
for(m=0; m<M; m++){
sum += a[l][m]*b[m][n];
}
p[l][n] = sum;
/* end : calc p[l][n] */
}
}
printf("matrix s=\n");
print_matrix(p, L, N);
}
D-10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
sum.c
D-11
}
a[0][1]= 1;
a[1][1]= 4;
b[0][1]= 7;
b[1][1]=10;
a[0][2]=2;
a[1][2]=5;
b[0][2]=8;
b[1][2]=11;
printf("matrix s=\n");
print_matrix(s);
/* begin : sum, s=a+b */
for(r=0; r<ROW; r++){
for(c=0; c<COL; c++){
s[r][c] = a[r][c] + b[r][c];
}
}
/* end : sum, s=a+b */
printf("matrix a=\n");
print_matrix(a);
printf("matrix b=\n");
print_matrix(b);
a[0][0]=0;
a[1][0]=3;
b[0][0]=6;
b[1][0]=9;
void main(){
double a[ROW][COL], b[ROW][COL];
double s[ROW][COL];
int r, c;
void print_matrix(double mat[COL][ROW]){
int r, c;
for(r=0; r<ROW; r++){
for(c=0; c<COL; c++){
printf("%6.2lf ", mat[r][c]);
}
printf("\n");
}
}
#include <stdio.h>
/* sum.c 行列の加算 */
#define COL 3
#define ROW 2
pro.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
D-12
}
a[0][1]= 1;
a[1][1]= 4;
b[0][1]= 7;
b[1][1]=11;
b[2][1]=15;
a[0][2]= 2;
a[1][2]= 5;
b[0][2]= 8; b[0][3]= 9;
b[1][2]=12; b[1][3]=13;
b[2][2]=16; b[2][3]=17;
printf("matrix s=\n");
print_matrix(p, L, N);
/* begin : product, p=a*b */
for(l=0; l<L; l++){
for(n=0; n<N; n++){
/* begin : calc p[l][n] */
double sum = 0.0;
for(m=0; m<M; m++){
sum += a[l][m]*b[m][n];
}
p[l][n] = sum;
/* end : calc p[l][n] */
}
}
/* end : product, p=a*b */
printf("matrix a=\n");
print_matrix(a, L, M);
printf("matrix b=\n");
print_matrix(b, M, N);
a[0][0]= 0;
a[1][0]= 3;
b[0][0]= 6;
b[1][0]=10;
b[2][0]=14;
void main(){
double a[L][M], b[M][N], p[L][N];
int l, m, n;
void print_matrix(double *mat, int row, int col){
int r, c;
for(r=0; r<row; r++){
for(c=0; c<col; c++){
printf("%6.2lf ", *(mat+col*r+c));
} /* ↑*(mat+col*r+c)でmat[r][c]となる */
printf("\n");
}
}
#include <stdio.h>
#define L 2
#define M 3
#define N 4
/* pro.c 行列の乗算
(LxM 行列)×(MxN 行列) --> (LxN 行列) の計算 */
C言語
D-13
C言語:変数の宣言と利用
• 変数の宣言
“ i ”という名前の整数型変数を宣言.
以後 i を使用可能.
i は,整数を格納(記録)できる箱.
int i;
“ d ”という名前の
double d;
浮動小数点型変数を宣言.
i = 3;
変数 i に整数 3 を代入.
以後, i には 3 が入っている.
d = 5.7;
printf("i=%d, d=%lf\n", i, d);
プログラム
実行結果
i=3, d=5.700000
D-14
C言語:for文による繰り返し
• for文
int i;
for(i=0; i<3; i++){
printf("Hello,World!\n");
}
for(i=0; i<3; i++){
printf("i=%d\n", i);
}
プログラム
実行結果
Hello,World!
Hello,World!
Hello,World!
i=0
i=1
i=2
D-15
C言語:配列の宣言と使用
• 配列
int型が3個の配列.
data[0]~data[2]
が使用可能.
int data[3];
int i;
"0から始めて,3未満"
data[0] = 3;
でfor文を使うと
data[1] = 4;
やりやすい.
data[2] = 5;
for(i=0; i<3; i++){
printf("data[%d]", i);
printf("=%d\n", data[i]);
}
プログラム
data[0]=3
data[1]=4
data[2]=5
実行結果
D-16
C言語:2次元配列
int data[3][2];
int型が2×3=6個の配列.
int i, j;
data[0][0]~data[2][1]
data[0][0] = 3; data[0][1] = 4;
が使用可能.
data[1][0] = 5; data[1][1] = 6;
「長さ2個の配列」が3個.
data[2][0] = 7; data[2][1] = 8;
(長さ3の配列が2個でない)
for(i=0; i<3; i++){
for(j=0; j<2; j++){
data[0][0]=3
printf("data[%d][%d]", i, j);
data[0][1]=4
printf("=%d\n", data[i][j]);
}
data[1][0]=5
}
data[1][1]=6
プログラム
data[2][0]=7
data[2][1]=8
実行結果
D-17
練習 A
• 3行4列の行列を記述せよ.要素は全て3.
• 5行7列の行列 と 7行8列の行列 の積は,
何行何列の行列となるか?
• 下記の行列の乗算の答えを求めよ.
 0 1  3 

   
 2 3  2 
D-18
解答 A
 3 3 3 3

• 
 3 3 3 3
 3 3 3 3


• 5行8列
2
•  
12
 
D-19