コード例 #1
0
        public double Run(Circuit.Circuit C, Func <double, double> Vin, Expression Input, IEnumerable <Expression> Plots)
        {
            long a = Timer.Counter;

            Analysis          analysis = C.Analyze();
            TransientSolution TS       = TransientSolution.Solve(analysis, (Real)1 / (SampleRate * Oversample), Log);

            analysisTime += Timer.Delta(a);

            Simulation S = new Simulation(TS)
            {
                Oversample = Oversample,
                Iterations = Iterations,
                Log        = Log,
                Input      = new[] { Input },
                Output     = Plots,
            };

            Log.WriteLine("");
            if (Samples > 0)
            {
                return(RunTest(
                           C, S,
                           Vin,
                           Samples,
                           C.Name));
            }
            else
            {
                return(0.0);
            }
        }
コード例 #2
0
        private void UpdateSimulation(bool Rebuild)
        {
            int id = Interlocked.Increment(ref update);

            new Task(() =>
            {
                ComputerAlgebra.Expression h = (ComputerAlgebra.Expression) 1 / (stream.SampleRate * Oversample);
                TransientSolution s          = Circuit.TransientSolution.Solve(circuit.Analyze(), h, Rebuild ? (ILog)Log : new NullLog());
                lock (sync)
                {
                    if (id > clock)
                    {
                        if (Rebuild)
                        {
                            simulation = new Simulation(s)
                            {
                                Log        = Log,
                                Input      = inputs.Keys.ToArray(),
                                Output     = probes.Select(i => i.V).Concat(OutputChannels.Select(i => i.Signal)).ToArray(),
                                Oversample = Oversample,
                                Iterations = Iterations,
                            };
                        }
                        else
                        {
                            simulation.Solution = s;
                            clock = id;
                        }
                    }
                }
            }).Start(scheduler);
        }
コード例 #3
0
        private void RebuildSolution()
        {
            lock (sync)
            {
                simulation = null;
                ProgressDialog.RunAsync(this, "Building circuit solution...", () =>
                {
                    try
                    {
                        ComputerAlgebra.Expression h = (ComputerAlgebra.Expression) 1 / (stream.SampleRate * Oversample);
                        TransientSolution solution   = Circuit.TransientSolution.Solve(circuit.Analyze(), h, Log);

                        simulation = new Simulation(solution)
                        {
                            Log        = Log,
                            Input      = inputs.Keys.ToArray(),
                            Output     = probes.Select(i => i.V).Concat(OutputChannels.Select(i => i.Signal)).ToArray(),
                            Oversample = Oversample,
                            Iterations = Iterations,
                        };
                    }
                    catch (Exception Ex)
                    {
                        Log.WriteException(Ex);
                    }
                });
            }
        }
コード例 #4
0
        public Dictionary <Expression, List <double> > Run(
            Circuit.Circuit C,
            Func <double, double> Vin,
            int SampleRate,
            int Samples,
            int Oversample,
            int Iterations,
            Expression Input = null,
            IEnumerable <Expression> Outputs = null)
        {
            Analysis          analysis = C.Analyze();
            TransientSolution TS       = TransientSolution.Solve(analysis, (Real)1 / (SampleRate * Oversample));

            // By default, pass Vin to each input of the circuit.
            if (Input == null)
            {
                Input = C.Components.Where(i => i is Input)
                        .Select(i => Component.DependentVariable(i.Name, Component.t))
                        // If there are no inputs, just make a dummy.
                        .DefaultIfEmpty("V[t]")
                        // Require exactly one input.
                        .Single();
            }

            // By default, produce every node of the circuit as output.
            if (Outputs == null)
            {
                Outputs = C.Nodes.Select(i => i.V);
            }

            Simulation S = new Simulation(TS)
            {
                Oversample = Oversample,
                Iterations = Iterations,
                Input      = new[] { Input },
                Output     = Outputs,
            };

            Dictionary <Expression, List <double> > outputs =
                S.Output.ToDictionary(i => i, i => new List <double>(Samples));

            double T         = S.TimeStep;
            double t         = 0;
            Random rng       = new Random();
            int    remaining = Samples;

            while (remaining > 0)
            {
                // Using a varying number of samples on each call to S.Run
                int             N             = Math.Min(remaining, rng.Next(1000, 10000));
                double[]        inputBuffer   = new double[N];
                List <double[]> outputBuffers = S.Output.Select(i => new double[N]).ToList();
                for (int n = 0; n < N; ++n, t += T)
                {
                    inputBuffer[n] = Vin(t);
                }

                S.Run(inputBuffer, outputBuffers);

                for (int i = 0; i < S.Output.Count(); ++i)
                {
                    outputs[S.Output.ElementAt(i)].AddRange(outputBuffers[i]);
                }

                remaining -= N;
            }

            return(outputs);
        }
コード例 #5
0
        /// <summary>
        /// Benchmark a circuit simulation.
        /// By default, benchmarks producing the sum of all output components.
        /// </summary>
        /// <returns>The rate at which the circuit simulated, in samples per second.</returns>
        public void Benchmark(
            Circuit.Circuit C,
            Func <double, double> Vin,
            int SampleRate,
            int Oversample,
            int Iterations,
            Expression Input = null,
            IEnumerable <Expression> Outputs = null)
        {
            Analysis analysis    = null;
            double   analyzeTime = Benchmark(1, () => analysis = C.Analyze());

            System.Console.WriteLine("Circuit.Analyze time: {0:G3} ms", analyzeTime * 1000);

            TransientSolution TS        = null;
            double            solveTime = Benchmark(1, () => TS = TransientSolution.Solve(analysis, (Real)1 / (SampleRate * Oversample)));

            System.Console.WriteLine("TransientSolution.Solve time: {0:G3} ms", solveTime * 1000);

            // By default, pass Vin to each input of the circuit.
            if (Input == null)
            {
                Input = FindInput(C);
            }

            // By default, produce every node of the circuit as output.
            if (Outputs == null)
            {
                Expression sum = 0;
                foreach (Speaker i in C.Components.Where(i => i is Speaker))
                {
                    sum += Component.DependentVariable(i.Name, Component.t);
                }
                Outputs = new[] { sum };
            }

            Simulation S       = null;
            double     simTime = Benchmark(1, () => S = new Simulation(TS)
            {
                Oversample = Oversample,
                Iterations = Iterations,
                Input      = new[] { Input },
                Output     = Outputs,
            });

            System.Console.WriteLine("Simulation.Simulation time: {0} ms", simTime * 1000);

            int N = 1000;

            double[]        inputBuffer   = new double[N];
            List <double[]> outputBuffers = Outputs.Select(i => new double[N]).ToList();

            double T       = 1.0 / SampleRate;
            double t       = 0;
            double runTime = Benchmark(3, () =>
            {
                // This is counting the cost of evaluating Vin during benchmarking...
                for (int n = 0; n < N; ++n, t += T)
                {
                    inputBuffer[n] = Vin(t);
                }

                S.Run(inputBuffer, outputBuffers);
            });
            double rate = N / runTime;

            System.Console.WriteLine("{0:G3} kHz, {1:G3}x real time", rate / 1000, rate / SampleRate);
        }
コード例 #6
0
        /// <summary>
        /// Update the simulation asynchronously
        /// </summary>
        /// <param name="rebuild">Whether a full simulation rebuild is required</param>
        void UpdateSimulation(bool rebuild)
        {
            int id = Interlocked.Increment(ref update);

            new Task(() =>
            {
                try
                {
                    Analysis analysis    = circuit.Analyze();
                    TransientSolution ts = TransientSolution.Solve(analysis, (Real)1 / (sampleRate * oversample));

                    lock (sync)
                    {
                        if (id > clock)
                        {
                            if (rebuild)
                            {
                                Expression inputExpression = circuit.Components.OfType <Input>().Select(i => i.In).SingleOrDefault();

                                if (inputExpression == null)
                                {
                                    simulationUpdateException = new NotSupportedException("Circuit has no inputs.");
                                }
                                else
                                {
                                    IEnumerable <Speaker> speakers = circuit.Components.OfType <Speaker>();

                                    Expression outputExpression = 0;

                                    // Output is voltage drop across the speakers
                                    foreach (Speaker speaker in speakers)
                                    {
                                        outputExpression += speaker.Out;
                                    }

                                    if (outputExpression.EqualsZero())
                                    {
                                        simulationUpdateException = new NotSupportedException("Circuit has no speaker outputs.");
                                    }
                                    else
                                    {
                                        simulation = new Simulation(ts)
                                        {
                                            Oversample = oversample,
                                            Iterations = iterations,
                                            Input      = new[] { inputExpression },
                                            Output     = new[] { outputExpression }
                                        };
                                    }
                                }
                            }
                            else
                            {
                                simulation.Solution = ts;
                                clock = id;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    simulationUpdateException = ex;
                }
            }).Start(scheduler);
        }