/// <summary>
        /// Test building blocks of interest rate swap exposure calculation.
        /// </summary>
        public void TestBasics(LinearGaussianModel model, IEnumerable<NArray> allZeroRatesT0,
            TimePoint[] timePoints, SimulationGraph graph)
        {
            bool testModel = true;
            if (testModel)
            {
                var check1 = model[1, timePoints[1].DateTime.AddDays(182)].First();
                Assert.IsTrue(TestHelpers.AgreesAbsolute(check1, 1.0015314301020275));

                var check2 = model[1, timePoints[1].DateTime.AddDays(91)].First();
                Assert.IsTrue(TestHelpers.AgreesAbsolute(check2, 1.0007451895710209));

                var check3 = model.ForwardRate(1,
                    timePoints[1].DateTime.AddDays(91), timePoints[1].DateTime.AddDays(182)).First();
                Assert.IsTrue(TestHelpers.AgreesAbsolute(check3, -0.0031509366920208916));
            }

            bool testProfile = true;
            if (testProfile)
            {
                var testVariates0 = graph.RegisterFactor<NormalVariates>("IR_DiscountFactor_EUR_Factor0");
                var testVariates1 = graph.RegisterFactor<NormalVariates>("IR_DiscountFactor_EUR_Factor1");
                var testVariates2 = graph.RegisterFactor<NormalVariates>("IR_DiscountFactor_EUR_Factor2");

                var check = Descriptive.Correlation(testVariates1.Value, testVariates2.Value);

                // check 3M rolling tenor
                var percentiles = new double[] { 1, 10, 50, 90, 99 };
                var measures = new List<IList<double>>();
                for (int i = 0; i < timePoints.Length; ++i)
                {
                    var tenorMonths = 3;
                    var tenorYears = tenorMonths / 12.0;
                    var df = model[i, timePoints[i].DateTime.AddMonths(3)];
                    var zeroRate = -NMath.Log(df) / tenorYears;
                    var values = NMath.Percentiles(zeroRate, percentiles).ToList();
                    measures.Add(values);
                }

                var times = timePoints.Select(p => p.YearsFromBaseDate).ToArray();
                var profile10 = measures.Select(p => p[1]).ToArray();
                var profile90 = measures.Select(p => p[3]).ToArray();
            }

            bool testForwardRate = true;
            if (testForwardRate)
            {
                // check 3M rolling tenor
                var percentiles = new double[] { 1, 10, 50, 90, 99 };
                var measures = new List<IList<double>>();
                for (int i = 0; i < timePoints.Length; ++i)
                {
                    var tenorMonths = 3;
                    var tenorYears = tenorMonths / 12.0;
                    var forwardRate = model.ForwardRate(i, timePoints[i].DateTime.AddMonths(3), timePoints[i].DateTime.AddMonths(6));
                    var values = NMath.Percentiles(forwardRate, percentiles).ToList();
                    measures.Add(values);
                }

                var times = timePoints.Select(p => p.YearsFromBaseDate).ToArray();
                var profile10 = measures.Select(p => p[1]).ToArray();
                var profile90 = measures.Select(p => p[3]).ToArray();
            }

            bool testAAD = true;
            if (testAAD)
            {
                // just get the result
                var result0 = NArray.Evaluate(() =>
                {
                    var df = model[10, timePoints[10].DateTime.AddMonths(3)];
                    return df;
                });

                // get the result and single derivative
                var result1 = NArray.Evaluate(() =>
                {
                    var df = model[10, timePoints[10].DateTime.AddMonths(3)];
                    return df;
                }, model.ZeroRatesT0[6].Value);

                var log = new StringBuilder();

                // get the result and all derivatives (and log output)
                var result2 = NArray.Evaluate(() =>
                {
                    var df = model[10, timePoints[10].DateTime.AddMonths(3)];
                    return df;
                }, log, allZeroRatesT0.ToArray());

                // now forward rate and all derivatives
                var result3 = NArray.Evaluate(() =>
                {
                    var df = model.ForwardRate(10, timePoints[10].DateTime.AddMonths(3), timePoints[10].DateTime.AddMonths(6));
                    return df;
                }, allZeroRatesT0.ToArray());

                var unbumped0 = model[10, timePoints[10].DateTime.AddMonths(3)];

                var expected0 = unbumped0.DebugDataView.ToArray();
                var unbumped3 = model.ForwardRate(10, timePoints[10].DateTime.AddMonths(3), timePoints[10].DateTime.AddMonths(6));
                var expected3 = unbumped3.DebugDataView.ToArray();

                var obtained0 = result1[0].DebugDataView.ToArray();
                var obtained1 = result1[0].DebugDataView.ToArray();
                var obtained2 = result2[0].DebugDataView.ToArray();
                var obtained3 = result3[0].DebugDataView.ToArray();

                Assert.IsTrue(TestHelpers.AgreesAbsolute(expected0, obtained0));
                Assert.IsTrue(TestHelpers.AgreesAbsolute(expected0, obtained1));
                Assert.IsTrue(TestHelpers.AgreesAbsolute(expected0, obtained2));
                Assert.IsTrue(TestHelpers.AgreesAbsolute(expected3, obtained3));

                var logCheck = log.ToString();

                var obtained_deriv1 = result1[1].DebugDataView.ToArray();
                var obtained_deriv2 = result2[7].DebugDataView.ToArray();
                var obtained_deriv3 = result3[7].DebugDataView.ToArray();

                model.ZeroRatesT0.Data[6] = new DataPoint(model.ZeroRatesT0.Data[6].Time, model.ZeroRatesT0.Data[6].Value + 1e-6);

                var bumped0 = model[10, timePoints[10].DateTime.AddMonths(3)];
                var bumped3 = model.ForwardRate(10, timePoints[10].DateTime.AddMonths(3), timePoints[10].DateTime.AddMonths(6));

                var expected_deriv1 = ((bumped0 - unbumped0) / 1e-6)
                    .DebugDataView.ToArray();

                var expected_deriv3 = ((bumped3 - unbumped3) / 1e-6)
                    .DebugDataView.ToArray();

                Assert.IsTrue(TestHelpers.AgreesAbsolute(expected_deriv1, obtained_deriv1, 1e-5));
                Assert.IsTrue(TestHelpers.AgreesAbsolute(expected_deriv1, obtained_deriv2, 1e-5));
                Assert.IsTrue(TestHelpers.AgreesAbsolute(expected_deriv3, obtained_deriv3, 1e-5));
            }

            bool checkTimings = true;
            if (checkTimings)
            {
                // check timings
                Console.WriteLine("Immediate execution");
                VectorAccelerator.Tests.TestHelpers.Timeit(() =>
                {
                    var df = model[10, timePoints[10].DateTime.AddMonths(3)];
                }, 10, 10);

                Console.WriteLine(); Console.WriteLine("Deferred execution no derivatives");
                VectorAccelerator.Tests.TestHelpers.Timeit(() =>
                {
                    NArray.Evaluate(() =>
                    {
                        var df = model[10, timePoints[10].DateTime.AddMonths(3)];
                        return df;
                    });
                }, 10, 10);

                Console.WriteLine(); Console.WriteLine("Deferred execution all derivatives");
                VectorAccelerator.Tests.TestHelpers.Timeit(() =>
                    {
                        NArray.Evaluate(() =>
                        {
                            var df = model[10, timePoints[10].DateTime.AddMonths(3)];
                            return df;
                        }, allZeroRatesT0.ToArray());
                    }, 10, 10);
            }
        }