2010-12-17 30 views
7

Tengo una pregunta que podría ser para principiantes.Multiplicación de matrices

Quiero multiplicar una matriz de 20x2 por una matriz de 2x2 en C++.

he probado con OpenCV pero me da un error que es

mal argumento (Desconocido tipo de matriz) en cvarrToMat


Aquí está el código que he utilizado en OpenCV en Para verificar el problema si estaba con mi código o el problema en openCV pero aún no funciona, puedo compilar sin error, pero cuando pruebo el código me aparece el problema "Argumento malo (tipo de matriz desconocida) en cvarrToMat "

#include <stdio.h> 
#include <stdlib.h> 
//#include "/usr/include/opencv/cv.h" 
#include <cv.h> 
#include <cvaux.h> 
#include <highgui.h> 
#include <math.h> 
#include <iostream> 

    int main() 
{ 


double a[] = {1, 2, 3, 4}; 
CvMat Ma; 
cvInitMatHeader(&Ma, 2, 2, CV_32FC1, a); 


double b[] ={0, -1, 1, 0}; 

CvMat Mb; 
cvInitMatHeader(&Mb, 2, 2, CV_32FC1, b); 

CvMat Mc; 
CvMat Mc1; 
cvMatMul(&Ma, &Mb, &Mc); 

return 0; 
} 
+0

¿Sabes cómo hacerlo a mano? ¿Estás buscando una forma que no sea a mano? – Falmarri

+0

¿Puedo preguntar, por qué necesita esta multiplicación? Sólo curioso. –

+9

Quizás deberías aceptar algunas respuestas. – GWW

Respuesta

-3

Puede ser que deba publicar el prototipo de la función que está llamando, así como la declaración de sus matrices y su llamada. No creo que todos estén familiarizados con openCV.

+1

Parece que necesita crear su matriz de salida. En su ejemplo, cambie la declaración de Mc de CvMat a CvMat * e inicialícela: CvMat * Mc = cvCreateMat (2, 2, CV_32FC1); Creo que esto funcionará El compilador no puede capturar una matriz no inicializada, ya que la verificación de tipo estática pasará. –

4

Bien. La respuesta a esta pregunta realmente depende de algunas cosas. Has dicho que sabes cómo hacerlo a mano, así que hacer esto en código dependerá de cómo representes tus matrices. Ahora bien, si se trata de algo de una sola vez y solo necesita la respuesta, sugeriría un lenguaje como MATLAB creado para esto. Si es parte de un programa más grande y usted hará muchas multiplicaciones de matrices que necesitan ser eficientes, recomiendo una biblioteca optimizada de alta calidad como boost::ublas.

Si es una cosa de una vez y realmente quieres hacerlo en C++ y realmente no quieres/saber cómo usar una biblioteca de terceros como ublas, me gustaría una multiplicación de matriz (no optimizada) lo siguiente:

template<typename T> 
struct matrix2d 
{ 
private: 
    std::vector<std::vector<T>> data; 
    size_t _rows, _columns; 
public: 
    matrix2d(size_t rows, size_t columns) 
     :_rows(rows) 
     ,_columns(columns) 
    { 
     data.resize(_rows, std::vector<T>(_columns)); 
    } 

    size_t rows() const { return _rows; } 
    size_t columns() const { return _columns; } 

    T& operator()(size_t row, size_t column) 
    { 
     return data[row][column]; 
    } 

    const T& operator()(size_t row, size_t column) const 
    { 
     return data[row][column]; 
    } 
}; 

template<typename T> 
void mmult(const matrix2d<T>& m1, const matrix2d<T>&m2, matrix2d<T>& result) 
{ 
    for (size_t r = 0 ; r<m1.rows() ; ++r) 
     for (size_t c = 0; c<m2.columns() ; ++c) 
      for (size_t n = 0; n<m1.columns() ; ++n) 
       result(r, c) = m1(r, n) * m2(n, c); 
} 


int main() 
{ 

    matrix2d<double> m1(20, 2); 
    matrix2d<double> m2(2, 2); 
    matrix2d<double> result(m1.rows(), m2.columns()); 
    mmult(m1, m2, result); 
} 
5

al comparar el código con el example in the OpenCV docs, parece que ha olvidado para inicializar la matriz de salida Mc:

double a[] = { 1, 2, 3, 4, 
       5, 6, 7, 8, 
       9, 10, 11, 12 }; 

double b[] = { 1, 5, 9, 
       2, 6, 10, 
       3, 7, 11, 
       4, 8, 12 }; 

double c[9]; 
CvMat Ma, Mb, Mc ; 

cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a); 
cvInitMatHeader(&Mb, 4, 3, CV_64FC1, b); 
cvInitMatHeader(&Mc, 3, 3, CV_64FC1, c); 

cvMatMulAdd(&Ma, &Mb, 0, &Mc); 
// the c array now contains the product of a (3x4) and b (4x3) 

de acuerdo con los documentos, cvMatMul(&Ma, &Mb, &Mc) es lo mismo que cvMatMulAdd(&Ma, &Mb, 0, &Mc).

Cuestiones relacionadas