public static double ComplexNMCProcess(MFCMData currentStateData)
        {
            if (m_complexCmp != null)
            {
                var processData = new double[NIn];
                var processResult = new double[NOut];

                processData[0] = currentStateData.CarbonMonoxideVolumePercent;
                processData[1] = currentStateData.CarbonOxideVolumePercent;
                processData[2] = currentStateData.HeightLanceCentimeters;
                processData[3] = currentStateData.OxygenVolumeRate;

                alglib.mlpprocess(m_complexCmp, processData, ref processResult);

                return processResult[0];
            }
            return -0.1133;
        }
        public static double MultiFactorCarbonMass(List<MFCMData> matrixStateData, MFCMData currentStateData)
        {
            const int nFeatures = 4;
            int nFeaturesCoefficcients;
            int info = 0;
            var inVector = new double[matrixStateData.Count, nFeatures+1];
            double[] coefficcients;
            var lm = new alglib.linearmodel();
            var lr = new alglib.lrreport();

            int lenghtData = matrixStateData.Count;
            for (int item = 0; item < lenghtData; item++)
            {
                inVector[item, 0] = matrixStateData[item].CarbonMonoxideVolumePercent; // X1
                inVector[item, 1] = matrixStateData[item].CarbonOxideVolumePercent;    // X2
                inVector[item, 2] = matrixStateData[item].HeightLanceCentimeters;      // X3
                inVector[item, 3] = matrixStateData[item].OxygenVolumeRate;            // X4
                inVector[item, 4] = matrixStateData[item].SteelCarbonPercent;          // Y
            }

            alglib.lrbuild(inVector, lenghtData, nFeatures, out info, out lm, out lr);
            if (info != 1)
            {
                return info;
            }
            alglib.lrunpack(lm, out coefficcients, out nFeaturesCoefficcients);
            if (nFeaturesCoefficcients != nFeatures)
            {
                return -2.011;
            }
            double calculatedCarbon = coefficcients[4];
            calculatedCarbon += coefficcients[0] * currentStateData.CarbonMonoxideVolumePercent;
            calculatedCarbon += coefficcients[1] * currentStateData.CarbonOxideVolumePercent;
            calculatedCarbon += coefficcients[2] * currentStateData.HeightLanceCentimeters;
            calculatedCarbon += coefficcients[3] * currentStateData.OxygenVolumeRate;
            return calculatedCarbon;
        }
        private void btnCalcMultiFactor_Click(object sender, EventArgs e)
        {
            if (m_matrixDataCorrect && BacklightMatrixinputs()) {
                List<MFCMData> matrixStateData = new List<MFCMData>();
                var currentStateData = new MFCMData();

                for (int row = 0; row < dGMatrixState.RowCount; row++) {
                    matrixStateData.Add(new MFCMData());

                    matrixStateData[row].CarbonMonoxideVolumePercent =
                        Convertion.StrToDouble(dGMatrixState.Rows[row].Cells[2].Value.ToString());

                    matrixStateData[row].HeightLanceCentimeters =
                        Convertion.StrToInt32(dGMatrixState.Rows[row].Cells[3].Value.ToString());

                    matrixStateData[row].OxygenVolumeRate =
                        Convertion.StrToDouble(dGMatrixState.Rows[row].Cells[4].Value.ToString());

                    matrixStateData[row].SteelCarbonPercent =
                        Convertion.StrToDouble(dGMatrixState.Rows[row].Cells[5].Value.ToString());
                }
                currentStateData.CarbonMonoxideVolumePercent = Convertion.StrToDouble(txbMatrixCO.Text);
                currentStateData.HeightLanceCentimeters = Convertion.StrToInt32(txbMatrixLance.Text);
                currentStateData.OxygenVolumeRate = Convertion.StrToDouble(txbMatrixOxigenVolumeRate.Text);
                lblMatrixCarbone.Text =
                    Decarbonater.MultiFactorCarbonMass(matrixStateData, currentStateData).ToString().Substring(0, 8);
            }
        }
        public static void Iterate(HeatData heatData)
        {
            using (var l = new Logger("Iterate")) {
                var calculatedCarboneEvent = new CalculatedCarboneEvent();
                if (!TotalCarbonMassCalculated) {
                    if (
                        (heatData.IronMass > 0) &&
                        (heatData.IronCarbonPercent > 0) &&
                        (heatData.ScrapMass > 0) &&
                        (heatData.ScrapCarbonPercent > 0) &&
                        (heatData.SteelCarbonPercent > 0)
                        ) {
                        TotalCarbonMass = Decarbonater.HeatCarbonMass(
                            heatData.IronMass,
                            heatData.IronCarbonPercent,
                            heatData.ScrapMass,
                            heatData.ScrapCarbonPercent,
                            heatData.SteelCarbonPercent
                            );
                        RemainCarbonMass = TotalCarbonMass;
                        RemainCarbonPercent = GetCarbonPercent(RemainCarbonMass, heatData.IronMass,
                                                               heatData.IronCarbonPercent,
                                                               heatData.ScrapMass, heatData.ScrapCarbonPercent);
                        if (TotalCarbonMass > 0 && heatData.OxygenVolumeRate > 0) {
                            TotalCarbonMassCalculated = true;
                            l.msg("##### [TotalCarbonMassCalculated: {0}][RemainCarbonPercent]", TotalCarbonMass,
                                  RemainCarbonPercent);
                        }
                        else
                            l.msg("HeatCarbonMass returned bad result: {0}", TotalCarbonMass);
                    }
                    else {
                        l.err(
                            "bad data for HeatCarbonMass [IronMass: {0}][IronCarbonPercent: {1}][ScrapMass: {2}][ScrapCarbonPercent: {3}][SteelCarbonPercent: {4}]",
                            heatData.IronMass,
                            heatData.IronCarbonPercent,
                            heatData.ScrapMass,
                            heatData.ScrapCarbonPercent,
                            heatData.SteelCarbonPercent
                            );
                    }
                }
                else if (!GasCarbonMassFinished) {
                    heatData.DeltaT = m_sw.ElapsedMilliseconds*0.001;
                    m_sw.Restart();

                    if (
                        (heatData.CarbonMonoxideVolumePercent > 0) &&
                        (heatData.OffgasVolumeRate > 0) &&
                        (heatData.DeltaT > 0) &&
                        (heatData.Kgasan > 0)
                        ) {
                        double GCMResult = Decarbonater.GasanCarbonMass(
                            heatData.CarbonMonoxideVolumePercent,
                            heatData.OffgasVolumeRate,
                            heatData.DeltaT,
                            heatData.Kgasan
                            );
                        if (GCMResult >= 0) {
                            if (heatData.OxygenVolumeRate > 0)
                                RemainCarbonMass -= GCMResult; //////////////////////////////
                        }
                        else
                            l.err("GasanCarbonMass return bad result: {0}", GCMResult);
                        if (
                            (RemainCarbonMass > 0) &&
                            (heatData.IronMass > 0) &&
                            (heatData.IronCarbonPercent > 0) &&
                            (heatData.ScrapMass > 0) &&
                            (heatData.ScrapCarbonPercent > 0)
                            ) {
                            RemainCarbonPercent = GetCarbonPercent(
                                RemainCarbonMass,
                                heatData.IronMass,
                                heatData.IronCarbonPercent,
                                heatData.ScrapMass,
                                heatData.ScrapCarbonPercent
                                );
                        }
                        else {
                            l.err(
                                "bad data for GetCarbonPercent [RemainCarbonMass: {0}][IronMass: {1}][IronCarbonPercent: {2}][ScrapMass: {3}][ScrapCarbonPercent: {4}]",
                                RemainCarbonMass,
                                heatData.IronMass,
                                heatData.IronCarbonPercent,
                                heatData.ScrapMass,
                                heatData.ScrapCarbonPercent
                                );
                        }

                        GasCarbonMassFinished = VerifyGasCarbonFinished(
                            heatData.OxygenVolumeTotal,
                            heatData.OxygenVolumeCurrent,
                            TotalCarbonMass, RemainCarbonMass,
                            heatData.CarbonMonoxideVolumePercent,
                            heatData.CarbonMonoxideVolumePercentPrevious,
                            heatData.CarbonOxideVolumePercent,
                            heatData.CarbonOxideVolumePercentPrevious
                            );
                    }
                    else {
                        l.err(
                            "bad data for GasanCarbonMass [CarbonMonoxideVolumePercent: {0}][OffgasVolumeRate: {1}][DeltaT: {2}][Kgasan: {3}]",
                            heatData.CarbonMonoxideVolumePercent,
                            heatData.OffgasVolumeRate,
                            heatData.DeltaT,
                            heatData.Kgasan
                            );
                    }
                }
                else {
                    var currentStateData = new MFCMData {
                                                            CarbonMonoxideVolumePercent =
                                                                heatData.CarbonMonoxideVolumePercent,
                                                            CarbonOxideVolumePercent = heatData.CarbonOxideVolumePercent,
                                                            HeightLanceCentimeters = heatData.HeightLanceCentimeters,
                                                            OxygenVolumeRate = heatData.OxygenVolumeRate
                                                        };
                    //MFMChooser
                    //var CMCarbon = Decarbonater.MultiFactorCarbonMass(heatData.MatrixStateData, currentStateData);
                    m_currentMatrix = MFMChooser(heatData);
                    var matrixStateData =
                        Program.MFCMDataGenerate(Program.MatrixStateDataFull[m_currentMatrix].MatrixList);
                    var CMCarbon = Decarbonater.MultiFactorCarbonMass(matrixStateData, currentStateData);
                    //if (CMCarbon < RemainCarbonPercent) RemainCarbonPercent = CMCarbon;
                    RemainCarbonPercent = CMCarbon;

                    if (MomentFixDataForMFactorModel(heatData.CarbonMonoxideVolumePercent,
                                                     heatData.CarbonOxideVolumePercent)) // фиксируем для обучения
                    {
                        if (m_noFixData) {
                            CurrentHeatResult.OxygenVolumeRate = heatData.OxygenVolumeRate;
                            CurrentHeatResult.SteelCarbonCalculationPercent = RemainCarbonPercent;
                            CurrentHeatResult.CarbonMonoxideVolumePercent = heatData.CarbonMonoxideVolumePercent;
                            CurrentHeatResult.CarbonOxideVolumePercent = heatData.CarbonOxideVolumePercent;
                            CurrentHeatResult.HeightLanceCentimeters = heatData.HeightLanceCentimeters;
                            CurrentHeatResult.MFMEquationId = m_currentMatrix; // фиксируем матрицу по которой учим
                            EnqueueWaitC(CurrentHeatResult); // ставим в очередь ожидания углерода
                            Program.PushGate.PushEvent(new FixDataMfactorModelEvent());

                            // временная мера для перехода на старый углерод
                            var fex = new ConnectionProvider.FlexHelper("CPlusProcessor.DataFix");
                            fex.Fire(Program.PushGate);
                            Console.WriteLine(fex.evt + "\n");
                            //////////////////////////////////////////////////////////////////////

                            m_noFixData = false;
                        }
                    }
                }
                DataArchSec.SD.Add(new SecondData()); // заполняем для статистики во время плавки
                DataArchSec.SD[DataArchSec.SD.Count - 1].CarboneCalc = RemainCarbonPercent;
                DataArchSec.SD[DataArchSec.SD.Count - 1].Time = DateTime.Now.ToString();
                DataArchSec.SD[DataArchSec.SD.Count - 1].CarboneMonoxide = heatData.CarbonMonoxideVolumePercent;
                DataArchSec.SD[DataArchSec.SD.Count - 1].CarboneOxide = heatData.CarbonOxideVolumePercent;
                DataArchSec.SD[DataArchSec.SD.Count - 1].HeightLance = heatData.HeightLanceCentimeters;
                DataArchSec.SD[DataArchSec.SD.Count - 1].OxygenVolumeCurrent = heatData.OxygenVolumeCurrent;
                //
                if (!GasCarbonMassFinished) {
                    DataArchSec.SD[DataArchSec.SD.Count - 1].Model = "Gas Analise Mono factor Model";
                    l.msg("Gas Analise Mono factor Model");
                }
                else {
                    DataArchSec.SD[DataArchSec.SD.Count - 1].Model = "Multi Factor Model";
                    l.msg("Multi Factor Model № {0}", m_currentMatrix);
                }
                calculatedCarboneEvent.CarbonePercent = RemainCarbonPercent;
                calculatedCarboneEvent.CarboneMass = RemainCarbonMass;
                calculatedCarboneEvent.model = DataArchSec.SD[DataArchSec.SD.Count - 1].Model;
                Program.PushGate.PushEvent(calculatedCarboneEvent);
                //Program.PushGate.PushEvent(new CalculatedCarboneEvent());

                // временная мера для перехода на старый углерод
                var fex2 = new ConnectionProvider.FlexHelper("CPlusProcessor.Result");
                fex2.AddArg("C", RemainCarbonPercent);
                fex2.Fire(Program.PushGate);
                //////////////////////////////////////////////////////////////////////
            }
        }
        public static void Iterate(HeatData heatData)
        {
            using (var l = new Logger("Iterate")) {
                if (ModelIsStarted) {
                    var currentStateData = new MFCMData {
                                                            CarbonMonoxideVolumePercent =
                                                                heatData.CarbonMonoxideVolumePercent,
                                                            CarbonOxideVolumePercent = heatData.CarbonOxideVolumePercent,
                                                            HeightLanceCentimeters = heatData.HeightLanceCentimeters,
                                                            OxygenVolumeRate = heatData.OxygenVolumeRate
                                                        };

                    m_currentMatrix = MFMChooser(heatData);
                    var matrixStateData =
                        Program.MFCMDataGenerate(Program.MatrixStateDataFull[m_currentMatrix].MatrixList);
                    var CMCarbon = Decarbonater.MultiFactorCarbonMass(matrixStateData, currentStateData);
                    //if (CMCarbon < RemainCarbonPercent) RemainCarbonPercent = CMCarbon;
                    RemainCarbonPercent = CMCarbon;

                    var fex2 = new ConnectionProvider.FlexHelper("SMFCarbon.Result");
                    fex2.AddArg("C", RemainCarbonPercent);
                    fex2.Fire(Program.PushGate);

                    Console.CursorTop = Console.CursorTop - 1;
                    Console.WriteLine("                                                   ");
                    Console.CursorTop = Console.CursorTop - 1;
                    Console.WriteLine("Carbon = " + RemainCarbonPercent + "%");

                    if (MomentFixDataForMFactorModel(heatData.CarbonMonoxideVolumePercent,
                                                     heatData.CarbonOxideVolumePercent)) // фиксируем для обучения
                    {
                        if (!m_dataIsFixed) {
                            CurrentHeatResult.OxygenVolumeRate = heatData.OxygenVolumeRate;
                            CurrentHeatResult.SteelCarbonCalculationPercent = RemainCarbonPercent;
                            CurrentHeatResult.CarbonMonoxideVolumePercent = heatData.CarbonMonoxideVolumePercent;
                            CurrentHeatResult.CarbonOxideVolumePercent = heatData.CarbonOxideVolumePercent;
                            CurrentHeatResult.HeightLanceCentimeters = heatData.HeightLanceCentimeters;
                            CurrentHeatResult.MFMEquationId = m_currentMatrix; // фиксируем матрицу по которой учим
                            EnqueueWaitC(CurrentHeatResult); // ставим в очередь ожидания углерода

                            var fex = new ConnectionProvider.FlexHelper("SMFCarbon.DataFix");
                            fex.AddArg("C", RemainCarbonPercent);
                            fex.Fire(Program.PushGate);
                            l.msg(fex.evt + "\n");

                            m_dataIsFixed = true;
                        }
                    }
                }
                else {
                    ModelIsStarted = ModelVerifiForStart(
                        heatData.OxygenVolumeTotal,
                        heatData.OxygenVolumeCurrent,
                        heatData.CarbonMonoxideVolumePercent,
                        heatData.CarbonMonoxideVolumePercentPrevious,
                        heatData.CarbonOxideVolumePercent,
                        heatData.CarbonOxideVolumePercentPrevious
                        );
                    if (ModelIsStarted) {
                        var fex = new ConnectionProvider.FlexHelper("SMFCarbon.ModelIsStarted");
                        fex.Fire(Program.PushGate);
                        l.msg(fex.evt + "\n");
                    }
                    Console.Write(".");
                }
            }
        }
        public static void Iterate(HeatData heatData)
        {
            using (var l = new Logger("Iterate")) {
                var calculatedCarboneEvent = new CalculatedCarboneEvent();

                var currentStateData = new MFCMData {
                                                        CarbonMonoxideVolumePercent =
                                                            heatData.CarbonMonoxideVolumePercent,
                                                        CarbonOxideVolumePercent = heatData.CarbonOxideVolumePercent,
                                                        HeightLanceCentimeters = heatData.HeightLanceCentimeters,
                                                        OxygenVolumeRate = heatData.OxygenVolumeRate
                                                    };
                //RemainCarbonPercent = Decarbonater.ComplexNMCProcess(heatData.MatrixStateData, currentStateData);
                RemainCarbonPercent = Decarbonater.ComplexNMCProcess(currentStateData);

                if (MomentFixDataForMFactorModel(heatData.OxygenVolumeCurrent, heatData.OxygenVolumeTotal,
                                                 heatData.CarbonMonoxideVolumePercent, heatData.CarbonOxideVolumePercent))
                    // фиксируем для обучения
                {
                    if (m_noFixData) {
                        CurrentHeatResult.OxygenVolumeRate = heatData.OxygenVolumeRate;
                        CurrentHeatResult.SteelCarbonCalculationPercent = RemainCarbonPercent;
                        CurrentHeatResult.CarbonMonoxideVolumePercent = heatData.CarbonMonoxideVolumePercent;
                        CurrentHeatResult.CarbonOxideVolumePercent = heatData.CarbonOxideVolumePercent;
                        CurrentHeatResult.HeightLanceCentimeters = heatData.HeightLanceCentimeters;
                        EnqueueWaitC(CurrentHeatResult); // ставим в очередь ожидания углерода
                        //Program.PushGate.PushEvent(new FixDataMfactorModelEvent());
                        FireFixEvent(RemainCarbonPercent);
                        m_noFixData = false;
                    }
                }

                ModelIsStarted = ModelVerifiForStart(heatData.OxygenVolumeCurrent, heatData.CarbonMonoxideVolumePercent,
                                                     heatData.CarbonOxideVolumePercent);
                if (ModelIsStarted) FireStartEvent();
                calculatedCarboneEvent.model = "Complex neural Model";
                calculatedCarboneEvent.CarbonePercent = RemainCarbonPercent;
                calculatedCarboneEvent.CarboneMass = RemainCarbonMass;
                var fex = new ConnectionProvider.FlexHelper("NeuralProcessorC.Calc");
                fex.AddArg("TypeNeural", "non linear");
                fex.AddArg("C", RemainCarbonPercent);
                fex.Fire(Program.PushGate);

                FireResultCarbonEvent();

                //l.msg("fired carbon:\n{0}",fex.evt.ToString());
                //Program.PushGate.PushEvent(calculatedCarboneEvent);
                //Program.PushGate.PushEvent(new CalculatedCarboneEvent());
            }
        }