Как получить прогноз по полиномиальной кривой? - PullRequest
0 голосов
/ 27 июля 2010

Хорошо, математика - не моя сильная сторона!

У меня есть эти данные, я использовал zunzun.com, чтобы создать пользовательскую полиномиальную кривую для моих данных, которая появилась как y = a + bx1 + cx2 + dx3 + ex4 + fx5

Однако, когда я использую предложенный код:

  double a = -4.2294409347240979E+01;
  double b = 5.5946102161174718E+00;
  double c = -1.3446057748924720E-01;
  double d = 1.5448461146899649E-03;
  double e = -8.2537158069276241E-06;
  double f = 1.7176546321558128E-08;

  temp = f;
  temp = temp * x_in + e;
  temp = temp * x_in + d;
  temp = temp * x_in + c;
  temp = temp * x_in + b;
  temp = temp * x_in + a;
  return temp;

Это дает мне «сумму квадратов абсолютной ошибки»?Скажем, для значения Х 94 я должен получить значение около 60,3, но этот код дает мне -46,152.Я понимаю, что я глуп, и, очевидно, мне не хватает уравнения в конце.Но может ли кто-нибудь помочь мне предсказать мою ценность Y из моего X с этим forumla?График подходит очень хорошо и было бы здорово, если бы вам не пришлось использовать справочную таблицу.

Большое спасибо!

XY
180 200
178 190
176 180
174 170
170 160
168 150
164 140
160 130
154 120
149 110
142 100
134 90
122 80
110 70
92 60
66 50
30 40

Спасибо всем!Код работает сейчас: http://img72.imageshack.us/img72/3705/ps3lrftest.png

Ответы [ 5 ]

1 голос
/ 27 июля 2010

Извините за округление, но вы реализуете;

Y = a + b x + c x ^ 2 + d x ^ 3 + e x ^4 + е * х ^ 5

х = 94х ^ 2 == х х = 8836х ^ 3 == х х х = 830584х ^ 4 == х х х х = 78074896х ^ 5 == х х х х х = 7339040224

A ~ -42,29440934B ~ 05.59461021C ~ -0.134460577D ~ 0,001544846E ~ -0.000008253F ~ 0.000000017

Y = -42,29440934 + 05,59461021 * 94 + -0,134460577 * 8836 + 0,001544846 * 830584 + -0,000008253 * 78074896 + 0,000000017 * 7339040224

Y = -42.29440934 + 525.89335974 - 1188.093658372 + 1283.124370064 - 644.352116688 + 124.763683808

Y = 59.041229212

Не совсем ваш ответ, но с достаточной точностью вы должны быть хорошими.*

1 голос
/ 27 июля 2010

Что бы ни вычислял temp, это не значение y.Но вы так много разобрались :) Это подойдет?

def y(x, coefficients):
    result = 0
    xpower = 1    
    for coeff in coefficients:
        result += xpower*coeff
        xpower *= x    
    return result
0 голосов
/ 25 февраля 2014

Гиперболические уравнения в целом хорошо соответствуют этим данным.Моя личная рекомендация - использовать вместо полинома

«Простое уравнение 21»

http://zunzun.com/Equation/2/Simple/Simple%20Equation%2021/

Но если то, что у вас есть, не работает, то нет особой причины его менять.

Джеймс Филлипс

0 голосов
/ 28 июля 2010

Вот как я написал бы это на Java:

/**
 * Polynomial
 * User: Michael
 * Date: Jul 27, 2010
 * Time: 7:15:41 PM
 */
public class Polynomial
{
    private double [] coeff;

    public Polynomial(double[] coeff)
    {
        if ((coeff == null) || (coeff.length == 0))
            throw new IllegalArgumentException("coefficient array cannot be null or empty");

        this.coeff = new double [coeff.length];
        System.arraycopy(coeff, 0, this.coeff, 0, coeff.length);
    }

    public double eval(double x)
    {
        int numTerms = coeff.length;
        double value = coeff[numTerms-1];

        for (int i = (numTerms-2); i >= 0; --i)
        {
            value += value*x + this.coeff[i];
        }

        return value;
    }

    @Override
    public String toString()
    {
        StringBuilder builder = new StringBuilder(128);

        for (int i = 0; i < (this.coeff.length-1); ++i)
        {
            builder.append("a[").append(i).append("]=").append(this.coeff[i]).append(",");
        }

        builder.append("a[").append(this.coeff.length-1).append("]=").append(this.coeff[this.coeff.length-1]);

        return builder.toString();
    }
}

Вот как я это проверю:

import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
 * PolynomialTest
 * User: Michael
 * Date: Jul 27, 2010
 * Time: 7:26:15 PM
 */
public class PolynomialTest
{
    private static final double [] a =
    {
        -4.2294409347240979E+01,
         5.5946102161174718E+00,
        -1.3446057748924720E-01,
         1.5448461146899649E-03,
        -8.2537158069276241E-06,
         1.7176546321558128E-08,
    };

    private Polynomial p = new Polynomial(a);

    @Test
    public void testEval()
    {
        double x = 94.0;
        double expected = 60.83781703621137;
        double actual = p.eval(x);

        assertEquals(expected, actual, 1.0e-3);
    }

    @Test
    public void testToString()
    {
        String expected = "a[0]=-42.29440934724098,a[1]=5.594610216117472,a[2]=-0.1344605774892472,a[3]=0.0015448461146899649,a[4]=-8.253715806927624E-6,a[5]=1.7176546321558128E-8";
        String actual = p.toString();

        assertEquals(expected, actual);
    }
}
0 голосов
/ 27 июля 2010

Я не знаю, что не так с вашей реализацией, но код, который вы дали, верен. Вы можете написать (используя полином второй степени для простоты):

y = a + b*x + c*x^2

в

y = a + (b + (c)*x)*x

или, что эквивалентно:

temp = c
temp = temp*x + b
temp = temp*x + a
y = temp

Вы просто назначаете выражение в круглых скобках для temp из самого внутреннего и расширяющегося наружу.

Это тот же формат, который вы показали выше. Просто используйте 6 коэффициентов вместо 3. Для более подробной информации об этом методе полиномиальной оценки вы можете прочитать Схема Хорнера в Википедии.

Чтобы проверить, используя Python:

>>> a = -4.2294409347240979E+01
>>> b = 5.5946102161174718E+00
>>> c = -1.3446057748924720E-01
>>> d = 1.5448461146899649E-03
>>> e = -8.2537158069276241E-06
>>> f = 1.7176546321558128E-08
>>> def test(x):
...     t = f
...     t = t*x + e
...     t = t*x + d
...     t = t*x + c
...     t = t*x + b
...     t = t*x + a
...     return t
...
>>> test(94)
60.281114720346885
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...