Cannot perform arithmetic operations on rows

Issue #117 wontfix
Daniel Baker created an issue

Hi,

I have been unable to get a set of operations which I would expect to be generic to compile.

First, I can't seem to subtract a matrix row from a vector and store it in another vector:

src/gmm_train.cpp:122:53:   required from here                                      
./lib/mm.h:64:21: error: no match for 'operator-' (operand types are 'const blaze::DynamicVector<double>' and 'blaze::DisableIf_<blaze::Or<blaze::IsComputation<blaze::DynamicMatrix<double> >, blaze::IsTra
         tmpdiff = r - row(mu_, 0);                                                 
                   ~~^~~~~~~~~~~~~                                                  
In file included from blaze/blaze/math/DenseVector.h:63:0,                          
                 from blaze/blaze/math/DynamicVector.h:45,                          
                 from blaze/blaze/math/CustomMatrix.h:46,                           
                 from blaze/blaze/Math.h:50,                                        
                 from ./lib/mm.h:12,                                                
                 from src/gmm_train.cpp:1:                                          
blaze/blaze/math/expressions/SVecDVecSubExpr.h:761:4: note: candidate: template<class VT1, class VT2, bool TF, class VT3> blaze::SubExprTrait_<blaze::SVecDVecSubExpr<VT1, VT2, TF>, VT3> blaze::operator-(c
    operator-( const SVecDVecSubExpr<VT1,VT2,TF>& lhs, const DenseVector<VT3,TF>& rhs )
    ^~~~~~~~                                                                        
blaze/blaze/math/expressions/SVecDVecSubExpr.h:761:4: note:   template argument deduction/substitution failed:
In file included from src/gmm_train.cpp:1:0:                                        
./lib/mm.h:64:21: note:   'const blaze::DynamicVector<double>' is not derived from 'const blaze::SVecDVecSubExpr<VT1, VT2, TF>' 
         tmpdiff = r - row(mu_, 0);                                                 
                   ~~^~~~~~~~~~~~~                 

Second, I can't multiply a matrix with a row as if it were a matrix/vector computation:

./lib/mm.h: In instantiation of 'FloatType mm::GaussianSubModel<FloatType, DistanceMetric, MatrixType>::operator()(const RowType1&, RowType2&) const [with RowType1 = blaze::Row<const blaze::DynamicMatrix<
./lib/mm.h:133:30:   required from 'void mm::submodel_update(const MT&, std::vector<SubModel>&, std::size_t, std::size_t, DistanceMetric, ModelArgs&& ...) [with MT = blaze::DynamicMatrix<double>; SubModel
./lib/mm.h:261:24:   required from 'void mm::GaussMixtureModel<FloatType, DistanceMetric, SubModel>::train(const MT&, std::size_t, ModelArgs&& ...) [with MT = blaze::DynamicMatrix<double>; ModelArgs = {};
./lib/mm.h:368:13:   required from 'void mm::MixtureModelClassifier<ModelClass, FloatType, DistanceMetric, IdIntegerType>::init_models(const MatrixType&, const VectorType&, std::size_t, mm::MixtureModelCl
./lib/mm.h:405:20:   required from 'void mm::MixtureModelClassifier<ModelClass, FloatType, DistanceMetric, IdIntegerType>::train(MatrixType&, VectorType&, std::size_t, mm::MixtureModelClassifier<ModelClas
./lib/mm.h:410:14:   required from 'void mm::MixtureModelClassifier<ModelClass, FloatType, DistanceMetric, IdIntegerType>::train(MatrixType&, VectorType&, std::size_t, Args&& ...) [with MatrixType = blaze
src/gmm_train.cpp:67:29:   required from here                                   
./lib/mm.h:67:37: error: no match for 'operator*' (operand types are 'const blaze::DynamicMatrix<double>' and 'blaze::Row<blaze::DynamicMatrix<double>, true, true, false>')
             dm_(tmpdiff, inv_sigma_ * tmpdiff) * -0.5);                        
                          ~~~~~~~~~~~^~~~~~~~~                                  
In file included from blaze/blaze/math/DenseVector.h:55:0,                      
                 from blaze/blaze/math/DynamicVector.h:45,                      
                 from blaze/blaze/math/CustomMatrix.h:46,                       
                 from blaze/blaze/Math.h:50,                                    
                 from ./lib/mm.h:12,                                            
                 from src/gmm_train.cpp:1:                                      
blaze/blaze/math/expressions/DVecScalarMultExpr.h:1820:4: note: candidate: template<class VT, class ST, class MT, bool SO> blaze::MultExprTrait_<blaze::DVecScalarMultExpr<VT, ST1, true>, MT> blaze::operat
    operator*( const DVecScalarMultExpr<VT,ST,true>& vec, const SparseMatrix<MT,SO>& mat )
    ^~~~~~~~                                                                    
blaze/blaze/math/expressions/DVecScalarMultExpr.h:1820:4: note:   template argument deduction/substitution failed:
In file included from src/gmm_train.cpp:1:0:                                    
./lib/mm.h:67:37: note:   'const blaze::DynamicMatrix<double>' is not derived from 'const blaze::DVecScalarMultExpr<VT, ST1, true>'
             dm_(tmpdiff, inv_sigma_ * tmpdiff) * -0.5);                        

[In this issue, inv_sigma_ is a DynamicMatrix<double> which has been declared symmetric and tmpdiff is a row in a matrix of doubles with the same layout as inv_sigma_.]

Is this a bug or simple user error?

Comments (2)

  1. Klaus Iglberger

    Hi dnbh!

    In this case it s a simple use error. Blaze distinguishes between column vectors and row vectors. The row of a matrix counts as a row vector. As stated in the wiki it is only possible to subtract vectors with the same transpose flag:

    blaze::DynamicVector<int,columnVector> v1( 5UL );
    blaze::CompressedVector<float,rowVector> v2( 5UL );
    
    v1 - v2;           // Compilation error: Cannot subtract a row vector from a column vector
    v1 - trans( v2 );  // OK: Subtraction of two column vectors
    

    Also, as also stated in the wiki you can only multiply a matrix with a column vector or alternatively a row vector with a matrix:

    using blaze::StaticVector;
    using blaze::DynamicVector;
    using blaze::DynamicMatrix;
    
    DynamicMatrix<int> M1( 39UL, 12UL );
    StaticVector<int,12UL,columnVector> v1;
    
    // ... Initialization of the matrix and the vector
    
    DynamicVector<int,columnVector> v2 = M1 * v1;           // Matrix/column vector multiplication
    DynamicVector<int,rowVector>    v3 = trans( v1 ) * M1;  // Row vector/matrix multiplication
    

    In order to make your code work you only have to transpose the row to a column vector:

    tmpdiff = r - trans( row(mu_, 0) );
    ...
    dm_(tmpdiff, inv_sigma_ * trans(tmpdiff)) * -0.5);
    

    For the second operation you can also choose to switch the operands since the matrix is symmetric:

    dm_(tmpdiff, tmpdiff * inv_sigma_) * -0.5);
    

    I hope this solves the problem.

    Best regards,

    Klaus!

  2. Log in to comment