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);
            }
Example #9
0
        //-------------------------------------------------------------------------
        // 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);
        }