Exemplo n.º 1
0
        public static RationalFunction ConvertToRationalFunction(this alglib.barycentricinterpolant function)
        {
            if (function == null)
            {
                throw new ArgumentNullException();
            }

            var n = function.innerobj.n;

            if (n <= 2)
            {
                // linear function, let's convert it to that form for simplicity
                double[] coefficients;
                alglib.polynomialbar2pow(function, out coefficients);

                return(RationalFunction.BuildPolynomial(coefficients.Select(x => (float)x).ToArray()));
            }
            else
            {
                // maintain barycentric representation
                var w = ConvertToFloatArray(function.innerobj.w, n);
                var x = ConvertToFloatArray(function.innerobj.x, n);
                var y = ConvertToFloatArray(function.innerobj.y, n);

                return(RationalFunction.BuildBarycentric(w, x, y, (float)function.innerobj.sy));
            }
        }
Exemplo n.º 2
0
        private void button_calculate_Click(object sender, EventArgs e)
        {
            Reading = false;

            alglib.barycentricinterpolant p;
            alglib.polynomialfitreport    rep;
            p   = new alglib.barycentricinterpolant();
            rep = new alglib.polynomialfitreport();
            double[] a_start, a_rest, a_itog;
            int      m     = Points_table.STEP_POLINOM;
            int      m_cur = Points_table.STEP_POLINOM_CURRENT;
            // double t = 0.1;
            int info = 0;

            // double v = 0;
            double[] x = new double[dataGridView1.RowCount - 1];
            double[] y = new double[dataGridView1.RowCount - 1];

            int koeff = (Termo.high + Math.Abs(Termo.low)) / Termo.step + 1;


            double[] Y_user    = new double[koeff]; // пользовательские
            double[] Y_restore = new double[koeff]; // восстановленные
            double[] Y_norm    = new double[koeff]; // нормированные по p25
            double[] Y_itog    = new double[koeff]; // итоговые
            //double[] yitog_calc = new double[koeff];

            // массив Stock_koeff - c заводскими значениями, переведёнными в double
            double[] Current_koeff = new double[Termo.polinom_termo_correct.Length];
            for (int i = 0; i < Current_koeff.Length; i++)
            {
                Current_koeff[i] = Convert.ToDouble(dataGridView2.Rows[i].Cells[1].Value);
            }

            Points_table.Table_yitog.Clear();
            Points_table.Table_restore.Clear();
            itog_poly.Clear();
            try
            {
                for (int i = 0; i < dataGridView1.RowCount - 1; i++)
                {
                    x[i] = (double)dataGridView1.Rows[i].Cells[1].Value;
                    y[i] = (double)dataGridView1.Rows[i].Cells[2].Value;
                }


                // 1. Приводим F в период Р = 1 / F и сохраняем в массиве
                double[] P = new double[dataGridView1.RowCount - 1];
                for (int i = 0; i < P.Length; i++)
                {
                    if (Points_table.f)
                    {
                        P[i] = 14745600 / y[i];
                    }
                    else
                    {
                        P[i] =
                            (14745600 / Points_table.Fmax) + ((y[i] / Points_table.Diap)
                                                              * (14745600 / Points_table.Fmin - 14745600 / Points_table.Fmax));
                        P[i] = P[i] / polinom_calc(x[i], Current_koeff);
                    }
                }
                // 2. Получаем коэффициенты полинома а_start
                alglib.polynomialfit(x, P, m, out info, out p, out rep);
                alglib.polynomialbar2pow(p, out a_start);

                // 3. Вычисляем y_user по пользовательским данным и заносим значения в таблицу
                int itest = Termo.low;
                for (int i = 0; itest <= Termo.high; i++)
                {
                    Y_user[i] = polinom_calc(itest, a_start);
                    itest    += Termo.step;
                }
                itest = Termo.low;

                // 4. Получаем Pвосстановленное = (Pi * полином(Aтек, Ti))

                double P25 = polinom_calc(25, a_start);

                // 5. Нормируем Y : Y_norm = P25 / Y_user если в диапазоне пользователя, иначе Y_norm по полиному текущих значений
                // 6. Получаем Y восстановленное: Y_restore = Y_user если в диапазоне пользователя, иначе Y_restore = P25 / значение по полиному текущих значений

                for (int i = 0; itest <= Termo.high; i++)
                {
                    DUTConfig_V3.Forms.etc.Point temp = new DUTConfig_V3.Forms.etc.Point();

                    if (itest >= x[0] && itest <= x[x.Length - 1])
                    {
                        Y_restore[i] = Y_user[i];
                        //Y_norm[i] = P25 / Y_user[i];
                    }
                    else
                    {
                        Y_restore[i] = P25 / polinom_calc(itest, Current_koeff);
                        //Y_norm[i] = polinom_calc(itest, Current_koeff);
                    }
                    temp.number = i + 1;
                    temp.x      = itest;
                    temp.y      = Y_restore[i];
                    Points_table.Table_restore.Add(temp);
                    itest += Termo.step;
                }
                itest = Termo.low;
                // массив значений X на интервале от Termo.low до Termo.high c шагом Termo.step
                double[] Xes = new double[koeff];
                for (int i = 0; i < Xes.Length; i++)
                {
                    Xes[i] = Termo.low + i * Termo.step;
                }

                // 7. Получаем коэффициенты восстановленного полинома, прогоняем калькуляцией полинома Y_restore для уточнения данных
                alglib.polynomialfit(Xes, Y_restore, m, out info, out p, out rep);
                alglib.polynomialbar2pow(p, out a_rest);
                for (int i = 0; itest <= Termo.high; i++)
                {
                    Y_restore[i] = polinom_calc(itest, a_rest);
                    Y_norm[i]    = polinom_calc(25, a_rest) / Y_restore[i];
                    itest       += Termo.step;
                    Points_table.Table_restore[i].y = 14745600 / Y_restore[i];
                }
                itest = Termo.low;

                // 8. Получаем коэффициенты итогового полинома
                alglib.polynomialfit(Xes, Y_norm, m_cur, out info, out p, out rep);
                alglib.polynomialbar2pow(p, out a_itog);

                // 9. Получаем массив Y_itog, с помощью его и массива Y_restore получаем точки графика
                for (int i = 0; itest <= Termo.high; i++)
                {
                    Y_itog[i] = polinom_calc(itest, a_itog);
                    DUTConfig_V3.Forms.etc.Point temp2 = new DUTConfig_V3.Forms.etc.Point();
                    temp2.number = i + 1;
                    temp2.x      = itest;
                    temp2.y      = Y_itog[i] * Y_restore[i];
                    temp2.y      = 14745600 / temp2.y;
                    //Y_itog[i] = temp2.y;
                    Points_table.Table_yitog.Add(temp2);
                    itest += Termo.step;
                }
                itest = Termo.low;

                // 10. показываем коэффициенты итогового полинома в текстбоксе на форме
                string s = "";
                for (int i = 0; i < a_itog.Length; i++)
                {
                    s += i + 1 + ": " + a_itog[i] + ";  ";
                    itog_poly.Add(a_itog[i]);
                }
                textBox_a.Text = s;

                // 11. Рисуем графики
                DrawGraph(Points_table);
                button_SMS.Enabled = true;
            }
            catch (Exception)
            {
                MessageBox.Show(currentTranslation.ThermoCalcFailMessage, Properties.Resources.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }