void CCNOTGateCountExample()
        {
            var config = new QCTraceSimulatorConfiguration();

            config.UsePrimitiveOperationsCounter = true;
            QCTraceSimulator sim = new QCTraceSimulator(config);
            QVoid            res;

            res = CCNOTDriver.Run(sim).Result;
            res = CCNOTDriver.Run(sim).Result;

            double tCount    = sim.GetMetric <Intrinsic.CCNOT, CCNOTDriver>(PrimitiveOperationsGroupsNames.T);
            double tCountAll = sim.GetMetric <CCNOTDriver>(PrimitiveOperationsGroupsNames.T);

            double cxCount = sim.GetMetric <Intrinsic.CCNOT, CCNOTDriver>(PrimitiveOperationsGroupsNames.CNOT);

            string csvSummary = sim.ToCSV()[MetricsCountersNames.primitiveOperationsCounter];

            // above code is an example used in the documentation

            Assert.Equal(7.0, sim.GetMetricStatistic <Intrinsic.CCNOT, CCNOTDriver>(PrimitiveOperationsGroupsNames.T, MomentsStatistic.Statistics.Average));
            Assert.Equal(7.0, tCount);
            Assert.Equal(8.0, sim.GetMetricStatistic <CCNOTDriver>(PrimitiveOperationsGroupsNames.T, MomentsStatistic.Statistics.Average));
            Assert.Equal(0.0, sim.GetMetricStatistic <CCNOTDriver>(PrimitiveOperationsGroupsNames.T, MomentsStatistic.Statistics.Variance));
            Assert.Equal(8.0, tCountAll);
            Assert.Equal(10.0, cxCount);
            Debug.WriteLine(csvSummary);
            output.WriteLine(csvSummary);
        }
        void TCountTest()
        {
            var config = new QCTraceSimulatorConfiguration();

            config.UsePrimitiveOperationsCounter = true;
            config.CallStackDepthLimit           = 2;
            QCTraceSimulator sim = new QCTraceSimulator(config);
            var    res           = TCountOneGatesTest.Run(sim).Result;
            var    res2          = TCountZeroGatesTest.Run(sim).Result;
            var    tcount        = PrimitiveOperationsGroupsNames.T;
            string csvSummary    = sim.ToCSV()[MetricsCountersNames.primitiveOperationsCounter];

            output.WriteLine(csvSummary);

            Assert.Equal(Double.NaN, sim.GetMetricStatistic <Intrinsic.T, TCountOneGatesTest>(
                             PrimitiveOperationsGroupsNames.T, MomentsStatistic.Statistics.Variance));
            Assert.Equal(1, sim.GetMetric <Intrinsic.T, TCountOneGatesTest>(tcount,
                                                                            functor: OperationFunctor.Adjoint));
            Assert.Equal(1, sim.GetMetric <Intrinsic.T, TCountOneGatesTest>(tcount));
            Assert.Equal(1, sim.GetMetric <Intrinsic.RFrac, TCountOneGatesTest>(tcount));
            Assert.Equal(1, sim.GetMetric <Intrinsic.ExpFrac, TCountOneGatesTest>(tcount));
            Assert.Equal(1, sim.GetMetric <Intrinsic.R1Frac, TCountOneGatesTest>(tcount));

            Assert.Equal(0, sim.GetMetric <Intrinsic.S, TCountZeroGatesTest>(tcount,
                                                                             functor: OperationFunctor.Adjoint));
            Assert.Equal(0, sim.GetMetric <Intrinsic.S, TCountZeroGatesTest>(tcount));
            Assert.Equal(0, sim.GetMetric <Intrinsic.RFrac, TCountZeroGatesTest>(tcount));
            Assert.Equal(0, sim.GetMetric <Intrinsic.ExpFrac, TCountZeroGatesTest>(tcount));
            Assert.Equal(0, sim.GetMetric <Intrinsic.R1Frac, TCountZeroGatesTest>(tcount));
        }
        public void RepeatUntilSuccessCircuitsMetricsTest()
        {
            // Get an instance of the appropriately configured QCTraceSimulator
            QCTraceSimulator sim = MetricCalculationUtils.GetSimulatorForMetricsCalculation();

            // Run tests against trace simulator to collect metrics
            var result = RepeatUntilSuccessCircuitsTest.Run(sim).Result;

            string TCount      = PrimitiveOperationsGroupsNames.T;
            string extraQubits = MetricsNames.WidthCounter.ExtraWidth;
            string min         = StatisticsNames.Min;
            string max         = StatisticsNames.Max;
            string avg         = StatisticsNames.Average;

            // Let us check how many ancillas we used
            // 4 for Nielsen & Chuang
            // version because we used CCNOT3 which itself required 2 ancillas
            Assert.Equal(4, sim.GetMetric <ExpIZArcTan2NC, caller>(extraQubits));
            // 2 for Paetznick & Svore version
            Assert.Equal(2, sim.GetMetric <ExpIZArcTan2PS, caller>(extraQubits));

            // One trial of ExpIZArcTan2NC requires at least 8 T gates
            Assert.True(8 <= sim.GetMetricStatistic <ExpIZArcTan2NC, caller>(TCount, min));

            // One trial of ExpIZArcTan2NC requires at least 3 T gates
            Assert.True(3 <= sim.GetMetricStatistic <ExpIZArcTan2PS, caller>(TCount, min));

            // The rest of the statistical information we print into test output
            // For ExpIZArcTan2NC:
            output.WriteLine($"Statistics collected for{nameof(ExpIZArcTan2NC)}");
            output.WriteLine($"Average number of T-gates:" +
                             $" {sim.GetMetricStatistic<ExpIZArcTan2NC, caller>(TCount, avg)}");
            output.WriteLine($"Minimal number of T-gates: " +
                             $"{sim.GetMetricStatistic<ExpIZArcTan2NC, caller>(TCount, min)}");
            output.WriteLine($"Maximal number of T-gates: " +
                             $"{sim.GetMetricStatistic<ExpIZArcTan2NC, caller>(TCount, max)}");

            // And for ExpIZArcTan2PS
            output.WriteLine($"Statistics collected for{nameof(ExpIZArcTan2PS)}");
            output.WriteLine($"Average number of T-gates:" +
                             $" {sim.GetMetricStatistic<ExpIZArcTan2PS, caller>(TCount, avg)}");
            output.WriteLine($"Minimal number of T-gates: " +
                             $"{sim.GetMetricStatistic<ExpIZArcTan2PS, caller>(TCount, min)}");
            output.WriteLine($"Maximal number of T-gates: " +
                             $"{sim.GetMetricStatistic<ExpIZArcTan2PS, caller>(TCount, max)}");
        }