public List <double> Predict(DiscreteTendon tendon, bool normalizeInputs = true)
        {
            double[] inputs = new double[5];
            if (tendon.IsFullTendon())
            {
                FullTendon fullTendon = tendon.GetFullTendon();
                inputs[0] = fullTendon.PointA.Z;
                inputs[1] = fullTendon.PointB.X;
                inputs[2] = fullTendon.PointB.Z;
                inputs[3] = fullTendon.PointC.Z;
                inputs[4] = fullTendon.SupportRadius;
            }
            else if (tendon.IsPartialTendon())
            {
                PartialTendon partialTendon = tendon.GetPartialTendon();
                inputs[0] = partialTendon.PointA.Z;
                inputs[1] = partialTendon.PointB.X;
                inputs[2] = partialTendon.PointB.Z;
                inputs[3] = partialTendon.PointC.Z;
                inputs[4] = partialTendon.SupportRadius;
            }
            else
            {
                return(new List <double>());
            }

            return(Predict(inputs, normalizeInputs));
        }
        public TendonNeuralNetwork(AnalyticalBridge analyticalBridge)
        {
            foreach (PrestressingCaseResult result in analyticalBridge.PrestressingCaseResults)
            {
                if (result.DiscreteTendon.IsFullTendon())
                {
                    FullTendon fullTendon    = result.DiscreteTendon.GetFullTendon();
                    double[]   tendonOutputs = new double[result.MY.Count()];
                    foreach (double my in result.MY)
                    {
                        tendonOutputs[result.MY.IndexOf(my)] = my;
                    }
                    AddMember(new double[5] {
                        fullTendon.PointA.Z, fullTendon.PointB.X, fullTendon.PointB.Z, fullTendon.PointC.Z, fullTendon.SupportRadius
                    }, tendonOutputs);
                }
                else if (result.DiscreteTendon.IsPartialTendon())
                {
                    PartialTendon partialTendon = result.DiscreteTendon.GetPartialTendon();
                    double[]      tendonOutputs = new double[result.MY.Count()];
                    foreach (double my in result.MY)
                    {
                        tendonOutputs[result.MY.IndexOf(my)] = my;
                    }
                    AddMember(new double[5] {
                        partialTendon.PointA.Z, partialTendon.PointB.X, partialTendon.PointB.Z, partialTendon.PointC.Z, partialTendon.SupportRadius
                    }, tendonOutputs);
                }
            }
            NumberOfHiddenUnits = int.Parse(analyticalBridge.PhysicalBridge.DataForm.DataFormHiddenUnits.Text);
            MaxNumberOfEpochs   = int.Parse(analyticalBridge.PhysicalBridge.DataForm.DataFormMaxEpochs.Text);
            LearnRate           = double.Parse(analyticalBridge.PhysicalBridge.DataForm.DataFormLearnRate.Text);

            double errorTreshold = double.Parse(analyticalBridge.PhysicalBridge.DataForm.DataFormErrorTreshold.Text);
            double error         = errorTreshold + 1.000000;

            TimeElapsed = new Stopwatch();
            TimeElapsed.Start();
            Logs = analyticalBridge.PhysicalBridge.Directory + Globals.TextFiles.NeuralNetworkLogs;

            Initialize(int.Parse(analyticalBridge.PhysicalBridge.DataForm.DataFormTestSetSize.Text));
            int epochs = 100;

            for (int epoch = 0; epoch < MaxNumberOfEpochs; epoch += epochs)
            {
                if (error <= errorTreshold)
                {
                    break;
                }
                if (TotalEpochs >= MaxNumberOfEpochs)
                {
                    break;
                }
                error = Train(epochs, errorTreshold);
            }
            PrintSummary();
        }