buddhi weerasinghe
buddhi weerasinghe

Reputation: 737

Assertion failure multiplying Eigen matrices

I am writing a c++ program for least square leaner regression problem in interpolation. I use Eigen for matrix operations. The problem I am getting is when I run the program it shows an error displaying an assertion error. Here is my code:

#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
using namespace std;
int main()
{
    int i;
    int nmbrOfPoints;
    cout<<" Enter the number of data points : ";
    cin>>nmbrOfPoints;

    MatrixXd matY(nmbrOfPoints,1);       //initialize matrix Y
    MatrixXd matX(nmbrOfPoints,2);       //initialize matrix X
    MatrixXd matXdup(nmbrOfPoints,2);      //initialize matrix X duplicate
    MatrixXd matAns(2,1);


    for(i=0;i<nmbrOfPoints;i++)
    {
        matX(i,0)=1;                    // storing the 1 st column of the matrix x, all 1s.
        matXdup(i,0)=1;
    }

    cout<<"Enter all sample points (x and y values ): "<<endl;

    for(i=0;i<nmbrOfPoints;i++)
    {
        cin>>matX(i,1)>>matY(i,0); // read both (x,f(x)) ,, store x values to matrix x and y values to matrix y
    }

    for(i=0;i<nmbrOfPoints;i++)
    {
        matXdup(i,1)=matX(i,1);    //copying matrix x to its duplicate
    }

    cout<<"\n \n";
    cout << matX << endl;
    cout<<"\n \n";
    cout << matY << endl;
    cout<<"\n \n";
    cout << matXdup << endl;

    // find the transpose of matrix x

    cout << "\nHere is the transposed matrix x duplicate:\n" << endl;
    matXdup.transposeInPlace();


    cout << matXdup << endl;
    cout<<"\n \n";
    cout << matX << endl;

    //find the multiplication of x and transpose of x

    matX = matX* matXdup;   // now the matrix x holds the multiplication of transpose of x and x

    cout << "\nmultiplication of x and xdup:\n" << endl;
    cout << matX << endl;
    cout<<"\n \n";

    //find the inverse of x

    double q,a,b,c,d;

    a=matX(0,0);
    b=matX(0,1);
    c=matX(1,0);
    d=matX(1,1);

    q=1/((a*d)-(b*c));

    matX(0,0) = d*q;
    matX(0,1) = b*-1*q;             //now matrix x holds the inverse of x
    matX(1,0) = c*-1*q;
    matX(1,1) = a*q;

    cout<<"\n \n";
    cout << "\n inverse of x:\n" << endl;
    cout << matX << endl;

    //find the multiplication of transpose of x(x duplicate matrix) and y

     matY = matXdup* matY;   // now the matrix x duplicate holds the multiplication of y and x transpose

    //find the multiplication of x(inverse of xt*x) and matXdup (xt*y)

    // matAns = matY* matX;

     cout << "\nfinal answers :\n" << endl;
     cout << "\n *********************:\n" << endl;

     cout << matY << endl;
     cout<<"\n \n";
     cout << matX << endl;

     cout << "\nfinal answer FINAL :\n" << endl;
     cout << "\n *********************:\n" << endl;
     matAns = matY* matX;
     cout << matAns << endl;

     /*cout<<"\n matx dup = \n";
     cout << matXdup << endl;
     cout<<"\n maty =  \n";
     cout << matY << endl;
     cout<<"\n \n";*/

     return 0;


}

I am getting the error from the final multiplication part which is matAns = matY* matX:

Assertion failed: a_lhs.cols() == a_rhs.rows() && "invalid matrix product" && "if you wanted a coeff-wise or a dot product use the respective explicit functions"

When I remove that statement code works. Up to that point the code works fine. Can someone explain me what is assertion problem and how to fix it here?

Upvotes: 2

Views: 6003

Answers (1)

ggael
ggael

Reputation: 29205

matY is a 2x1 vector and matX is a NxN matrix, so the product matY * matX is invalid. Are you sure you don't want to compute matX as:

matX = matXdup * matX;

and matAns as:

matAns = matX * matY;

?

BTW, no need to explicitly transpose matXdup with transposeInPlace, you can directly do:

matX = matXdup.transpose() * matX;

Moreover, when a dimension is known at compiletime and that this dimension is very small, better specify it. For instance, matY should rather be a VectorXd. The result of matXdup.transpose() * matX should rather be stored in a Matrix2d object. Then call inverse() instead of writing your own inverse routine (you need to include <Eigen/LU>:

Matrix2d XX = matXdup.transpose() * matX; 
Vector2d Y = matXdup * matY;
Vector2d ans = XX.inverse() * Y;

Upvotes: 3

Related Questions