Re: [eigen] first time usage by me! and very satisfied!
• To: eigen@xxxxxxxxxxxxxxxxxxx
• Subject: Re: [eigen] first time usage by me! and very satisfied!
• From: "Schleimer, Ben" <bensch128@xxxxxxxxx>
• Date: Fri, 12 Sep 2008 16:27:42 -0700 (PDT)

```Hi Gael,

I think we are heading towards a common design.

> I don't follow you. Actually there is no such Array
> class. The Array
> module mainly contains the definitions of a couple of
> methods declared

Sorry about that. I haven't actually worked with Eigen2 yet. Work is mostly on my mind :( (I have a story about two very badly implemented Matrix libraries (in the name of optimization) which is why I'm eager to see eigen2 be well written.)
>
>
> ah ! after answering the rest of the comments I now see how
> it could
> be done. maybe you were thinking  to something like that:
>
> VectorType v;
> // play with v..
> // now you want some statistics on v:
>
> Statistics<VectorType> s(v);
>
> s.mean();
> s.variance();
> etc.
> etc.
>
> // MatrixBase would define:
> // Statistics<Derived> stats() const { return
> derived(); }
> // so that you can also do:
>
> v.stats().mean();
>

Actually I was thinking of:
template <typename Scalar>
struct DirtyCacher
{
bool dirty() const { return _dirty; }
void setDirty(bool f) { _dirty = f; }
Scalar mean(Statistics* obj) const
{
if(dirty())
{
_mean = obj->meanInternal();
_dirty = false;
}
return _mean;
}

bool _dirty;
Scalar _mean;
}

template <typename Scalar>
struct NoCacher
{
bool dirty() const { return true; }
void setDirty(bool f) { /*nothing*/ }
Scalar mean(Statistics* obj) const
{
return obj->meanInternal();
}
}

template <typename VectorType, typename Cacher = DirtyCacher<VectorType::Scalar> >
class Statistics
{
Statistics(VectorType v)
: _v(v) {}
VectorType::Scalar mean() const
{
return cacher.mean(this);
}
const VectorType& value() const
{
// always assume this isn't changed
return _v;
}
VectorType& value()
{
cacher.setDirty(true); // always assume the data is changed
return _v;
}
...
protected:
Cacher cacher;
friend struct DirtyCacher;
friend struct NoCacher;
VectorType::Scalar meanInternal()
{
// always calculate the mean here
Scalar ret = 0;
for(size_t i=0; i<_v.size(); ++i)
{
ret += _v[i];
}
return ret / _v.size();
}
}

Basically, if the user chooses to use the DirtyCacher, he should get a mean() lookup speed increase but he'll loose 1+sizeof(Scalar) bytes. If he uses NoCacher, he gets the space back but with a lookup speed loss. If there are more items to cache, then we can use a bitfield to minimize the space loss (eg. use meanDirty, varienceDirty, sortDirty).
Also the other nice thing about this design is that VectorType doesn't need to know anything about the existance of the Statistic class.
The returning the value as non-const maybe could be sped up if VectorType can indicate that an operation has modified it or not. This is just the most straight forward thing i could think of.

>
> "*this"... but you
> can use the result of any function as default argument
> value, for
> instance:
>
> float foo(float v = random()) {...}
>
> is ok.

Ahh, i did not know that... interesting..

cheers
Ben

>
> >> I prefer that to something like:
> >> Scalar stddev(Scalar*  returnedMean = 0) const;
> >> because in case you have already computed the mean
> value
> >> you cannot
> >> tell stddev to use it...
> >
> > This is confusing. what does the function return if
> returnedMean == 0?
> > It might be better to cache the mean and not return it
> in the stddev() method. The user has access to it in mean(),
> no?
>
>  I think I was not clear here. I meant: "I prefer the
> above approach
> rather than the following common solution".
> and to be clear, its implementation would be:
> Scalar stddev(Scalar*  returnedMean = 0) const
> {
>    Scalar m = mean();
>    if (returnedMean) *returnedMean = m;
>    // compute and returns stddev
> }
>
> but again I don't like this approach !!
>
> >>
> >> so to summarize we would add:
> >>
> >> * mean()
> >>
> >> * standardDeviation([precomputed_mean])
> >> yeah, eventually "standardDeviation" is
> not too
> >> long
> >>
> >> * variance([precomputed_mean])
> >>
> >> * median()
> >> maybe here we could have an optional argument to
> tell if
> >> the vector is
> >
> > We could have a cached sorted flag...
>
> same pb as above
>
>
> gael.
>
> >>
> >> * sort()
> >> median needs a sort algo, and here I really mean
> >> "sort", not "sorted",
> >> so it an in-place sort
> >>
> >
> >
> > Cheers
> > Ben
> >
> >
> >>
> >> cheers,
> >> gael.
> >>
> >> On Thu, Sep 11, 2008 at 8:29 PM, Andre Krause
> >> <post@xxxxxxxxxxxxxxxx> wrote:
> >> > dear list, just wanted to let you all know i
> am using
> >> eigen2 alpha 07 for the
> >> > first time - and i am very satisfied. works
> like
> >> charm, with no problems on
> >> > win32 and visualc++ 2008.
> >> >
> >> > though i am missing some basic convenience
> functions
> >> like mean, medium, stdev
> >> > etc. . i already heard on #eigen, that they
> are
> >> planned for some future release.
> >> >
> >> > kind regards,
> >> >        andre
> >> >
> >> >
> >> >
> >
> >
> >

```

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