Is this design ok?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Is this design ok?

Peter Caspers-2
Hello Luigi,

I want to add a new model to the lib. The model observes a yield term
structure and a volatility structure. Whenever one of them changes a
method update1() shall be called. Furthermore the model has a (piecewise
constant) parameter that can be calibrated to additional instruments.
When this parameter changes, another method update2() should be called.
In fact, update1() calls update2(). Both methods update1() and update2()
need some computation time, so in particular during calibration
update1() should _not_ be called. Finally, the model should be a
LazyObject, because multiple changes in market data (say a parallel
shift in the volatility surface) should trigger only one call of update1().

I think I have a solution, but I want to learn a bit about the libs
design and I want to be sure to be in line with this design and not have
overseen something. So could you please have a look?

My first attempt was the following: Let the model inherit from
TermstructureConsistentModel, CalibratedModel and LazyObject. However,
when calling registerWith(myYts's), this registration is ambiguous
because both LazyObject and CalibratedModel derive from Observer, but in
the case of CalibratedModel this is no virtual inheritance. So my first
question would be: Is there a special reason for that or could the
declaration also be CalibratedModel : public virtual Observer, ... ?
Given I would change that, I need to overwrite the update() method in my
model then basically calling LazyObject::update(). The
performCalculations() implementation in my model would call update1()
and update2().

The next problem occurs in the setParams() method of CalibratedModel
which calls update() at the end, causing full recalculation (i.e. calls
of update1() and update2()) of the model, which I wanted to avoid. My
interpretation of the purpose of generateArguments() up to now was to
update the model w.r.t. changes in its parameters. So a call of
generateArguments() and notifyObservers() instead of update() in the
setParams() method would be enough (and produce the desired behaviour in
my case). The implementation of generateArguments() in my model would
then simply call update2(). In fact, a call of setParams() would
instantaneously trigger a call of update2(), which would not be
consistent with the lazy behaviour of the model w.r.t. market data
changes, but this is no serious problem I guess.

Summarizing my questions:

1. Why is CalibratedModel derived from Observer as "public" and not
"public virtual" ?
2. Why is update() and not generateArguments(); notifyObservers();
called in CalibratedModel::setParams() ?

The solution I actually arrived at (requiring no adjustments in the lib)
is the following:

- Use LazyObject::registerWith(myYts's), i.e. only let the Observer of
LazyObject observe the term structures and not the observers copy in
CalibratedModel.
- Do not implement an update() method in my model.
- Implement performCalculations() and generateArguments() just as
described above.

Is this latter way correct ?

Thanks a lot
Peter



------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
_______________________________________________
QuantLib-dev mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-dev
Reply | Threaded
Open this post in threaded view
|

Re: Is this design ok?

Luigi Ballabio
Hi Peter,
    apologies for the delay.

> 1. Why is CalibratedModel derived from Observer as "public" and not
> "public virtual" ?

It's probably an oversight.  Try changing it and running the test
suite; if it works, give me a shout and I'll correct it.

> 2. Why is update() and not generateArguments(); notifyObservers();
> called in CalibratedModel::setParams() ?

It might just be that whoever wrote the call didn't think that
update() could be extended.
On the other hand, it's been a while since I looked at that part of
the library, and I'm not sure that one wouldn't want the model to
update fully when parameters are set... Hmm. Again, you might try to
make the change and see what happens.

Another possibility is that you decouple the two updates entirely.
You might call update2 code from the model's update() method, and
manage update1() by using another observer. Something like:

class YourModel {
  private:
    class updateHelper : public Observer {
      public:
        updateHelper(YourModel* model) : model(model) {}
        void update() { model->update1(); }
    };
    ...
    updateHelper uh;
  public:
    YourModel(whatever) : uh(this) {
        this->registerWith(a);  // triggers update2()
        this->registerWith(b);  // triggers update2()...
        uh->registerWith(b);   // ...and also update1()
    }
};

The problem is, it's not guaranteed in what order update1() and
update2() will be called, which might be a showstopper for you.

In any case, let me know how it goes.

Later,
    Luigi


On Sun, Jan 29, 2012 at 6:09 PM, Peter Caspers <[hidden email]> wrote:

> Hello Luigi,
>
> I want to add a new model to the lib. The model observes a yield term
> structure and a volatility structure. Whenever one of them changes a
> method update1() shall be called. Furthermore the model has a (piecewise
> constant) parameter that can be calibrated to additional instruments.
> When this parameter changes, another method update2() should be called.
> In fact, update1() calls update2(). Both methods update1() and update2()
> need some computation time, so in particular during calibration
> update1() should _not_ be called. Finally, the model should be a
> LazyObject, because multiple changes in market data (say a parallel
> shift in the volatility surface) should trigger only one call of update1().
>
> I think I have a solution, but I want to learn a bit about the libs
> design and I want to be sure to be in line with this design and not have
> overseen something. So could you please have a look?
>
> My first attempt was the following: Let the model inherit from
> TermstructureConsistentModel, CalibratedModel and LazyObject. However,
> when calling registerWith(myYts's), this registration is ambiguous
> because both LazyObject and CalibratedModel derive from Observer, but in
> the case of CalibratedModel this is no virtual inheritance. So my first
> question would be: Is there a special reason for that or could the
> declaration also be CalibratedModel : public virtual Observer, ... ?
> Given I would change that, I need to overwrite the update() method in my
> model then basically calling LazyObject::update(). The
> performCalculations() implementation in my model would call update1()
> and update2().
>
> The next problem occurs in the setParams() method of CalibratedModel
> which calls update() at the end, causing full recalculation (i.e. calls
> of update1() and update2()) of the model, which I wanted to avoid. My
> interpretation of the purpose of generateArguments() up to now was to
> update the model w.r.t. changes in its parameters. So a call of
> generateArguments() and notifyObservers() instead of update() in the
> setParams() method would be enough (and produce the desired behaviour in
> my case). The implementation of generateArguments() in my model would
> then simply call update2(). In fact, a call of setParams() would
> instantaneously trigger a call of update2(), which would not be
> consistent with the lazy behaviour of the model w.r.t. market data
> changes, but this is no serious problem I guess.
>
> Summarizing my questions:
>
> 1. Why is CalibratedModel derived from Observer as "public" and not
> "public virtual" ?
> 2. Why is update() and not generateArguments(); notifyObservers();
> called in CalibratedModel::setParams() ?
>
> The solution I actually arrived at (requiring no adjustments in the lib)
> is the following:
>
> - Use LazyObject::registerWith(myYts's), i.e. only let the Observer of
> LazyObject observe the term structures and not the observers copy in
> CalibratedModel.
> - Do not implement an update() method in my model.
> - Implement performCalculations() and generateArguments() just as
> described above.
>
> Is this latter way correct ?
>
> Thanks a lot
> Peter
>
>
>
> ------------------------------------------------------------------------------
> Try before you buy = See our experts in action!
> The most comprehensive online learning library for Microsoft developers
> is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
> Metro Style Apps, more. Free future releases when you subscribe now!
> http://p.sf.net/sfu/learndevnow-dev2
> _______________________________________________
> QuantLib-dev mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/quantlib-dev

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
QuantLib-dev mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-dev
Reply | Threaded
Open this post in threaded view
|

Re: Is this design ok?

Peter Caspers-2
Hi Luigi,

thank you for your answer. The test suite runs fine with both changes.

The order in which update1() and update2() are called is in fact
crucial. The model is a markov functional one factor model. update1()
precomputes arbitrage free smiles from a given volatility structure.
update2() bootstraps a numeraire surface fitting these smiles. So
update1() only depends on the market data input, while update2() in
addition depends on the model parameters, i.e. the parameters describing
the driving state process.

I would apreciate to have both changes in the code, if no one has second
thoughts.

Thanks again,
Peter


Am 07.02.2012 14:59, schrieb Luigi Ballabio:

> Hi Peter,
>      apologies for the delay.
>
>> 1. Why is CalibratedModel derived from Observer as "public" and not
>> "public virtual" ?
> It's probably an oversight.  Try changing it and running the test
> suite; if it works, give me a shout and I'll correct it.
>
>> 2. Why is update() and not generateArguments(); notifyObservers();
>> called in CalibratedModel::setParams() ?
> It might just be that whoever wrote the call didn't think that
> update() could be extended.
> On the other hand, it's been a while since I looked at that part of
> the library, and I'm not sure that one wouldn't want the model to
> update fully when parameters are set... Hmm. Again, you might try to
> make the change and see what happens.
>
> Another possibility is that you decouple the two updates entirely.
> You might call update2 code from the model's update() method, and
> manage update1() by using another observer. Something like:
>
> class YourModel {
>    private:
>      class updateHelper : public Observer {
>        public:
>          updateHelper(YourModel* model) : model(model) {}
>          void update() { model->update1(); }
>      };
>      ...
>      updateHelper uh;
>    public:
>      YourModel(whatever) : uh(this) {
>          this->registerWith(a);  // triggers update2()
>          this->registerWith(b);  // triggers update2()...
>          uh->registerWith(b);   // ...and also update1()
>      }
> };
>
> The problem is, it's not guaranteed in what order update1() and
> update2() will be called, which might be a showstopper for you.
>
> In any case, let me know how it goes.
>
> Later,
>      Luigi
>
>
> On Sun, Jan 29, 2012 at 6:09 PM, Peter Caspers<[hidden email]>  wrote:
>> Hello Luigi,
>>
>> I want to add a new model to the lib. The model observes a yield term
>> structure and a volatility structure. Whenever one of them changes a
>> method update1() shall be called. Furthermore the model has a (piecewise
>> constant) parameter that can be calibrated to additional instruments.
>> When this parameter changes, another method update2() should be called.
>> In fact, update1() calls update2(). Both methods update1() and update2()
>> need some computation time, so in particular during calibration
>> update1() should _not_ be called. Finally, the model should be a
>> LazyObject, because multiple changes in market data (say a parallel
>> shift in the volatility surface) should trigger only one call of update1().
>>
>> I think I have a solution, but I want to learn a bit about the libs
>> design and I want to be sure to be in line with this design and not have
>> overseen something. So could you please have a look?
>>
>> My first attempt was the following: Let the model inherit from
>> TermstructureConsistentModel, CalibratedModel and LazyObject. However,
>> when calling registerWith(myYts's), this registration is ambiguous
>> because both LazyObject and CalibratedModel derive from Observer, but in
>> the case of CalibratedModel this is no virtual inheritance. So my first
>> question would be: Is there a special reason for that or could the
>> declaration also be CalibratedModel : public virtual Observer, ... ?
>> Given I would change that, I need to overwrite the update() method in my
>> model then basically calling LazyObject::update(). The
>> performCalculations() implementation in my model would call update1()
>> and update2().
>>
>> The next problem occurs in the setParams() method of CalibratedModel
>> which calls update() at the end, causing full recalculation (i.e. calls
>> of update1() and update2()) of the model, which I wanted to avoid. My
>> interpretation of the purpose of generateArguments() up to now was to
>> update the model w.r.t. changes in its parameters. So a call of
>> generateArguments() and notifyObservers() instead of update() in the
>> setParams() method would be enough (and produce the desired behaviour in
>> my case). The implementation of generateArguments() in my model would
>> then simply call update2(). In fact, a call of setParams() would
>> instantaneously trigger a call of update2(), which would not be
>> consistent with the lazy behaviour of the model w.r.t. market data
>> changes, but this is no serious problem I guess.
>>
>> Summarizing my questions:
>>
>> 1. Why is CalibratedModel derived from Observer as "public" and not
>> "public virtual" ?
>> 2. Why is update() and not generateArguments(); notifyObservers();
>> called in CalibratedModel::setParams() ?
>>
>> The solution I actually arrived at (requiring no adjustments in the lib)
>> is the following:
>>
>> - Use LazyObject::registerWith(myYts's), i.e. only let the Observer of
>> LazyObject observe the term structures and not the observers copy in
>> CalibratedModel.
>> - Do not implement an update() method in my model.
>> - Implement performCalculations() and generateArguments() just as
>> described above.
>>
>> Is this latter way correct ?
>>
>> Thanks a lot
>> Peter
>>
>>
>>
>> ------------------------------------------------------------------------------
>> Try before you buy = See our experts in action!
>> The most comprehensive online learning library for Microsoft developers
>> is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
>> Metro Style Apps, more. Free future releases when you subscribe now!
>> http://p.sf.net/sfu/learndevnow-dev2
>> _______________________________________________
>> QuantLib-dev mailing list
>> [hidden email]
>> https://lists.sourceforge.net/lists/listinfo/quantlib-dev


------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
QuantLib-dev mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-dev