简体   繁体   中英

Matrix multiplication

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;
}

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);
}

May be you should post the prototype of the function you are calling, as well as the declaration of your matrices and your call. I don't think everyone is familiar with a openCV.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM