public static long cal_inv(double temperature, double RW = 100, string METHOD = "poly3", double R1 = 10, double R2 = 10, double R3 = 10) { double rx; if (METHOD == "linear") { rx = LINEAR.caly(temperature) / 1000; } else { rx = POLY3.caly(temperature) / 1000; } double v_rxr1 = VREF_R * R1 / (rx + R1); double v_r2r3 = VREF_R * R3 / (R2 + R3); double ad_input = ((double)10 / 3 + 1 / RW * 200 / 3) * (v_r2r3 - v_rxr1); if (ad_input >= AD_MAX) { ad_input = AD_MAX; } else if (ad_input <= 0) { ad_input = 0; } long ret = (long)Math.Round((ad_input / VREF_AD) * AD_MAX); return(ret); }
//------------------------------------------------------------------------- public virtual void coverage() { coverPrivateConstructor(typeof(CurveInterpolators)); coverPrivateConstructor(typeof(StandardCurveInterpolators)); assertFalse(LINEAR.Equals(null)); assertFalse(LINEAR.Equals(ANOTHER_TYPE)); }
public virtual void noRightTest() { BoundCurveInterpolator bci = LINEAR.bind(X_DATA, Y_DATA, DISCOUNT_FACTOR_QUADRATIC_LEFT_ZERO_RATE, DISCOUNT_FACTOR_QUADRATIC_LEFT_ZERO_RATE); assertThrowsIllegalArg(() => bci.interpolate(10d)); assertThrowsIllegalArg(() => bci.firstDerivative(10d)); assertThrowsIllegalArg(() => bci.parameterSensitivity(10d)); }
public virtual void limitingTest() { BoundCurveInterpolator bci = LINEAR.bind(X_DATA, Y_DATA, DISCOUNT_FACTOR_QUADRATIC_LEFT_ZERO_RATE, PRODUCT_LINEAR); double small = 1.0e-8; assertEquals(bci.interpolate(small), bci.interpolate(10d * small), Y_DATA.get(0) * 10d * small); double derivative = bci.firstDerivative(small); double derivativeExp = (bci.interpolate(small + 0.5 * small) - bci.interpolate(small - 0.5 * small)) / small; assertEquals(derivative, derivativeExp, Y_DATA.get(0) * small); DoubleArray sensi = bci.parameterSensitivity(small); DoubleArray sensiS = bci.parameterSensitivity(small * 5d); assertTrue(DoubleArrayMath.fuzzyEquals(sensi.toArray(), sensiS.toArray(), Y_DATA.get(0) * 10d * small)); }
public static long cal_inv_by_pts(double temperature, List <double> para, string METHOD = "poly3", double R1 = 10) { double rx; if (METHOD == "linear") { rx = LINEAR.caly(temperature) / 1000; } else { rx = POLY3.caly(temperature) / 1000; } double v_rxr1 = VREF_R * R1 / (rx + R1); long ret = (long)(para[0] + para[1] * v_rxr1); return(ret); }
/// <summary> /// 根据拟合直线确定温度值,规定x轴为电压,y轴为AD输出 /// AD_output = para[0] + para[1] * voltage /// </summary> /// <param name="ad_output"></param> /// <param name="para"></param> /// <param name="METHOD"></param> /// <param name="R1"></param> /// <param name="R2"></param> /// <param name="R3"></param> /// <returns></returns> public static double cal_by_pts(long ad_output, List <double> para, string METHOD = "poly3", double R1 = 10) { double vol = cal_vol_by_pts(ad_output, para); double v_rxr1 = vol; double rx = R1 * (VREF_R / v_rxr1 - 1); double ret; if (METHOD == "linear") { ret = LINEAR.calx(rx * 1000); } else { ret = POLY3.calx(rx * 1000); } return(ret); }
//------------------------------------------------------------------------- public virtual void test_bind() { DoubleArray xValues = DoubleArray.of(1, 2, 3); DoubleArray yValues = DoubleArray.of(2, 4, 5); BoundCurveInterpolator bound = LINEAR.bind(xValues, yValues, CurveExtrapolators.FLAT, CurveExtrapolators.FLAT); assertEquals(bound.interpolate(0.5), 2d, 0d); assertEquals(bound.interpolate(1), 2d, 0d); assertEquals(bound.interpolate(1.5), 3d, 0d); assertEquals(bound.interpolate(2), 4d, 0d); assertEquals(bound.interpolate(2.5), 4.5d, 0d); assertEquals(bound.interpolate(3), 5d, 0d); assertEquals(bound.interpolate(3.5), 5d, 0d); // coverage assertEquals(bound.parameterSensitivity(0.5).size(), 3); assertEquals(bound.parameterSensitivity(2).size(), 3); assertEquals(bound.parameterSensitivity(3.5).size(), 3); assertEquals(bound.firstDerivative(0.5), 0d, 0d); assertTrue(bound.firstDerivative(2) != 0d); assertEquals(bound.firstDerivative(3.5), 0d, 0d); assertNotNull(bound.ToString()); }
/// <summary> /// Better performance on a "Consolas" font. /// Unit: kΩ /// VREF_R /// | /// |----- /// | | /// RX R2 VREF_AD /// |----+--->--(-) | /// | | RW-->--ADC----(0~AD_MAX) /// | |--->--(+) | /// R1 R3 GND /// |----- /// GND /// </summary> /// <returns></returns> public static double cal(long ad_output, double RW = 100, string METHOD = "poly3", double R1 = 10, double R2 = 10, double R3 = 10) { if (RW <= 0 || ad_output == AD_MAX) { return(UNDEF); } double ad_input = ((double)ad_output / AD_MAX) * VREF_AD; double v_r2r3 = VREF_R * R3 / (R2 + R3); double v_rxr1 = v_r2r3 - ad_input / ((double)10 / 3 + 1 / RW * 200 / 3); double rx = R1 * (VREF_R / v_rxr1 - 1); double ret; if (METHOD == "linear") { ret = LINEAR.calx(rx * 1000); } else { ret = POLY3.calx(rx * 1000); } return(ret); }
//------------------------------------------------------------------------- // bumping a node point at (nodeExpiry, nodeDelta) private double nodeSensitivity(BlackFxOptionSmileVolatilities provider, CurrencyPair pair, ZonedDateTime expiry, double strike, double forward, double nodeExpiry, double nodeDelta) { double strikeMod = provider.CurrencyPair.Equals(pair) ? strike : 1.0 / strike; double forwardMod = provider.CurrencyPair.Equals(pair) ? forward : 1.0 / forward; InterpolatedStrikeSmileDeltaTermStructure smileTerm = (InterpolatedStrikeSmileDeltaTermStructure)provider.Smile; double[] times = smileTerm.Expiries.toArray(); int nTimes = times.Length; SmileDeltaParameters[] volTermUp = new SmileDeltaParameters[nTimes]; SmileDeltaParameters[] volTermDw = new SmileDeltaParameters[nTimes]; int deltaIndex = -1; for (int i = 0; i < nTimes; ++i) { DoubleArray deltas = smileTerm.VolatilityTerm.get(i).Delta; int nDeltas = deltas.size(); int nDeltasTotal = 2 * nDeltas + 1; double[] deltasTotal = new double[nDeltasTotal]; deltasTotal[nDeltas] = 0.5d; for (int j = 0; j < nDeltas; ++j) { deltasTotal[j] = 1d - deltas.get(j); deltasTotal[2 * nDeltas - j] = deltas.get(j); } double[] volsUp = smileTerm.VolatilityTerm.get(i).Volatility.toArray(); double[] volsDw = smileTerm.VolatilityTerm.get(i).Volatility.toArray(); if (Math.Abs(times[i] - nodeExpiry) < TOLERANCE) { for (int j = 0; j < nDeltasTotal; ++j) { if (Math.Abs(deltasTotal[j] - nodeDelta) < TOLERANCE) { deltaIndex = j; volsUp[j] += EPS; volsDw[j] -= EPS; } } } volTermUp[i] = SmileDeltaParameters.of(times[i], deltas, DoubleArray.copyOf(volsUp)); volTermDw[i] = SmileDeltaParameters.of(times[i], deltas, DoubleArray.copyOf(volsDw)); } InterpolatedStrikeSmileDeltaTermStructure smileTermUp = InterpolatedStrikeSmileDeltaTermStructure.of(ImmutableList.copyOf(volTermUp), ACT_365F); InterpolatedStrikeSmileDeltaTermStructure smileTermDw = InterpolatedStrikeSmileDeltaTermStructure.of(ImmutableList.copyOf(volTermDw), ACT_365F); BlackFxOptionSmileVolatilities provUp = BlackFxOptionSmileVolatilities.of(NAME, CURRENCY_PAIR, VAL_DATE_TIME, smileTermUp); BlackFxOptionSmileVolatilities provDw = BlackFxOptionSmileVolatilities.of(NAME, CURRENCY_PAIR, VAL_DATE_TIME, smileTermDw); double volUp = provUp.volatility(pair, expiry, strike, forward); double volDw = provDw.volatility(pair, expiry, strike, forward); double totalSensi = 0.5 * (volUp - volDw) / EPS; double expiryTime = provider.relativeTime(expiry); SmileDeltaParameters singleSmile = smileTerm.smileForExpiry(expiryTime); double[] strikesUp = singleSmile.strike(forwardMod).toArray(); double[] strikesDw = strikesUp.Clone(); double[] vols = singleSmile.Volatility.toArray(); strikesUp[deltaIndex] += EPS; strikesDw[deltaIndex] -= EPS; double volStrikeUp = LINEAR.bind(DoubleArray.ofUnsafe(strikesUp), DoubleArray.ofUnsafe(vols), FLAT, FLAT).interpolate(strikeMod); double volStrikeDw = LINEAR.bind(DoubleArray.ofUnsafe(strikesDw), DoubleArray.ofUnsafe(vols), FLAT, FLAT).interpolate(strikeMod); double sensiStrike = 0.5 * (volStrikeUp - volStrikeDw) / EPS; SmileDeltaParameters singleSmileUp = smileTermUp.smileForExpiry(expiryTime); double strikeUp = singleSmileUp.strike(forwardMod).get(deltaIndex); SmileDeltaParameters singleSmileDw = smileTermDw.smileForExpiry(expiryTime); double strikeDw = singleSmileDw.strike(forwardMod).get(deltaIndex); double sensiVol = 0.5 * (strikeUp - strikeDw) / EPS; return(totalSensi - sensiStrike * sensiVol); }