public void recalibration(List <Period> swapLengths, List <double> beta, Period swapTenor) { Utils.QL_REQUIRE(beta.Count == swapLengths.Count, () => "beta size (" + beta.Count + ") must be equal to number of swap lenghts (" + swapLengths.Count + ")"); List <double> betaTimes = new List <double>(); for (int i = 0; i < beta.Count; i++) { betaTimes.Add(timeFromReference(optionDateFromTenor(swapLengths[i]))); } LinearInterpolation betaInterpolation = new LinearInterpolation(betaTimes, betaTimes.Count, beta); List <double> cubeBeta = new List <double>(); for (int i = 0; i < optionTimes().Count; i++) { double t = optionTimes()[i]; // flat extrapolation ensures admissable values if (t < betaTimes.First()) { t = betaTimes.First(); } if (t > betaTimes.Last()) { t = betaTimes.Last(); } cubeBeta.Add(betaInterpolation.value(t)); } recalibration(cubeBeta, swapTenor); }
public void applyTo(object o, double t) { Vector a = (Vector)o; Vector aCopy = new Vector(a); int iterIndex = dividendTimes_.BinarySearch(t); if (iterIndex >= 0) { double dividend = dividends_[iterIndex]; if (mesher_.layout().dim().Count == 1) { LinearInterpolation interp = new LinearInterpolation(x_, x_.Count, aCopy); for (int k = 0; k < x_.size(); ++k) { a[k] = interp.value(Math.Max(x_[0], x_[k] - dividend), true); } } else { Vector tmp = new Vector(x_.size()); int xSpacing = mesher_.layout().spacing()[equityDirection_]; for (int i = 0; i < mesher_.layout().dim().Count; ++i) { if (i != equityDirection_) { int ySpacing = mesher_.layout().spacing()[i]; for (int j = 0; j < mesher_.layout().dim()[i]; ++j) { for (int k = 0; k < x_.size(); ++k) { int index = j * ySpacing + k * xSpacing; tmp[k] = aCopy[index]; } LinearInterpolation interp = new LinearInterpolation(x_, x_.Count, tmp); for (int k = 0; k < x_.size(); ++k) { int index = j * ySpacing + k * xSpacing; a[index] = interp.value( Math.Max(x_[0], x_[k] - dividend), true); } } } } } } }
protected override double volatilityImpl(double length, double strike) { calculate(); List <double> vol = new InitializedList <double>(nInterpolations_); for (int i = 0; i < nInterpolations_; ++i) { vol[i] = strikeInterpolations_[i].value(strike, true); } List <double> optionletTimes = new List <double>(optionletStripper_.optionletFixingTimes()); LinearInterpolation timeInterpolator = new LinearInterpolation(optionletTimes, optionletTimes.Count, vol); return(timeInterpolator.value(length, true)); }
public Concentrating1dMesher(double start, double end, int size, Pair <double?, double?> cPoints = null, bool requireCPoint = false) : base(size) { Utils.QL_REQUIRE(end > start, () => "end must be larger than start"); if (cPoints == null) { cPoints = new Pair <double?, double?>(); } double?cPoint = cPoints.first; double?density = cPoints.second == null ? null : cPoints.second * (end - start); Utils.QL_REQUIRE(cPoint == null || (cPoint >= start && cPoint <= end), () => "cPoint must be between start and end"); Utils.QL_REQUIRE(density == null || density > 0.0, () => "density > 0 required"); Utils.QL_REQUIRE(cPoint == null || density != null, () => "density must be given if cPoint is given"); Utils.QL_REQUIRE(!requireCPoint || cPoint != null, () => "cPoint is required in grid but not given"); double dx = 1.0 / (size - 1); if (cPoint != null) { List <double> u = new List <double>(); List <double> z = new List <double>(); Interpolation transform = null; double c1 = Utils.Asinh((start - cPoint.Value) / density.GetValueOrDefault()); double c2 = Utils.Asinh((end - cPoint.Value) / density.GetValueOrDefault()); if (requireCPoint) { u.Add(0.0); z.Add(0.0); if (!Utils.close(cPoint.Value, start) && !Utils.close(cPoint.Value, end)) { double z0 = -c1 / (c2 - c1); double u0 = Math.Max( Math.Min(Convert.ToInt32(z0 * (size - 1) + 0.5), Convert.ToInt32(size) - 2), 1) / (Convert.ToDouble(size - 1)); u.Add(u0); z.Add(z0); } u.Add(1.0); z.Add(1.0); transform = new LinearInterpolation(u, u.Count, z); } for (int i = 1; i < size - 1; ++i) { double li = requireCPoint ? transform.value(i * dx) : i * dx; locations_[i] = cPoint.Value + density.GetValueOrDefault() * Math.Sinh(c1 * (1.0 - li) + c2 * li); } } else { for (int i = 1; i < size - 1; ++i) { locations_[i] = start + i * dx * (end - start); } } locations_[0] = start; locations_[locations_.Count - 1] = end; for (int i = 0; i < size - 1; ++i) { dplus_[i] = dminus_[i + 1] = locations_[i + 1] - locations_[i]; } dplus_[dplus_.Count - 1] = null; dminus_[0] = null; }
public Concentrating1dMesher(double start, double end, int size, List <Tuple <double?, double?, bool> > cPoints, double tol = 1e-8) : base(size) { Utils.QL_REQUIRE(end > start, () => "end must be larger than start"); List <double?> points = new List <double?>(), betas = new List <double?>(); foreach (Tuple <double?, double?, bool> iter in cPoints) { points.Add(iter.Item1); betas.Add((iter.Item2 * (end - start)) * (iter.Item2 * (end - start))); } // get scaling factor a so that y(1) = end double aInit = 0.0; for (int i = 0; i < points.Count; ++i) { double c1 = Utils.Asinh((start - points[i].GetValueOrDefault()) / betas[i].GetValueOrDefault()); double c2 = Utils.Asinh((end - points[i].GetValueOrDefault()) / betas[i].GetValueOrDefault()); aInit += (c2 - c1) / points.Count; } OdeIntegrationFct fct = new OdeIntegrationFct(points, betas, tol); double a = new Brent().solve( new OdeSolver(fct, start, 0.0, 1.0, end), tol, aInit, 0.1 * aInit); // solve ODE for all grid points Vector x = new Vector(size), y = new Vector(size); x[0] = 0.0; y[0] = start; double dx = 1.0 / (size - 1); for (int i = 1; i < size; ++i) { x[i] = i * dx; y[i] = fct.solve(a, y[i - 1], x[i - 1], x[i]); } // eliminate numerical noise and ensure y(1) = end double dy = y[y.Count - 1] - end; for (int i = 1; i < size; ++i) { y[i] -= i * dx * dy; } LinearInterpolation odeSolution = new LinearInterpolation(x, x.Count, y); // ensure required points are part of the grid List <Pair <double?, double?> > w = new InitializedList <Pair <double?, double?> >(1, new Pair <double?, double?>(0.0, 0.0)); for (int i = 0; i < points.Count; ++i) { if (cPoints[i].Item3 && points[i] > start && points[i] < end) { int j = y.distance(y[0], y.BinarySearch(points[i].Value)); double e = new Brent().solve( new OdeSolver2(odeSolution.value, points[i].Value), Const.QL_EPSILON, x[j], 0.5 / size); w.Add(new Pair <double?, double?>(Math.Min(x[size - 2], x[j]), e)); } } w.Add(new Pair <double?, double?>(1.0, 1.0)); w = w.OrderBy(xx => xx.first).Distinct(new equal_on_first()).ToList(); List <double> u = new List <double>(w.Count), z = new List <double>(w.Count); for (int i = 0; i < w.Count; ++i) { u[i] = w[i].first.GetValueOrDefault(); z[i] = w[i].second.GetValueOrDefault(); } LinearInterpolation transform = new LinearInterpolation(u, u.Count, z); for (int i = 0; i < size; ++i) { locations_[i] = odeSolution.value(transform.value(i * dx)); } for (int i = 0; i < size - 1; ++i) { dplus_[i] = dminus_[i + 1] = locations_[i + 1] - locations_[i]; } dplus_[dplus_.Count] = null; dminus_[0] = null; }
private Interpolation put_imvolFitting() { List<double> xGrid = this.put_strikeData_; List<double> yGrid = this.put_imvolData_; //List<double> xGrid = Enumerable.Range(0, 100); LinearInterpolation cubic = new LinearInterpolation(xGrid, xGrid.Count, yGrid); return cubic; }
private Interpolation call_imvolFitting() { List<double> xGrid = this.call_strikeData_; List<double> yGrid = this.call_imvolData_; //List<double> xGrid = Enumerable.Range(0, 100); //LinearInterpolation cubic = new LinearInterpolation(xGrid, xGrid.Count, yGrid, // CubicInterpolation.DerivativeApprox.Kruger, true, // CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, // CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0); LinearInterpolation cubic = new LinearInterpolation(xGrid, xGrid.Count, yGrid); return cubic; }
public double k(double t, List <double> xBegin, int size) { LinearInterpolation li = new LinearInterpolation(xBegin, size, coeffs_.k_); return(li.value(t)); }
public double k(double t) { LinearInterpolation li = new LinearInterpolation(this.xBegin_, this.size_, this.yBegin_); return(li.value(t)); }