|
From: Oleg B. <ole...@nl...> - 2008-03-19 15:28:27
|
Chris Kenyon <chris.kenyon <at> yahoo.com> writes: > > Hi Oleg, & list,both of the first two layers are really interfaces:- the first says what you get- the second (interpolated) says that if you already know the answer here is what you get, as you say a data representation.- the third layer says how to build something on the secondI.e. the third layer is a specific way to construct an interpolated whatever. I would argue (am arguing ) against combining levels two and three because combining them would force the second layer (interpolated) to be made in a certain way from a certain set of input data. As a design point I think that it's b > etter to leave the construction of the data separate from the data itself. Best regards,Chris Hi Chris, I agree with you and the idea to separate level 2 and level 3. Although , ways to do this may differ. It would be nice to discuss which is the best. [However, what I propose may require too large volume of changes.] For sake of clarity let's postulate following: Level 2 comprises of static data and collateral methods, all but bootstrapping. It also _implements_ what level 1 defines, therefore instances of level2 are creatable. Level 3 subclasses level2, aggregates the bootstrap and makes curve observable. Should one level 2 be different from another , if _implementation_ is somewhere outside ? Not likely. Data containers and all manipulations with them seem to be copied from class to class. Should level 3 be a subclass of level 2? What if bootstrap is just another object, the observer linked to instrument helpers? Then , the curve is essentially level2, with _implementation_ and data arrays has been filled up by extern bootstrap. We pay for having another instance, bootstrap, in the program. But does not this decouple bare curve and its bootstrap? What prevents us from separating bootstrap and curve? Bootstrap uses very limited set of operations to modify curve points. Basically, these are: reset (size), add(time, value), set(index, value). All these interpolator->update() look redundant, because we should assume that the bare curve knows about how to update its interpolator _better_ than bootstrap does. So we can decouple them to having just a common interface, e.g. CurveBuildStrategy. What keeps bootsrapper inside the level 3 _now_ is observability, namely, the issue with calling calculate() inside every member. Since bootstrap is separate, curve has to be able to wake it. It can be done surprisingly simple. OK, let's see what we get here: the TCurve<xxxStructure, yyyInterpolator> class, with constructors: template<class T1,class T2> TCurve(T1 begin, T1 end, T2 vbegin,...) // static data TCurve(refDate,...); // dynamic data and here is TCurveBuilder<Curve,Traits> with constructor TCurveBuilder(Curve &, instruments ) TCurve template lays down layer 2 for _all_ curves. One layer 3 class per curve type subclasses layer 2 as it did before, but now layer 3 is merely the _implementation_ (formerly presented in layer 2), and , at least , a pair of delegating constructors, one for static and one for dynamic. I can show inflation and credit risk curves implemented this way, and both classes look exactly as I said, interface + 2 constructors. Does this sound any better? Best regards, Oleg Burundukov, ABN AMRO > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > _______________________________________________ > QuantLib-dev mailing list > QuantLib-dev <at> lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/quantlib-dev > |