Re: [eigen] proposal for "clean" output arguments |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] proposal for "clean" output arguments
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Tue, 18 Aug 2009 11:09:07 -0400
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=VKc1IiGa0kW9cMogcK2E8xZESOESEFaTzsq3TYfayq8=; b=uyYWir/jSTErvj376RV1yNlAr6jgaX88Wz3lJn9jVn50JMf+ygypOEkqJbvbN0eBzl gPuEORUsdXHUx468lw+6479bcNknTe+FzQ12H77K6cs9sHPLEiDHqrtwD47uPsBhKZzB b1GW5iWNMHyZ/p/LoaQ5pMrvXS9U2Bq5tvIGI=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=UQ9xCRwlqbrzwhtmkPMzCCPrs07/wYug89fUaECXRyhhBggy/8qkMFvOZpiBRpersm 5uCNfD2zuJouuvVHW3iqUmkqXkQ7Sekl1W2YgA4STTV8OGTNGl02ovvbvqEIwCGSPFZQ uxhrrQMKHAmHzw/EcSTs0CUUm5anpz657r2+A=
Wow, this is a terrific idea. Most of the time it will be used on
Eigen objects so .output() will be good. For the relatively few cases
where the output is a scalar, i think that the global output() is a
good solution. Actually, at the moment I cant think of an example
where the output is not a Eigen object....?
Benoit
2009/8/18 Gael Guennebaud <gael.guennebaud@xxxxxxxxx>:
> Hi all,
>
> here is a proposal to deal with functions having output (or inout)
> arguments. Currently the situation is quite a mess:
>
> 1 - some take non const references like
> TriangularView::solveInPlace(MatrixBase<T>&)
> 2 - some take pointers like LU::solve(const MatrixBase<T1>& B,
> MatrixBase<T2>* X)
> 3 - some take const references like MatrixBase<T1>::swap(const MatrixBase<T2>&)
>
> The main advantage of the solution 3 is that allows to use temporary
> proxies, e.g.:
>
> m.col(i).swap(m.col(j));
>
> The main advantage of solution 2 is that it makes it clear what is an output:
>
> m.lu().solve(b, &x);
>
> The respective drawbacks of each method are pretty obvious I won't
> enumerate them one more time...
>
> So what I propose is to add a trivial Output<T> class mimicking a
> reference T& that we'll be passed by value. Ok to make thing crystal
> clear here is such a Output class:
>
> template<typename T> class Output
> {
> public:
> Output(T& obj) : m_object(obj) { }
> operator T&() { return m_object; }
> protected:
> T& m_object;
> };
>
> then we add a output() member function to AnyMatrixBase<> :
>
> Output<Derived> output() { return derived(); }
>
> then the function LU::solve(const MatrixBase<T1>& B, MatrixBase<T2>*
> X) can be rewritten:
>
> LU::solve(const MatrixBase<T1>& B, Output<T2> _x) {
> T2& x(_x);
> // use x
> }
>
> and the user sill call it like this:
>
> mat.lu().solve(b, xs.col(2).output());
>
> For in-out argument we can do the same with a InOut<T> class, and a
> AnyMatrixBase::inout() function.
>
> Unless I missed something, I think this solution has all the
> advantages that someone can expect:
> - it is more C++ than pointers,
> - it respects constness (unlike const references)
> - it allows to use temporary proxies returned by a function (unlike
> references and pointers)
> - it make it crystal clear what is an output and an in-out arguments
> when someone read a piece of code (unlike all other solutions)
>
> The only limitation I can see is how to extend this concept to scalar
> type arguments because we cannot have:
>
> double x;
> x.output()
>
> Note that if we don't make the ctor of Output explicit, then the
> following we'll work:
>
> void foo(Output<float> _x);
>
> float x;
> foo(x);
>
> If we want to enforce to have "output" next to x, one possibility is
> to add a global function output(T&) and make the ctor of Output
> explicit:
>
> float x;
> foo(output(x));
>
> Note that such a global function will only work on declared objects,
> and not on temporary proxies, that is why we really have to also have
> the output() function as a member of AnyMatrixBase...
>
> Of course, another drawback is more API changes...
>
> What do you think ?
>
> gael.
>
>
>