public virtual void check_pv_sensitivity()
        {
            ImmutableRatesProvider multicurve = CALIBRATOR.calibrate(GROUP_DEFINITION_PV_SENSI, MARKET_QUOTES, REF_DATA);
            // the trades used for calibration
            IDictionary <CurveName, IList <Trade> >         trades         = new Dictionary <CurveName, IList <Trade> >();
            IDictionary <CurveName, IList <ResolvedTrade> > resolvedTrades = new Dictionary <CurveName, IList <ResolvedTrade> >();
            ImmutableList <CurveDefinition> curveGroups = GROUP_DEFINITION.CurveDefinitions;

            ImmutableList.Builder <CurveParameterSize> builder = ImmutableList.builder();
            foreach (CurveDefinition entry in curveGroups)
            {
                ImmutableList <CurveNode> nodes               = entry.Nodes;
                IList <Trade>             tradesCurve         = new List <Trade>();
                IList <ResolvedTrade>     resolvedTradesCurve = new List <ResolvedTrade>();
                foreach (CurveNode node in nodes)
                {
                    tradesCurve.Add(node.trade(1d, MARKET_QUOTES, REF_DATA));
                    resolvedTradesCurve.Add(node.resolvedTrade(1d, MARKET_QUOTES, REF_DATA));
                }
                trades[entry.Name]         = tradesCurve;
                resolvedTrades[entry.Name] = resolvedTradesCurve;
                builder.add(entry.toCurveParameterSize());
            }
            ImmutableList <CurveParameterSize> order = builder.build();    // order of the curves
            // Check CurveInfo present and sensitivity as expected
            IDictionary <CurveName, DoubleArray> mqsGroup = new Dictionary <CurveName, DoubleArray>();
            int nodeIndex = 0;

            foreach (CurveParameterSize cps in order)
            {
                int      nbParameters = cps.ParameterCount;
                double[] mqsCurve     = new double[nbParameters];
                for (int looptrade = 0; looptrade < nbParameters; looptrade++)
                {
                    DoubleArray mqsNode = PV_MEASURES.derivative(resolvedTrades[cps.Name][looptrade], multicurve, order);
                    mqsCurve[looptrade] = mqsNode.get(nodeIndex);
                    nodeIndex++;
                }
                Optional <Curve> curve = multicurve.findData(cps.Name);
                DoubleArray      pvSensitivityExpected = DoubleArray.ofUnsafe(mqsCurve);
                mqsGroup[cps.Name] = pvSensitivityExpected;
                assertTrue(curve.Present);
                assertTrue(curve.get().Metadata.findInfo(CurveInfoType.PV_SENSITIVITY_TO_MARKET_QUOTE).Present);
                DoubleArray pvSensitivityMetadata = curve.get().Metadata.findInfo(CurveInfoType.PV_SENSITIVITY_TO_MARKET_QUOTE).get();
                assertTrue(pvSensitivityExpected.equalWithTolerance(pvSensitivityMetadata, 1.0E-10));
            }
        }
        //-------------------------------------------------------------------------
        public override DoubleMatrix apply(DoubleArray x)
        {
            // create child provider from matrix
            ImmutableRatesProvider provider = providerGenerator.generate(x);
            // calculate derivative for each trade using the child provider
            int size = trades.Count;

            return(DoubleMatrix.ofArrayObjects(size, size, i => measures.derivative(trades[i], provider, curveOrder)));
        }
        private ImmutableMap <CurveName, DoubleArray> sensitivityToMarketQuoteForGroup(ImmutableRatesProvider provider, ImmutableList <ResolvedTrade> trades, ImmutableList <CurveParameterSize> orderGroup)
        {
            ImmutableMap.Builder <CurveName, DoubleArray> mqsGroup = new ImmutableMap.Builder <CurveName, DoubleArray>();
            int nodeIndex = 0;

            foreach (CurveParameterSize cps in orderGroup)
            {
                int      nbParameters = cps.ParameterCount;
                double[] mqsCurve     = new double[nbParameters];
                for (int looptrade = 0; looptrade < nbParameters; looptrade++)
                {
                    DoubleArray mqsNode = pvMeasures.derivative(trades.get(nodeIndex), provider, orderGroup);
                    mqsCurve[looptrade] = mqsNode.get(nodeIndex);
                    nodeIndex++;
                }
                mqsGroup.put(cps.Name, DoubleArray.ofUnsafe(mqsCurve));
            }
            return(mqsGroup.build());
        }
 // calculate the derivatives
 private DoubleMatrix derivatives(ImmutableList <ResolvedTrade> trades, ImmutableRatesProvider provider, ImmutableList <CurveParameterSize> orderAll, int totalParamsAll)
 {
     return(DoubleMatrix.ofArrayObjects(trades.size(), totalParamsAll, i => measures.derivative(trades.get(i), provider, orderAll)));
 }