Re: [eigen] Missing operator definition in Sparse? |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Missing operator definition in Sparse?
- From: Sameer Agarwal <sameeragarwal@xxxxxxxxxx>
- Date: Thu, 24 Jun 2010 15:31:44 -0700
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta; t=1277418710; bh=FsdMrCeUAiGQllxSlKMrQV4YtAY=; h=MIME-Version:In-Reply-To:References:Date:Message-ID:Subject:From: To:Content-Type:Content-Transfer-Encoding; b=etwC3LrT0AkstAZcansx77g56W/o+zjKwov4JgPf6W6Zgd0NynipX7sDTSAsrr98K 0IP6wJFBGKICV0+2bAPAQ==
- Domainkey-signature: a=rsa-sha1; s=beta; d=google.com; c=nofws; q=dns; h=mime-version:in-reply-to:references:date:message-id:subject:from:to: content-type:content-transfer-encoding:x-system-of-record; b=fs4dK2Z550T76p9lh4p79rfu9opfZBgVfUAfPhbgKe/hCTG0qkvYrK8Ku1ir9TTqC lLyYCF/w1h68uOMChc25g==
Hi Gael,
x*y^T where one of the vectors is dense and one is sparse should
return a sparse matrix.
m.col(0) is a large but extremely sparse vector, so creating a dense
temporary is a bad idea.
Such rank 1 updates are not that uncommon. I encounter this one
while constructing a preconditioner.
I can solve the problem by making both the vectors sparse, but I would
argue that the mixed version should also work.
Sameer
On Thu, Jun 24, 2010 at 1:51 PM, Gael Guennebaud
<gael.guennebaud@xxxxxxxxx> wrote:
> On Thu, Jun 24, 2010 at 10:07 PM, Sameer Agarwal
> <sameeragarwal@xxxxxxxxxx> wrote:
>> Hi Guys,
>>
>> I am using the development branch. The following bit of code does not compile.
>>
>> #include "Eigen/Core"
>> #include "Eigen/Sparse"
>>
>> typedef Eigen::SparseMatrix<double, Eigen::ColMajor> SparseCol;
>> typedef Eigen::Matrix<double, Eigen::Dynamic, 1> Vector;
>>
>> int main() {
>> int nrow = 5;
>> int ncol = 5;
>> SparseCol m(nrow,ncol);
>> Vector x(ncol,1);
>> SparseCol A = m.subcols(1, 4) - m.col(0)* x.transpose();
>> return 0;
>> }
>>
>> Compiled complains about a missing operator definition.
>
> Indeed, there is no special handling for m.col(0)* x.transpose(). It
> is treated as a standard sparse by dense product, and so it returns a
> dense object...
>
> To be honest I'm a bit surprised by such an expression, but if you
> need it that's easily doable.
>
> As a side note, the following works but fully evaluate the outer
> product to a dense temporary matrix:
>
> Vector x(4,1);
> SparseCol A = m.subcols(1, 4) - (m.col(0)* x.transpose()).sparseView();
>
> (you need to update your local copy to make it compile fine)
>
> gael
>
>>
>>
>> test_sparse.cc: In function ‘int main()’:
>> test_sparse.cc:12: error: no match for ‘operator-’ in
>> ‘m.Eigen::SparseMatrix<double, 0,
>> int>::<anonymous>.Eigen::SparseMatrixBase<Derived>::subcols [with
>> Derived = Eigen::SparseMatrix<double, 0, int>](1, 4) -
>> Eigen::SparseMatrixBase<Derived>::operator*(const
>> Eigen::MatrixBase<OtherDerived>&) const [with OtherDerived =
>> Eigen::Transpose<Eigen::Matrix<double, -0x00000000000000001, 1, 0,
>> -0x00000000000000001, 1> >, Derived =
>> Eigen::SparseInnerVectorSet<Eigen::SparseMatrix<double, 0, int>,
>> 1>](((const Eigen::MatrixBase<Eigen::Transpose<Eigen::Matrix<double,
>> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> > >&)((const
>> Eigen::MatrixBase<Eigen::Transpose<Eigen::Matrix<double,
>> -0x00000000000000001, 1, 0, -0x00000000000000001, 1> >
>>>*)(&((Eigen::DenseBase<Eigen::Matrix<double, -0x00000000000000001, 1,
>> 0, -0x00000000000000001, 1> >*)(&
>> x))->Eigen::DenseBase<Derived>::transpose [with Derived =
>> Eigen::Matrix<double, -0x00000000000000001, 1, 0,
>> -0x00000000000000001, 1>]()))))’
>> Eigen/src/Sparse/../plugins/CommonCwiseUnaryOps.h:59: note: candidates
>> are: const Eigen::CwiseUnaryOp<Eigen::ei_scalar_opposite_op<typename
>> Eigen::ei_traits<Derived>::Scalar>, Derived>
>> Eigen::SparseMatrixBase<Derived>::operator-() const [with Derived =
>> Eigen::SparseInnerVectorSet<Eigen::SparseMatrix<double, 0, int>,
>> -0x00000000000000001>]
>>
>> Thanks,
>> Sameer
>>
>>
>>
>
>
>