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 second I.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 better to leave the construction of the data separate from the data itself. Best regards, Chris ------------------------------------------------------------------------- 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 [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-dev |
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 > ------------------------------------------------------------------------- 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 [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-dev |
On Wed, 2008-03-19 at 15:28 +0000, Oleg Burundukov wrote:
> > 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 second [...] 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. > > > 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. Hi Oleg, just for the sake of clarity: level 1 is already observable. What level 3 adds is lazy calculation. > 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. Unfortunately, the level 2 classes are all different. Each of the curves implements a different interface. InterpolatedDiscountCurve implements the abstract discountImpl() method in YieldTermStructure; InterpolatedZeroCurve implements zeroImpl() from the ZeroStructure adapter; and InterpolatedForwardCurve implements forwardImpl() from the ForwardStructure adapter. The inflation and credit curves implement other interfaces. > 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? I was under the impression that the base curve(s) and the bootstrap were pretty much decoupled already---the generic bootstrap class does the filling for all curves, and the piecewise curves are only a thin layer over level 2 that call the bootstrap instance. Having the bootstrap as an external instance (as opposed to a data member) doesn't give us much of an advantage---especially since the curve would then have to register with the bootstrapper, and thus store it as a data member implicitly. > 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. Here we agree completely. It is indeed possible to create a generic InterpolatedCurve<Interpolation> class that stores the data and the methods to manipulate them, and that the interpolated curves can inherit from. Unfortunately, we'd still need all level 2 curves because they have to implement different interfaces; but their common code would be written just once in InterpolatedCurve. I'd be happy to include the class in the library. > 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. It's not only observability---it's also laziness. But let's start with observability. Let's say the bootstrap is an external object and stores the helpers itself. We instantiate it, we ask it to create a curve, and pass the curve to an instrument. The instrument has to be notified when the value of a helper quote changes. Also, the instrument should not know that a bootstrap is involved; it only knows it holds a YieldTermStructure instance. This means that either: a) the term structure registers as an observer of the bootstrap, and asks the bootstrap to redo its magic when needed. But this requires the curve to store the bootstrap, so I guess this isn't what you had in mind. b) the bootstrap observes the helpers, and makes sure the curve is up to date whenever they change by performing the calculation. However, this causes us to lose laziness. If the curve is based on, say, ten helpers, and we want to change the value of all ten, this implementation would cause 10 bootstrap to be performed, nine of which we didn't need---only the final one gives us the result we wanted. In the current implementation, instead, setting the ten values just flips a boolean flag, and only one bootstrap is performed when we ask the curve for data. (Incidentally, we could already remove all the calculate() calls by calling it just once inside the curve update() method. But we would have the same issue with the ten bootstraps.) Later, Luigi -- Flon's Law: There is not now, and never will be, a language in which it is the least bit difficult to write bad programs. ------------------------------------------------------------------------- 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 [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-dev |
Free forum by Nabble | Edit this page |