-
Notifications
You must be signed in to change notification settings - Fork 176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Design flaw in how polymorphism and generics work #89
Comments
I still have to commit my new branch with the default curves, but even without it, the problem exists in the yield curves too. We're just lucky the tests pass. |
The real problem for us is that PiecewiseYieldCurve in c++ is derived from a template parameter typedef : template <class Traits, class Interpolator, template <class> class Bootstrap = IterativeBootstrap>
class PiecewiseYieldCurve : public Traits::template curve<Interpolator>::type so base_curve::discountImpl(t); This is impossible to do in c#, so during the years we tried to make a configuration that works in most cases . Several people worked on this but still we don't have a clean solution. |
Well, yes, that's what I was also trying to say. ;-) I'll start reducing the problem so that it's easier to look for alternative solutions. |
Hang on, I'm still working on this... |
Hello, I will try to help a bit but you may have notice I'm not such a good coder. In QLNet the design of the different Traits does not seems to be as in Quantlib and honestly I do not understand why. For example this part isn't "translated" to C#:
I know @igitur does not really like this but it seems that the following sample can replace easily this code:
Then it's becoming quite easy to instatiate within PieceYieldCurve the base_curve object:
will become
With previously declared Then we need to update the discountImpl:
Until here I get it working, but now I need to update the base_curve with bootstrap helpers when calculate() method is called. If you have any suggestion ? |
Well, yes, I don't like using Reflection for a few reasons:
But I have admit that I've also thought that Reflection is going to be our only solution here. I don't think C#'s generics are advanced enough yet. Higher kinded generics might be a solution if it is implemented in C# one day. I'm not sure. |
How much slower is it ? Personally I use the PiecewiseCurves only for bootstrapping once and then I'm using directly the InterpolatedCurves with calculated ZeroRates. So the growth in calculation time will barely impact me. Your issue is almost a year old, I think it's time to correct this (which is quite alarming as the behaviour is totally different from official Quantlib). Starting with reflection now should help once the feature is available in C# and should not be too troublesome to migrate. @amaggiulli seems to disaprove use of external library, so I think we know what is left to do. |
Let me just complete that reduced example first and get some feedback from StackOverflow. There might be a few gurus there would could give advice. We should at least be 100% sure that there is no way that generics can work. If generics are ruled out, then, besides reflection, we should also investigate lambda expressions. I don't know them well, but I have a hunch that might be a solution. And they're much faster than reflection. To answer your question, Reflection is a lot slower, and here is a post that explains why. |
The right way to solve this is with Interfaces , reflection is not needed ( and it is to avoid if possible ), we don't need a guru , just some time to dedicate to this development and , like all the open source projects , this can't be planned with certainty. |
Well, I will probably leave that to you as I have no idea how to do it with
interfaces.
Regarding the reflection, my proposal was just using it to instatiate the
object, all methods are then called by the usual way. I don't think it is
impacting the time calculation like in the exemple given by @igitur.
If I can be of any help, tell me I have a bit of the needed time.
Le 5 mai 2017 14:14, "Andrea Maggiulli" <[email protected]> a écrit :
… The right way to solve this is with Interfaces , reflection is not needed
( and it is to avoid if possible ), we don't need a guru , just some time
to dedicate to this development and , like all the open source projects ,
this can't be planned with certainty.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#89 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AXZfhJJdo-xEad06t7TJt--fIHA-CENyks5r2xK4gaJpZM4Ip5mn>
.
|
work at this issue in branch https://github.com/amaggiulli/QLNet/tree/generics |
Hello, Did you had a look at this branch : https://github.com/tournierjc/QLNet/tree/ITraitsRefactoring? |
@tournierjc With #196 merged, you can rebase and your unit tests should pass now. |
@tournierjc Can you log a PR for it in the meantime? |
Hi, I'm also having a hard time implementing the PiecewiseDefaultCurve. Any updates on solving this issue using interfaces? |
Hello @andeen , I have implemented it in my repos (defaultcurve branch): https://github.com/tournierjc/QLNet/tree/defaultcurves I'm using it on a daily basis, it's working great. |
That's just perfect, tournierjc. Thanks! What's the status on the pull request? |
@andeen the previous pull request has been closed without merging. I will make another one. |
I'm not sure whether this is a major problem, but I struggled for a long time and couldn't solve it. I'm trying to implement the default probability curves. The design pattern is similar in how the yield term structures work.
To illustrate the problem, look at the
testLinearDiscountConsistency
test. It uses aPiecewiseYieldCurve
to build a curve and interpolates theDiscount
curve usingLinear
interpolator. When the interpolation occurs, this piece of the codebase is executed:In QuantLib:
The
discountImpl
that is executed is thenInterpolatedDiscountCurve<T>::discountImpl
:What happens in QLNet is this. In
PiecewiseYieldCurve
:But
_traits
is defined as theDiscount
class, notInterpolatedDiscountCurve
as in QuantLib and the code that is then executed is:This is because of the difference in how the generics and polymorphism work. We are "lucky" in the sense that
InterpolatedDiscountCurve.discountImpl
andDiscount.discountImpl
do almost the same thing and that is why the tests pass.When I started implementing the Default Curves, I noticed the same problem, except we aren't so lucky anymore. Refer to the
testLinearDensityConsistency
, which is very similar to the discount curve test I discussed above. The test wants to calculate a swap fair value and in doing so, needs the survival probability. In QuantLib:PiecewiseDefaultCurve::survivalProbabilityImpl
would callInterpolatedDefaultDensityCurve<T>::survivalProbabilityImpl
. But in QLNet,PiecewiseDefaultCurve.survivalProbabilityImpl
would callDefaultDensity.survivalProbabilityImpl
:And then the test fails. There must be a way to make the call to
InterpolatedDefaultDensityCurve
instead ofDefaultDensity
, but I can't figure how how. C++ has typenames and typedefs which help here, but that's not possible in C#. Maybe there is a solution using reflection?The text was updated successfully, but these errors were encountered: