I have a question which might be for beginners.
I want to multiply a 20x2 matrix by a 2x2 matrix in c++.
I tried it with openCV but I get an error which is
Bad argument (Unknown array type) in cvarrToMat
Here is the code that I used in openCV in order to check the problem if it was with my code or the problem in the openCV but it still not working, I can compile with out error, but when I test the code I get the problem " Bad argument (Unknown array type) in 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;
}
To perform matrix multiplication, the first matrix must have the same number of columns as the second matrix has rows. The number of rows of the resulting matrix equals the number of rows of the first matrix, and the number of columns of the resulting matrix equals the number of columns of the second matrix.
Comparing your code with the example in the OpenCV docs, it seems that you forgot to initialize the output matrix 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)
According to the docs, cvMatMul(&Ma, &Mb, &Mc)
is the same as cvMatMulAdd(&Ma, &Mb, 0, &Mc)
.
Well. The answer to this question really depends on a few things. You've said that you know how to do this by hand so to do this in code it will depend on how you represent your matrices. Now if this is a one time thing and you just need the answer to it, I would suggest a language like MATLAB that is built for this. If it is part of a larger program and you will be doing a lot of matrix multiplications that need to be efficient I recommend a high quality optimized library like boost::ublas.
If it is a one time thing and you really want to do it in C++ and you really don't want/know how to use a third party library like ublas, a (not-optimized) matrix multiplication would like like the following:
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With