行列とベクトルの積

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
あい

行列とベクトルの積

#1

投稿記事 by あい » 3年前

ベクトルの積を求めたいんですが、うまくいきません
Void MatProから下を教えてほしいです
形はなるべく変えずにお願いします。


#include<stdio.h>

void MatPro(double(*Mat)[3], double *Vec, double *ReVec);
double innerp(int n, double *a, double *b);

int main(void)
{
double Mat[3][3] = { { 12, 34, 82 }, { 43, 80, -54 }, { 56, 31, 78 } };
double Vec[3] = { 2, 64, 32 }, ReVec[3];
int i;

MatPro(Mat, Vec, ReVec);

printf("output=Mat[3][3](input)*Vec[3](input)\n");

for (i = 0; i < 3; i++)
printf("|%7.2f| |%6.2f %6.2f %6.2f| |%6.2f|\n", *(ReVec + i), *(*(Mat + i)), *(*(Mat + i) + 1), *(*(Mat + i) + 2), *(Vec + i));

return 0;
}
void MatPro(double(*Mat)[3], double *Vec, double *ReVec)
{
int i,j;

for (i = 0; i < 3; i++){
for (j = 0; j < 0; j++){
Mat[j] * Vec;
}

}
}
double innerp(int n, double *a, double *b)
{
double ip = 0;
int i;

for (i = 0; i < n; i++)
ip += *(a + i)**(b + i);

return ip;

}

アバター
みけCAT
記事: 6398
登録日時: 10年前
住所: 千葉県
連絡を取る:

Re: 行列とベクトルの積

#2

投稿記事 by みけCAT » 3年前

質問者からの返事がなく、あまりいいトピックではありませんが、参考として過去ログに同様の問題に関する質問があります。
ポインタ • C言語交流フォーラム ~ mixC++ ~
ベクトルの積 • C言語交流フォーラム ~ mixC++ ~
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Math

Re: 行列とベクトルの積

#3

投稿記事 by Math » 3年前

コード:

#include<stdio.h>
void MatPro(double(*Mat)[3], double* Vec, double* ReVec);
double innerp(int n, double* a, double* b);

int main(void)
{
	double Mat[3][3] = { { 12, 34, 82 },{ 43, 80, -54 },{ 56, 31, 78 } };
	double Vec[3] = { 2, 64, 32 }, ReVec[3];
	int i;

	//MatPro(Mat, Vec, ReVec);
	MatPro(Mat, Vec, ReVec);

	printf("output=Mat[3][3](input)*Vec[3](input)\n");

	for (i = 0; i < 3; i++)
		printf("|%7.2f| |%6.2f %6.2f %6.2f| |%6.2f|\n", *(ReVec + i), *(*(Mat + i)), *(*(Mat + i) + 1), *(*(Mat + i) + 2), *(Vec + i));

	return 0;
}
void MatPro(double(*Mat)[3], double *Vec, double *ReVec)
{
	int i;//, j;

	for (i = 0; i < 3; i++) {
		//for (j = 0; j < 0; j++) {
		//Mat[i][j] * Vec[i];
		//}

		*(ReVec + i) = innerp(3, (Mat)[i], Vec);
	}
}
double innerp(int n, double *a, double *b)//d:n次元:a行Vector:b列Vector
{
	double ip = 0;//内積(inner product)
	int i;

	for (i = 0; i < n; i++)
		ip += *(a + i) * *(b + i);

	return ip;//内積(inner product)を返す

}

コード:

1>------ すべてのリビルド開始: プロジェクト:ConsoleApplication0601, 構成: Debug Win32 ------
1>c1.c
1>ConsoleApplication0601.vcxproj -> D:\z17\c\ConsoleApplication0601\Debug\ConsoleApplication0601.exe
1>ConsoleApplication0601.vcxproj -> D:\z17\c\ConsoleApplication0601\Debug\ConsoleApplication0601.pdb (Partial PDB)
========== すべてリビルド: 1 正常終了、0 失敗、0 スキップ ==========

コード:

output=Mat[3][3](input)*Vec[3](input)
|4824.00| | 12.00  34.00  82.00| |  2.00|
|3478.00| | 43.00  80.00 -54.00| | 64.00|
|4592.00| | 56.00  31.00  78.00| | 32.00|
続行するには何かキーを押してください . . .
VS2017を使用してます。
EXCELで検証
画像
注:ポインターと2次元行列は複雑なので疑問点があったら質問をしてくださいね。(^^;
[/size]

MathM

Re: 行列とベクトルの積

#4

投稿記事 by MathM » 3年前

書き方が雑だったので清書して補足説明をします。

全コード c1.c 

コード:

#include<stdio.h>
void MatPro(double(*Mat)[3], double* Vec, double* ReVec);
double innerp(int n, double* a, double* b);

int main(void)
{
	double Mat[3][3] = { { 12, 34, 82 },{ 43, 80, -54 },{ 56, 31, 78 } };
	double Vec[3] = { 2, 64, 32 }, ReVec[3];
	int i;

	MatPro(Mat, Vec, ReVec);

	printf("output=Mat[3][3](input)*Vec[3](input)\n");

	for (i = 0; i < 3; i++)
		printf("|%7.2f| |%6.2f %6.2f %6.2f| |%6.2f|\n", *(ReVec + i), *(*(Mat + i)), *(*(Mat + i) + 1), *(*(Mat + i) + 2), *(Vec + i));

	return 0;
}
void MatPro(double(*Mat)[3], double *Vec, double *ReVec)
{
	int i;

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

		*(ReVec + i) = innerp(3, (Mat)[i], Vec);
	}
}
double innerp(int n, double *a, double *b)//nは次元:*a は行Vector:*b は列Vector
{
	double ip = 0;//内積(inner product)
	int i;

	for (i = 0; i < n; i++)
		ip += *(a + i) * *(b + i);

	return ip;//内積(inner product)を返す

}
バッチファイル c.bat

コード:

rem コンパイル後リンク
cl /TC c1.c
rem 実行結果
c1.exe
VS2017 コマンドプロンプトで実行

コード:

D:\z17c\c\0601>c

D:\z17c\c\0601>rem コンパイル後リンク

D:\z17c\c\0601>cl /TC c1.c
Microsoft(R) C/C++ Optimizing Compiler Version 19.10.25019 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

c1.c
Microsoft (R) Incremental Linker Version 14.10.25019.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:c1.exe
c1.obj

D:\z17c\c\0601>rem 実行結果

D:\z17c\c\0601>c1.exe
output=Mat[3][3](input)*Vec[3](input)
|4824.00| | 12.00  34.00  82.00| |  2.00|
|3478.00| | 43.00  80.00 -54.00| | 64.00|
|4592.00| | 56.00  31.00  78.00| | 32.00|

D:\z17c\c\0601>
注:ポインターと2次元配列は複雑なので以下の通り補足説明をします。
このコードがC言語の正しい書き方なのですが人間にはわかりずらいので”配列”風に書き直して見ることができます。
【C言語では添字演算子[]は配列とは無関係です。C言語には多次元配列は存在しません。多次元配列のように見えるものは「配列の配列」です。この方が使いやすいこともあります。】
シンタックスシュガーを使って書き換えてみます。
以下参照:
http://dixq.net/forum/viewtopic.php?f=3&t=19137
[/size]

Math

Re: 行列とベクトルの積

#5

投稿記事 by Math » 3年前

シンタックスシュガーを使って書き換えたコードです。

コード:

#include<stdio.h>
void MatPro(double Mat[3][3],  Vec[3], ReVec[3]);
double innerp(int n, double *a, double *b);

int main(void)
{
	double Mat[3][3] = { { 12, 34, 82 },{ 43, 80, -54 },{ 56, 31, 78 } };
	double Vec[3] = { 2, 64, 32 }, ReVec[3];
	int i;

	MatPro(Mat[3][3], Vec[3], ReVec[3]);

	printf("output=Mat[3][3](input)*Vec[3](input)\n");

	for (i = 0; i < 3; i++)
		printf("|%7.2f| |%6.2f %6.2f %6.2f| |%6.2f|\n", ReVec[i], Mat[i][0], Mat[i + 1][1],Mat[i + 2][2], Vec[i];

	return 0;
}
void MatPro(double Mat[3][3], Vec[3], ReVec[3]);
{
	int i;

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

		ReVec[i] = innerp(3, (Mat)[i], Vec);
	}
}
double innerp(int n, double *a, double *b)//nは次元:*a は行Vector:*b は列Vector
{
	double ip = 0;//内積(inner product)
	int i;

	for (i = 0; i < n; i++)
		ip += *(a + i) * *(b + i);

	return ip;//内積(inner product)を返す

}
VS2017で実行

コード:

output=Mat[3][3](input)*Vec[3](input)
|4824.00| | 12.00  34.00  82.00| |  2.00|
|3478.00| | 43.00  80.00 -54.00| | 64.00|
|4592.00| | 56.00  31.00  78.00| | 32.00|
続行するには何かキーを押してください . . .

Math

Re: 行列とベクトルの積

#6

投稿記事 by Math » 3年前

// これでも良い

コード:

#include<stdio.h>
void MatPro(double Mat[3][3],  Vec[3], ReVec[3]);
double innerp(int n, double *a, double *b);

int main(void)
{
	double Mat[3][3] = { { 12, 34, 82 },{ 43, 80, -54 },{ 56, 31, 78 } };
	double Vec[3] = { 2, 64, 32 }, ReVec[3];
	int i;

	MatPro(Mat[3][3], Vec[3], ReVec[3]);

	printf("output=Mat[3][3](input)*Vec[3](input)\n");

	for (i = 0; i < 3; i++)
		printf("|%7.2f| |%6.2f %6.2f %6.2f| |%6.2f|\n", ReVec[i], Mat[i][0], Mat[i + 1][1],Mat[i + 2][2], Vec[i];

	return 0;
}
void MatPro(double Mat[3][3], Vec[3], ReVec[3]);
{
	int i;

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

		ReVec[i] = innerp(3, Mat[i][0], Vec);// これでも良い
	}
}
double innerp(int n, double *a, double *b)//nは次元:*a は行Vector:*b は列Vector
{
	double ip = 0;//内積(inner product)
	int i;

	for (i = 0; i < n; i++)
		ip += *(a + i) * *(b + i);

	return ip;//内積(inner product)を返す

}

box
記事: 1760
登録日時: 10年前

Re: 行列とベクトルの積

#7

投稿記事 by box » 3年前

あい さんが書きました:

コード:

			 Mat[i][j] * Vec[i];
何か計算はしてますけど、それを「どこにも代入していない」ので、そりゃダメですよね。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

Math

Re: 行列とベクトルの積

#8

投稿記事 by Math » 3年前

「これでも良い」です。(^^;

コード:

#include<stdio.h>
void MatPro(double Mat[3][3],  Vec[3], ReVec[3]);
double innerp(int n, double *a, double *b);

int main(void)
{
	double Mat[3][3] = { { 12, 34, 82 },{ 43, 80, -54 },{ 56, 31, 78 } };
	double Vec[3] = { 2, 64, 32 }, ReVec[3];
	int i;

	MatPro(Mat[3][3], Vec[3], ReVec[3]);

	printf("output=Mat[3][3](input)*Vec[3](input)\n");

	for (i = 0; i < 3; i++)
		printf("|%7.2f| |%6.2f %6.2f %6.2f| |%6.2f|\n", ReVec[i], Mat[i][0], Mat[i + 1][1],Mat[i + 2][2], Vec[i];

	return 0;
}
void MatPro(double Mat[3][3], Vec[3], ReVec[3]);
{
	int i;

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

		ReVec[i] = innerp(3, Mat[i][0], Vec[3]);// 「これでも良い」
	}
}
double innerp(int n, double *a, double *b)//nは次元:*a は行Vector:*b は列Vector
{
	double ip = 0;//内積(inner product)
	int i;

	for (i = 0; i < n; i++)
		ip += *(a + i) * *(b + i);

	return ip;//内積(inner product)を返す

}

かずま

Re: 行列とベクトルの積

#9

投稿記事 by かずま » 3年前

Math さんが書きました:シンタックスシュガーを使って書き換えたコードです。
Math さんが書きました:// これでも良い
Math さんが書きました:「これでも良い」です。(^^;
Mathさん、No.5、No.6、No.8のコードはすべてコンパイルエラーになります。
これ以上、質問者を惑わすような投稿はやめてください。

Math

Re: 行列とベクトルの積

#10

投稿記事 by Math » 3年前

あ 寝ぼけて 間違えています。後で訂正します・ごめん。!

Math

Re: 行列とベクトルの積

#11

投稿記事 by Math » 3年前

>Mathさん、No.5、No.6、No.8のコードはすべてコンパイルエラーになります。
>これ以上、質問者を惑わすような投稿はやめてください。
コマンドプロンプトのエディターにVS2017のIDEを使っていてひどい 勘違いしていました。関数に定義からエラーのはずなのにすみませんでした。No.5、No.6、No.8は初歩的におお間違いです。
------------------------------------------------------------------------------
「訂正版」シンタックスシュガーを使って書き換えたコードです。

コード:

#include<stdio.h>
void MatPro(double Mat[3][3], double Vec[3], double ReVec[3]);
double innerp(int n, double* a, double* b);

int main(void)
{
	double Mat[3][3] = { { 12, 34, 82 },{ 43, 80, -54 },{ 56, 31, 78 } };
	double Vec[3] = { 2, 64, 32 }, ReVec[3];
	int i;

	MatPro(Mat, Vec, ReVec);

	printf("output=Mat[3][3](input)*Vec[3](input)\n");

	for (i = 0; i < 3; i++)
		printf("|%7.2f| |%6.2f %6.2f %6.2f| |%6.2f|\n", ReVec[i], Mat[i][0], Mat[i][1], Mat[i][2], Vec[i]);

	return 0;
}
void MatPro(double Mat[3][3], double Vec[3], double ReVec[3])
{
	int i;

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

		ReVec[i] = innerp(3, Mat[i], Vec);
	}
}
double innerp(int n, double *a, double *b)//nは次元:*a は行Vector:*b は列Vector
{
	double ip = 0;//内積(inner product)
	int i;

	for (i = 0; i < n; i++)
		ip += *(a + i) * *(b + i);

	return ip;//内積(inner product)を返す

}

コード:

1>------ すべてのリビルド開始: プロジェクト:ConsoleApplication0601, 構成: Debug Win32 ------
1>c1.c
1>ConsoleApplication0601.vcxproj -> D:\z17\c\ConsoleApplication0601\Debug\ConsoleApplication0601.exe
1>ConsoleApplication0601.vcxproj -> D:\z17\c\ConsoleApplication0601\Debug\ConsoleApplication0601.pdb (Partial PDB)
========== すべてリビルド: 1 正常終了、0 失敗、0 スキップ ==========

コード:

output=Mat[3][3](input)*Vec[3](input)
|4824.00| | 12.00  34.00  82.00| |  2.00|
|3478.00| | 43.00  80.00 -54.00| | 64.00|
|4592.00| | 56.00  31.00  78.00| | 32.00|
続行するには何かキーを押してください . . .

Math

Re: 行列とベクトルの積

#12

投稿記事 by Math » 3年前

シンタックスシュガーであるためこれも正しいプログラムです!

コード:

#include<stdio.h>
void MatPro(double Mat[3][3], double Vec[3], double ReVec[3]);
double innerp(int n, double* a, double* b);

int main(void)
{
	double Mat[3][3] = { { 12, 34, 82 },{ 43, 80, -54 },{ 56, 31, 78 } };
	double Vec[3] = { 2, 64, 32 }, ReVec[3];
	int i;

	MatPro(Mat, Vec, ReVec);

	printf("output=Mat[3][3](input)*Vec[3](input)\n");

	for (i = 0; i < 3; i++)
		printf("|%7.2f| |%6.2f %6.2f %6.2f| |%6.2f|\n", i[ReVec], i[Mat][0], i[Mat][1], i[Mat][2], i[Vec]);

	return 0;
}
void MatPro(double Mat[3][3], double Vec[3], double ReVec[3])
{
	int i;

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

		i[ReVec] = innerp(3, i[Mat], Vec);
	}
}
double innerp(int n, double *a, double *b)//nは次元:*a は行Vector:*b は列Vector
{
	double ip = 0;//内積(inner product)
	int i;

	for (i = 0; i < n; i++)
		ip += *(a + i) * *(b + i);

	return ip;//内積(inner product)を返す

}

コード:

1>------ すべてのリビルド開始: プロジェクト:ConsoleApplication2, 構成: Debug Win32 ------
1>c1.c
1>ConsoleApplication2.vcxproj -> D:\z17\c\ConsoleApplication2\Debug\ConsoleApplication2.exe
1>ConsoleApplication2.vcxproj -> D:\z17\c\ConsoleApplication2\Debug\ConsoleApplication2.pdb (Partial PDB)
========== すべてリビルド: 1 正常終了、0 失敗、0 スキップ ==========

コード:

output=Mat[3][3](input)*Vec[3](input)
|4824.00| | 12.00  34.00  82.00| |  2.00|
|3478.00| | 43.00  80.00 -54.00| | 64.00|
|4592.00| | 56.00  31.00  78.00| | 32.00|
続行するには何かキーを押してください . . .

返信

“C言語何でも質問掲示板” へ戻る