[eigen] Incorrect result of multiplication with scalar (mingw gcc 4.5 x64)

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Hi all,

I stumbled across a compiler-specific bug (Current Hg tip version 'fix bad "using typename"'):

    static MatrixXd Covariance(Eigen::MatrixBase<MatrixXd> const & points, VectorXd const & mean) {
        return (points.colwise() - mean) * (points.colwise() - mean).transpose() * (1.0/(points.cols()-1.0));
    }

    static MatrixXd CovarianceB(Eigen::MatrixBase<MatrixXd>const & points, VectorXd const & mean) {
        VectorXd diff = VectorXd::Zero(points.rows());
        MatrixXd cov = MatrixXd::Zero(points.rows(),points.rows());
        for(int i=0;i<points.cols();++i) {
            diff.noalias() = points.col(i) - mean;
            cov.noalias() += diff * diff.transpose();
        }
        return cov * (1.0/(points.cols()-1.0));
    }

These two methods return approximately equal results in MSC but not in GCC; turns out the multiplication by the scalar "1.0/(points.cols()-1.0" is ignored by GCC in the first example.

Rearranging the order of the multiplication (i.e. putting the scalar factor in front or in the middle) provides a workaround at no performance cost, as does placing the result into an intermediate variable with the assignment operator rather than returning it directly (with perf cost).  On the other hand, this is also broken:

    static MatrixXd Covariance(Eigen::MatrixBase<MatrixXd> const & points, VectorXd const & mean) {
        return  (1.0/(points.cols()-1.0)) *  ((points.colwise() - mean) * (points.colwise() - mean).transpose());
    }

I'm guessing somewhere some specialization of GeneralProduct is wrong, but as to why this is compiler specific or what exactly the problem is, I don't know.

--eamon@xxxxxxxxxxxx - Tel#:+31-6-15142163


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/