public override void update() { sectionHelpers_.Clear(); if (size_ == 2) //single period { ISectionHelper singleHelper = new EverywhereConstantHelper(yBegin_[1], 0.0, xBegin_[0]); sectionHelpers_.Add(xBegin_[1], singleHelper); extrapolationHelper_ = singleHelper; return; } List <double> f = new InitializedList <double>(size_); sectionHelpers_ = new Dictionary <double, ISectionHelper>(preSectionHelpers_); int startPoint = sectionHelpers_.Count + 1; //first derive the boundary forwards. for (int i = startPoint; i < size_ - 1; ++i) { double dxPrev = xBegin_[i] - xBegin_[i - 1]; double dx = xBegin_[i + 1] - xBegin_[i]; f[i] = dxPrev / (dx + dxPrev) * yBegin_[i] + dx / (dx + dxPrev) * yBegin_[i + 1]; } if (startPoint > 1) { f[startPoint - 1] = preSectionHelpers_.Last().Value.fNext(); } if (startPoint == 1) { f[0] = 1.5 * yBegin_[1] - 0.5 * f[1]; } f[size_ - 1] = 1.5 * yBegin_[size_ - 1] - 0.5 * f[size_ - 2]; if (forcePositive_) { if (f[0] < 0) { f[0] = 0.0; } if (f[size_ - 1] < 0.0) { f[size_ - 1] = 0.0; } } double primitive = 0.0; for (int i = 0; i < startPoint - 1; ++i) { primitive += yBegin_[i + 1] * (xBegin_[i + 1] - xBegin_[i]); } int endPoint = size_; //constantLastPeriod_ = false; if (constantLastPeriod_) { endPoint = endPoint - 1; } for (int i = startPoint; i < endPoint; ++i) { double gPrev = f[i - 1] - yBegin_[i]; double gNext = f[i] - yBegin_[i]; //first deal with the zero gradient case if (Math.Abs(gPrev) < 1.0E-14 && Math.Abs(gNext) < 1.0E-14) { ISectionHelper singleHelper = new ConstantGradHelper(f[i - 1], primitive, xBegin_[i - 1], xBegin_[i], f[i]); sectionHelpers_.Add(xBegin_[i], singleHelper); } else { double quadraticity = quadraticity_; ISectionHelper quadraticHelper = null; ISectionHelper convMonotoneHelper = null; if (quadraticity_ > 0.0) { if (gPrev >= -2.0 * gNext && gPrev > -0.5 * gNext && forcePositive_) { quadraticHelper = new QuadraticMinHelper(xBegin_[i - 1], xBegin_[i], f[i - 1], f[i], yBegin_[i], primitive); } else { quadraticHelper = new QuadraticHelper(xBegin_[i - 1], xBegin_[i], f[i - 1], f[i], yBegin_[i], primitive); } } if (quadraticity_ < 1.0) { if ((gPrev > 0.0 && -0.5 * gPrev >= gNext && gNext >= -2.0 * gPrev) || (gPrev < 0.0 && -0.5 * gPrev <= gNext && gNext <= -2.0 * gPrev)) { quadraticity = 1.0; if (quadraticity_ == 0) { if (forcePositive_) { quadraticHelper = new QuadraticMinHelper( xBegin_[i - 1], xBegin_[i], f[i - 1], f[i], yBegin_[i], primitive); } else { quadraticHelper = new QuadraticHelper( xBegin_[i - 1], xBegin_[i], f[i - 1], f[i], yBegin_[i], primitive); } } } else if ((gPrev < 0.0 && gNext > -2.0 * gPrev) || (gPrev > 0.0 && gNext < -2.0 * gPrev)) { double eta = (gNext + 2.0 * gPrev) / (gNext - gPrev); double b2 = (1.0 + monotonicity_) / 2.0; if (eta < b2) { convMonotoneHelper = new ConvexMonotone2Helper( xBegin_[i - 1], xBegin_[i], gPrev, gNext, yBegin_[i], eta, primitive); } else { if (forcePositive_) { convMonotoneHelper = new ConvexMonotone4MinHelper( xBegin_[i - 1], xBegin_[i], gPrev, gNext, yBegin_[i], b2, primitive); } else { convMonotoneHelper = new ConvexMonotone4Helper( xBegin_[i - 1], xBegin_[i], gPrev, gNext, yBegin_[i], b2, primitive); } } } else if ((gPrev > 0.0 && gNext < 0.0 && gNext > -0.5 * gPrev) || (gPrev < 0.0 && gNext > 0.0 && gNext < -0.5 * gPrev)) { double eta = gNext / (gNext - gPrev) * 3.0; double b3 = (1.0 - monotonicity_) / 2.0; if (eta > b3) { convMonotoneHelper = new ConvexMonotone3Helper( xBegin_[i - 1], xBegin_[i], gPrev, gNext, yBegin_[i], eta, primitive); } else { if (forcePositive_) { convMonotoneHelper = new ConvexMonotone4MinHelper( xBegin_[i - 1], xBegin_[i], gPrev, gNext, yBegin_[i], b3, primitive); } else { convMonotoneHelper = new ConvexMonotone4Helper( xBegin_[i - 1], xBegin_[i], gPrev, gNext, yBegin_[i], b3, primitive); } } } else { double eta = gNext / (gPrev + gNext); double b2 = (1.0 + monotonicity_) / 2.0; double b3 = (1.0 - monotonicity_) / 2.0; if (eta > b2) { eta = b2; } if (eta < b3) { eta = b3; } if (forcePositive_) { convMonotoneHelper = new ConvexMonotone4MinHelper( xBegin_[i - 1], xBegin_[i], gPrev, gNext, yBegin_[i], eta, primitive); } else { convMonotoneHelper = new ConvexMonotone4Helper( xBegin_[i - 1], xBegin_[i], gPrev, gNext, yBegin_[i], eta, primitive); } } } if (quadraticity == 1.0) { sectionHelpers_.Add(xBegin_[i], quadraticHelper); } else if (quadraticity == 0.0) { sectionHelpers_.Add(xBegin_[i], convMonotoneHelper); } else { sectionHelpers_.Add(xBegin_[i], new ComboHelper(quadraticHelper, convMonotoneHelper, quadraticity)); } } primitive += yBegin_[i] * (xBegin_[i] - xBegin_[i - 1]); } if (constantLastPeriod_) { sectionHelpers_.Add(xBegin_[size_ - 1], new EverywhereConstantHelper(yBegin_[size_ - 1], primitive, xBegin_[size_ - 2])); extrapolationHelper_ = sectionHelpers_[xBegin_[size_ - 1]]; } else { extrapolationHelper_ = new EverywhereConstantHelper((sectionHelpers_.Last()).Value.value(xBegin_.Last()), primitive, xBegin_.Last()); } }
public override void update() { sectionHelpers_.Clear(); if (size_ == 2) { //single period ISectionHelper singleHelper = new EverywhereConstantHelper(yBegin_[1], 0.0, xBegin_[0]); sectionHelpers_.Add(xBegin_[1], singleHelper); extrapolationHelper_ = singleHelper; return; } List<double> f = new InitializedList<double>(size_); sectionHelpers_ = new Dictionary<double,ISectionHelper>(preSectionHelpers_); int startPoint = sectionHelpers_.Count+1; //first derive the boundary forwards. for (int i=startPoint; i<size_-1; ++i) { double dxPrev = xBegin_[i] - xBegin_[i-1]; double dx = xBegin_[i+1] - xBegin_[i]; f[i] = dxPrev/(dx+dxPrev) * yBegin_[i] + dx/(dx+dxPrev) * yBegin_[i+1]; } if (startPoint > 1) f[startPoint-1] = preSectionHelpers_.Last().Value.fNext(); if (startPoint == 1) f[0] = 1.5 * yBegin_[1] - 0.5 * f[1]; f[size_-1] = 1.5 * yBegin_[size_-1] - 0.5 * f[size_-2]; if (forcePositive_) { if (f[0] < 0) f[0] = 0.0; if (f[size_-1] < 0.0) f[size_-1] = 0.0; } double primitive = 0.0; for (int i = 0; i < startPoint-1; ++i) primitive += yBegin_[i+1] * (xBegin_[i+1]-xBegin_[i]); int endPoint = size_; //constantLastPeriod_ = false; if (constantLastPeriod_) endPoint = endPoint-1; for (int i=startPoint; i< endPoint; ++i) { double gPrev = f[i-1] - yBegin_[i]; double gNext = f[i] - yBegin_[i]; //first deal with the zero gradient case if ( Math.Abs(gPrev) < 1.0E-14 && Math.Abs(gNext) < 1.0E-14 ) { ISectionHelper singleHelper = new ConstantGradHelper(f[i - 1], primitive, xBegin_[i-1], xBegin_[i], f[i]); sectionHelpers_.Add(xBegin_[i], singleHelper); } else { double quadraticity = quadraticity_; ISectionHelper quadraticHelper = null; ISectionHelper convMonotoneHelper = null; if (quadraticity_ > 0.0) { if (gPrev >= -2.0*gNext && gPrev > -0.5*gNext && forcePositive_) { quadraticHelper = new QuadraticMinHelper(xBegin_[i-1], xBegin_[i], f[i-1], f[i], yBegin_[i], primitive); } else { quadraticHelper = new QuadraticHelper(xBegin_[i-1], xBegin_[i], f[i-1], f[i], yBegin_[i], primitive); } } if (quadraticity_ < 1.0) { if ((gPrev > 0.0 && -0.5*gPrev >= gNext && gNext >= -2.0*gPrev) || (gPrev < 0.0 && -0.5*gPrev <= gNext && gNext <= -2.0*gPrev)) { quadraticity = 1.0; if (quadraticity_ == 0) { if (forcePositive_) { quadraticHelper = new QuadraticMinHelper( xBegin_[i-1], xBegin_[i], f[i-1], f[i], yBegin_[i], primitive); } else { quadraticHelper = new QuadraticHelper( xBegin_[i-1], xBegin_[i], f[i-1], f[i], yBegin_[i], primitive); } } } else if ( (gPrev < 0.0 && gNext > -2.0*gPrev) || (gPrev > 0.0 && gNext < -2.0*gPrev)) { double eta = (gNext + 2.0*gPrev)/(gNext - gPrev); double b2 = (1.0 + monotonicity_)/2.0; if (eta < b2) { convMonotoneHelper = new ConvexMonotone2Helper( xBegin_[i-1], xBegin_[i], gPrev, gNext, yBegin_[i], eta, primitive); } else { if (forcePositive_) { convMonotoneHelper = new ConvexMonotone4MinHelper( xBegin_[i-1], xBegin_[i], gPrev, gNext, yBegin_[i], b2, primitive); } else { convMonotoneHelper = new ConvexMonotone4Helper( xBegin_[i-1], xBegin_[i], gPrev, gNext, yBegin_[i], b2, primitive); } } } else if ( (gPrev > 0.0 && gNext < 0.0 && gNext > -0.5*gPrev) || (gPrev < 0.0 && gNext > 0.0 && gNext < -0.5*gPrev) ) { double eta = gNext/(gNext-gPrev) * 3.0; double b3 = (1.0 - monotonicity_) / 2.0; if (eta > b3) { convMonotoneHelper = new ConvexMonotone3Helper( xBegin_[i-1], xBegin_[i], gPrev, gNext, yBegin_[i], eta, primitive); } else { if (forcePositive_) { convMonotoneHelper = new ConvexMonotone4MinHelper( xBegin_[i-1], xBegin_[i], gPrev, gNext, yBegin_[i], b3, primitive); } else { convMonotoneHelper = new ConvexMonotone4Helper( xBegin_[i-1], xBegin_[i], gPrev, gNext, yBegin_[i], b3, primitive); } } } else { double eta = gNext/(gPrev + gNext); double b2 = (1.0 + monotonicity_) / 2.0; double b3 = (1.0 - monotonicity_) / 2.0; if (eta > b2) eta = b2; if (eta < b3) eta = b3; if (forcePositive_) { convMonotoneHelper = new ConvexMonotone4MinHelper( xBegin_[i-1], xBegin_[i], gPrev, gNext, yBegin_[i], eta, primitive); } else { convMonotoneHelper = new ConvexMonotone4Helper( xBegin_[i-1], xBegin_[i], gPrev, gNext, yBegin_[i], eta, primitive); } } } if (quadraticity == 1.0) { sectionHelpers_.Add(xBegin_[i], quadraticHelper); } else if (quadraticity == 0.0) { sectionHelpers_.Add(xBegin_[i], convMonotoneHelper); } else { sectionHelpers_.Add(xBegin_[i], new ComboHelper(quadraticHelper, convMonotoneHelper, quadraticity)); } } primitive += yBegin_[i] * (xBegin_[i]-xBegin_[i-1]); } if (constantLastPeriod_) { sectionHelpers_.Add(xBegin_[size_-1], new EverywhereConstantHelper(yBegin_[size_-1], primitive, xBegin_[size_-2])); extrapolationHelper_ = sectionHelpers_[xBegin_[size_-1]]; } else { extrapolationHelper_ = new EverywhereConstantHelper((sectionHelpers_.Last()).Value.value(xBegin_.Last()), primitive, xBegin_.Last()); } }