Re: [eigen] RFC - how to avoid (impossible) recursive declarations |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] RFC - how to avoid (impossible) recursive declarations
- From: Hauke Heibel <hauke.heibel@xxxxxxxxx>
- Date: Fri, 21 Sep 2012 09:53:19 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=UKtupueLOW275U4QrUnUrl0mEOHMHK3h4V28LSKvhN0=; b=EJJCxAYOfwo8IRqLX/DuR2JnV37ufQGz/6pY0YO88BJrzw0RpBuGD1+zOGX1Ot29EA OABCBqx+0cIzy/sIQveYyfYVvWfOhbawAZ7umArbsbn5bWU3vbt2PQPqXy4qcbAe8rxx D/7xMbvJ2rumJ4aghvamtn8h1FZeEms5ruTzG864jsj+2AZjmyR1DCE2eDVnhJzCQfiL GpMl5GO5iTcIh7+CjT7ulHKDW7rSmaaNTsqvuetpfQ6KWGhXoacMO3LL6D9OR9MDt7Zs vQRXVx9kYVZQ1sa88Dw/a+kEc22Gj58SB5Ptoz2uGzdUAiuQ9pl2edehWiIv1wfCVAjT Tfxg==
Hi,
first, you should take a look at this part of the documentation:
http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html
Your code compiles because since you pass by value, you allow implicit
conversions. I.e. the function will create temporary objects, as you
already observed. When you look at your code, you want to pass
MatrixXd, VectorXd as well as Eigen::Block<MatrixXd,Dynamic,Dynamic>
and VectorXd::SegmentReturnType. The most specialized common base
class of these objects is MatrixBase. In order to prevent copies and
code duplication you have write Block_Solve as a template function. I
guess the interface would look like this:
template <typename Derived, typename OtherDerived>
VectorXd Block_Solve( const MatrixBase<Derived>& A, const
MatrixBase<OtherDerived>& b );
Regards,
Hauke
On Fri, Sep 21, 2012 at 9:33 AM, Helmut Jarausch
<jarausch@xxxxxxxxxxxxxxxxxxx> wrote:
> Hi,
>
> I'm just learning using Eigen with partial matrices.
>
> In the example below I try to implement a Block-Gauss-Elimination method.
> It works as shown, but my version needs to copy the parameters of function
> Block_Solve.
> I didn't manage to find a suitable type of the parameters which would avoid
> copying.
> (The algorithm wouldn't need copies)
>
> Many thanks for your help,
> Helmut.
>
>
> #include <iostream>
> using std::cin; using std::cout; using std::cerr; using std::endl;
>
> #include <Eigen/Core>
> #include <Eigen/LU>
>
> using Eigen::MatrixXd; using Eigen::VectorXd;
> using Eigen::Dynamic; using Eigen::PartialPivLU;
> using Eigen::ArrayXd;
>
> const int Teil_Dim = 4;
> typedef Eigen::Block<MatrixXd,Dynamic,Dynamic> PartialMatrix;
> typedef VectorXd::SegmentReturnType PartialVector;
>
> // how to avoid the copying for the paramters A and b ???
>
> VectorXd Block_Solve( MatrixXd A, VectorXd b )
> { int N = A.rows(), m = Teil_Dim, mrest= N-m;
>
> if ( N <= m ) return PartialPivLU<MatrixXd>(A).solve(b);
> VectorXd x = b;
>
> PartialMatrix A11(A,0,0,m,m),
> A12(A,0,m,m,mrest),
> A21(A,m,0,mrest,m),
> A22(A,m,m,mrest,mrest);
>
> PartialVector x1(x,0,m), x2(x,m,mrest);
> PartialPivLU<MatrixXd> A11_LU(A11);
>
> x2 -= A21 * A11_LU.solve(x1);
> A22-= A21 * A11_LU.solve(A12);
>
> x2 = Block_Solve( A22, x2 );
>
> VectorXd x1d = x1; // copy needed against aliasing ???
> x1= A11_LU.solve( x1d - A12*x2 ); // aliasing problem !!!
>
> return x;
> }
>
> int main()
> { int N;
> int i;
> cerr << "Dimension: "; cin >> N;
>
> MatrixXd A(N,N);
> VectorXd rhs(N); // temp. Vektor initially
> VectorXd x(N);
>
> for (i= 0; i < N; i++ ) rhs[i]= i;
> rhs= cos( (M_PI/N)*rhs.array() );
> ArrayXd rhs_pow = rhs.array();
>
> A.col(0).fill(1.0);
> A.col(1)= rhs;
> for ( i= 2; i < N; i++ ) {
> rhs_pow*= rhs.array();
> A.col(i)= rhs_pow;
>
> }
> for ( i= 0; i < N; i++ ) x[i]= i+1; // solution
> rhs= A*x;
>
> VectorXd Lsg = Block_Solve( A, rhs );
> cout << "Fehler: " << (Lsg-x).norm() << endl;
> return 0;
> }
>
>