質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1966閲覧

テンプレートクラスを使用した行列クラスの内積

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/02/03 11:41

編集2019/02/03 12:55

###main.hpp

c++

1//main.cpp用のインクルードガード 2#ifndef STDIO_H 3#define STDIO_H 4#include <stdio.h> 5#endif 6 7#ifndef MATRIX_HPP 8#define MATRIX_HPP 9#include <matrix.hpp> 10#endif 11 12

main.cpp

c++

1#include <main.hpp> 2 3int main(){ 4 matrix::Matrix_2d<double,2,2> matrix_1;//2x2の行列オブジェクト作成 5 double var1[2][2] = {{1,2},{3,4}}; 6 matrix_1.copy(var1);//空の行列に数値を流し込む 7 8 matrix::Matrix_2d<double,2,3> matrix_2;//2x3の行列オブジェクト作成 9 double var2[2][3] = {{1,2,3},{4,5,6}}; 10 matrix_2.copy(var2);//空の行列に数値を流し込む 11 12 matrix::Matrix_2d<double,2,3> matrix_3;//2x3の行列オブジェクト作成 13 matrix_3.dot(matrix_1,matrix_2);//matrix_1 dot matrix_2 = matrix_3 14 matrix_3.print();//matrix_3の中身表示 15 16 return 0; 17}

###matrix.hpp(ヘッダー内に実装も記述)

c++

1#ifndef STDIO_H 2#define STDIO_H 3#include <stdio.h> 4#endif 5 6 7namespace matrix{ 8 template<typename TYPE,int COL,int ROW> 9 class Matrix_2d{//行列クラス 10 private: 11 int col = COL;//行数 12 int row = ROW;//列数 13 TYPE mat[COL][ROW];//行列の数値を保存するための配列 14 public: 15 void clear(){//ゼロクリア関数 16 for(int i=0;i<this->col;i++){ 17 for(int j=0;j<this->row;j++){ 18 (this->mat)[i][j] = 0; 19 } 20 } 21 } 22 void print(){//行列の中身表示用関数 23 printf("//////////////////////////////////////////////////////////////\n"); 24 for(int i=0;i<this->col;i++){ 25 printf("["); 26 for(int j=0;j<this->row;j++){ 27 printf("[%lf]",(this->mat)[i][j]); 28 } 29 printf("]\n"); 30 } 31 } 32 void copy(TYPE mat[COL][ROW]){//行列のコピー用関数 33 for(int i=0;i<this->col;i++){ 34 for(int j=0;j<this->row;j++){ 35 (this->mat)[i][j] = mat[i][j]; 36 } 37 } 38 } 39 void print_shape(){//行列の形状表示用関数 40 printf("shape = [%d,%d]\n",(this->col),(this->row)); 41 } 42 43 int get_col(){//行数表示用関数 44 return (this->col); 45 } 46 47 int get_row(){//列数表示用関数 48 return (this->row); 49 } 50 51 TYPE get_mat(int col_in,int row_in){//要素へのアクセス用関数 52 return (this->mat)[col_in][row_in]; 53 } 54 55 void dot(Matrix_2d in_1, Matrix_2d in_2) {//内積用関数 56 int i, j, k; 57 TYPE term; 58 59 for (i = 0; i < (this->col); i++) { 60 for (j = 0; j < (this->row); j++) { 61 term = 0; 62 for (k = 0; k < (in_2.get_col()); k++) { 63 term = term + in_1.get_mat(i,k) * in_2.get_mat(k,j); 64 } 65 (this->mat)[i][j] = term; 66 } 67 } 68 } 69 }; 70 71} 72 73 74 75

質問内容

c++初心者です。
上記のコードで2次元行列の内積を表現したいのですが
コンパイル時に下記のようなエラーが発生します。
おそらくmatrix_3.dot(matrix_1,matrix_2);
の引数のメモリサイズがそれぞれ違うのかな(トンチンカンなこと言ってたらごめんなさい)と思います
がエラーの回避方法がわからず困っています。
どうかご教授おねがいします。

error

1main.cpp:14:35: error: no matching function for call to ‘matrix::Matrix_2d<double, 2, 3>::dot(matrix::Matrix_2d<double, 2, 2>&, matrix::Matrix_2d<double, 2, 3>&)’ 2 matrix_3.dot(matrix_1,matrix_2); 3 ^ 4In file included from ./main.hpp:8:0, 5 from main.cpp:1: 6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2019/02/03 12:10

エラーについては、メッセージ通りで、引数と戻り値が一致する関数が無いと言っています。 私の理解が不足しているのかも知れませんが、内積は行列を返すのでしょうか? 一つの数値を返すと理解していますが、、、。
退会済みユーザー

退会済みユーザー

2019/02/03 13:26 編集

質問を拝見して下さりありがとうございます。 dot関数は行列と行列の内積なので行列を返す関数です。 matrix_3 = matrix_1 dot matrix_2 matrix_3.dot(matrix_1,matrix_2)   ↑     ↑    ↑ 結果保存用  入力1   入力2 [2行3列]   [2行2列]   [2行3列]
guest

回答2

0

C++

1 template<typename TYPE,int COL,int ROW> 2 class Matrix_2d{//行列クラス 3 ... 4 void dot(Matrix_2d in_1, Matrix_2d in_2)

これだと ROW行COL列 と ROW行COL列 のふたつの行列の積になるです。

template<int K> void dot(matrix_2d<COL,K> in_1, matrix_2d<K,ROW> in_2)

とか、そんなんなるんじゃないかな正解は。

投稿2019/02/03 12:30

編集2019/02/05 04:49
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

Matrix_2dはtemplateクラスなので、直接dotの引数の型には使えません。dotをテンプレートメンバー関数にすれば、例えば次のように書けます。

c++

1#ifndef MATRIX_HPP 2#define MATRIX_HPP 3#include <stdio.h> 4 5namespace matrix { 6template <typename TYPE, int COL, int ROW> 7class Matrix_2d { //行列オブジェクト 8 ... # 省略 9 template <int K> 10 void dot(Matrix_2d<TYPE, COL, K> in_1, 11 Matrix_2d<TYPE, K, ROW> in_2) 12 { 13 ... # 省略 14 } 15}; 16 17} // namespace matrix 18#endif // MATRIX_HPP

気になった点

  • include guardの使い方がおかしい・・・。
  • 行列の積は[p, q] * [q, r] (p, q, rは正の整数)でしか定義されないので、上のテンプレートメンバー関数はもう少し制限かけておいたほうがよい。
  • たぶん計算結果おかしい。

投稿2019/02/03 12:24

編集2019/02/03 12:38
tachikoma

総合スコア3601

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/02/04 11:06

ご回答ありがとうございます。 このコードでコンパイルしてみたら無事動きました。 include guardのご指摘も助かりました。 計算結果についてはpythonのnumpyで同じ計算をして確かめてみましたが大丈夫そうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問