public void Analyse(List <IProbabilityDistribution> inputDistributions, List <IProbabilityDistribution> outputDistributions, WorkflowComponent innerWorkflow)
        {
            using (filer = new CSVFiler(path))
            {
                int NVariables = inputDistributions.Count;
                int NTargets   = outputDistributions.Count;

                var sampler  = new FASTSampler(NVariables);
                int NSamples = sampler.Ns;
                int Ns2      = NSamples / 2;

                propagator.Propagate(inputDistributions, outputDistributions, innerWorkflow);
                Matrix <double> samples = propagator.Samples;

                double[] ResultMeans              = new double[NTargets];
                double[] ResultVariances          = new double[NTargets];
                double[] ResultStandardDeviations = new double[NTargets];
                for (int r = 0; r < NTargets; r++)                 //for rth result (output)
                {
                    //to store intermedient sum
                    double sum        = 0;
                    double sumSquared = 0;

                    int r2 = NVariables + r;
                    for (int s = 0; s < Ns2; s++)
                    {
                        double sample = samples[s, r2];
                        sum        += sample;
                        sumSquared += sample * sample;
                    }

                    ResultMeans[r]              = sum / Ns2;
                    ResultVariances[r]          = sumSquared / Ns2 - (ResultMeans[r]) * (ResultMeans[r]);                                           //sobol's original approach (satelli's approach to be added)
                    ResultStandardDeviations[r] = Sqrt(ResultVariances[r]);
                }


                var      A           = new List <double>();
                var      B           = new List <double>();
                var      Lambda      = new List <double>();
                double[] samplesFAST = sampler.Samples;

                Matrix <double> Sensitivities = Matrix <double> .Build.Dense(NTargets, NVariables);

                for (int t = 0; t < NTargets; t++)
                {
                    ResultVariances[t] = 0;
                    Lambda.Clear();

                    //for (int j = -(NSamples - 1) / 2; j <= (NSamples - 1) / 2; j++)   in "A Quantitative Model-Independent Method for Global Sensitivity Analysis of Model Output"
                    for (int s = 0; s < Ns2; s++)                         //seems -(NSamples - 1) / 2 ~ 0 are not used
                    {
                        double tempFA = 0;
                        double tempFB = 0;


                        for (int k = 0; k < NSamples; k++)
                        {
                            //tempFA += ResultMatrix[k][t] * Cos(s * samplesFAST[k]);
                            //tempFB += ResultMatrix[k][t] * Sin(s * samplesFAST[k]);
                            tempFA += samples[k, NVariables + t] * Cos(s * samplesFAST[k]);
                            tempFB += samples[k, NVariables + t] * Sin(s * samplesFAST[k]);
                        }
                        tempFA = tempFA / NSamples;
                        tempFB = tempFB / NSamples;

                        A.Add(tempFA);
                        B.Add(tempFB);

                        double lambda = Pow(tempFA, 2) + Pow(tempFB, 2);
                        Lambda.Add(lambda);
                        ResultVariances[t] += lambda;
                    }

                    ResultVariances[t]         *= 2;
                    ResultStandardDeviations[t] = Sqrt(ResultVariances[t]);
                    ResultMeans[t] = samples.SubMatrix(0, Ns2, NVariables + t, 1).Column(0).Sum() / Ns2;

                    // Get Sensitivities
                    for (int v = 0; v < NVariables; v++)
                    {
                        Sensitivities[t, v] = 0;
                        for (int p = 1; p <= sampler.M; p++)
                        {
                            int temp_counter = p * sampler.Omega[v] - 1;
                            Sensitivities[t, v] += Lambda[temp_counter];
                        }
                        Sensitivities[t, v] *= 2 / ResultVariances[t];
                    }

                    //Write .csv file
                    filer.NewRow();

                    filer.AddToRow(t);
                    filer.AddToRow(outputDistributions[t].Name);
                    foreach (var s in Sensitivities.Row(t))
                    {
                        filer.AddToRow(s);
                    }

                    filer.WriteRow();
                }

                for (int t = 0; t < NTargets; t++)
                {
                    filer.NewRow();
                    filer.AddToRow(t);
                    filer.AddToRow(outputDistributions[t].Name);
                    for (int v = 0; v < NVariables; v++)
                    {
                        filer.AddToRow(Sensitivities[t, v]);
                    }
                    filer.AddToRow(1 - Sensitivities.Row(t).Sum());
                }
            }
        }
Example #2
0
        public void Propagate(List <IFASTDistribution> inputDistributions, List <ProbabilityDistributionFromSamples> outputDistributions, WorkflowComponent innerWorkflow)
        {
            filer = (createFile) ? new CSVFiler(path) : null;

            try
            {
                int Ninputs  = inputDistributions.Count;
                int Noutputs = outputDistributions.Count;

                sampler = new FASTSampler(Ninputs);
                int NSamples = sampler.Ns;

                Matrix <double> samples = Matrix <double> .Build.Dense(NSamples, Ninputs + Noutputs);

                for (int i = 0; i < inputDistributions.Count; i++)
                {
                    samples.SetColumn(i, inputDistributions[i].GetSamples(NSamples, sampler.GetSamplesForVariable(i)));
                }

                for (int s = 0; s < NSamples; s++)
                {
                    int v = 0;
                    foreach (IProbabilityDistribution input in inputDistributions)
                    {
                        input.Data.Value = samples[s, v];
                        v++;
                    }

                    // Execute workflow
                    bool statusToCheck = innerWorkflow.Execute();

                    foreach (IProbabilityDistribution output in outputDistributions)
                    {
                        samples[s, v] = Convert.ToDouble(output.Data.Value);
                        v++;
                    }

                    if (createFile && statusToCheck)
                    {
                        // Execute database insert command
                        filer.NewRow();

                        //filer.AddToRow(i);

                        foreach (Data input in innerWorkflow.ModelDataInputs)
                        {
                            filer.AddToRow(input);
                        }

                        foreach (Data output in innerWorkflow.ModelDataInputs)
                        {
                            filer.AddToRow(output);
                        }

                        filer.WriteRow();
                    }
                }

                int o = Ninputs;
                foreach (IProbabilityDistribution output in outputDistributions)
                {
                    output.Update(samples.Column(o).AsArray());
                    o++;
                }

                Samples = samples;
            }
            finally
            {
                filer?.Dispose();
            }
        }