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)); } }
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); } }