disturbance to 1 field of a large object

H

Hicham Mouline

Hello

I have a function

double f( const Parameters& p );

the object Parameters is big. sizeof(Parameters) is big.

we wish to calculate the senstivity of f to 1 of the parameters inside p,
a naive implementation is

// forward difference
double fprime( const Parameters& p )
{
const double y = f(p);
Parameters pup = p;
pup.p3 += epsilon;

const double yup = f(pup);

return (yup-y)/epsilon;
}

on a profiler, the problem here looks to be the deep copy of p into pup.

Is there an alternative way that remains readable and concise?

regards,
 
P

Pascal J. Bourguignon

Hicham Mouline said:
Hello

I have a function

double f( const Parameters& p );

the object Parameters is big. sizeof(Parameters) is big.

we wish to calculate the senstivity of f to 1 of the parameters inside p,
a naive implementation is

// forward difference
double fprime( const Parameters& p )
{
const double y = f(p);
Parameters pup = p;
pup.p3 += epsilon;

const double yup = f(pup);

return (yup-y)/epsilon;
}

on a profiler, the problem here looks to be the deep copy of p into pup.

Is there an alternative way that remains readable and concise?

Write a wrapper that forwards all messages to the Parameters but p3.

Of course, in C++, it's hard to do it.
In any other OO programming language, it's trivial.


But it may remain readable:

// or perhaps: template <class ParametersOrForwarder>
double f(const ParametersOrForwarder& p){
...
}

double fprime( const Parameters& p )
{
const double y = f(p);
Forwarder pup(p);
pup.p3 += epsilon;
const double yup = f(pup);
return (yup-y)/epsilon;
}
 
L

Lionel B

Hello

I have a function

double f( const Parameters& p );

the object Parameters is big. sizeof(Parameters) is big.

we wish to calculate the senstivity of f to 1 of the parameters inside
p, a naive implementation is

// forward difference
double fprime( const Parameters& p )
{
const double y = f(p);
Parameters pup = p;
pup.p3 += epsilon;

const double yup = f(pup);

return (yup-y)/epsilon;
}

on a profiler, the problem here looks to be the deep copy of p into pup.

Is there an alternative way that remains readable and concise?

How about simply:

double fprime( Parameters& p )
{
const double y = f(p);
const p3type p3save = p.p3;
p.p3 += epsilon;
const double yup = f(p);
p.p3 = p3save;
return (yup-y)/epsilon;
}

Not ideal - you lose const-ness of your parameter - but workable.
 
M

mzdude

Hello

double f( const Parameters& p );

the object Parameters is big. sizeof(Parameters) is big.

we wish to calculate the senstivity of f to 1 of the parameters inside p,
a naive implementation is

// forward difference
double fprime( const Parameters& p )
{
   const double y = f(p);
   Parameters pup = p;
   pup.p3 += epsilon;

   const double yup = f(pup);

   return (yup-y)/epsilon;

}

Rewrite f() to do both calculations at the same time.

std::pair<double,double> p = f2(p,epsilon);

p.first = original call
p.second = second call
 
P

Pascal J. Bourguignon

Lionel B said:
How about simply:

double fprime( Parameters& p )
{
const double y = f(p);
const p3type p3save = p.p3;
p.p3 += epsilon;
const double yup = f(p);
p.p3 = p3save;
return (yup-y)/epsilon;
}

Not ideal - you lose const-ness of your parameter - but workable.

You would have to protect against exceptions:

template <class Cleanup>
class Unwinder{
private:
Cleanup& cleanup;
public:
Unwinder(Cleanup& aCleanup):cleanup(aCleanup){};
~Unwinder(){ cleanup(); }
};

#include <boost/bind.hpp>

double fprime( Parameters& p )
{
const double y = f(p);
const p3type p3save = p.p3;
{
Unwinder u(boost::bind(&Parameters::setP3,p,p3,p3save));
p.p3 += epsilon;
const double yup = f(p);
}
return (yup-y)/epsilon;
}

And it doesn't work when several threads use p at the same time...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,417
Latest member
DarrenGaun

Latest Threads

Top