Правильна ли реализация моего метода Эйлера? - PullRequest
1 голос
/ 14 июня 2019

Я пишу код, который должен решить дифференциальное уравнение, которое уже дано по методу Эйлера. После получения результатов я нанесу их на график. Однако я получаю неправильные значения.

Это сделано для получения отклика функции передачи. Я уже пытался написать метод Эйлера иначе (с тем же результатом). Я несколько раз проверял, правильно ли написано мое дифференциальное уравнение. Я хотел бы знать, лежит ли проблема здесь или где-то еще. У меня закончились идеи, что не так с этим кодом.

public static double inputSignal(double t, double A, double f, int typeOfSignal) {

        switch (typeOfSignal) {
            case 1:
                return A*cos(2*Math.PI*f*t);
            case 2:
                return A*(2/Math.PI)*asin(sin(2*Math.PI*f*t));
            case 3:
                return A*signum(sin(2*Math.PI*f*t));
            default:
                break;
        }

        return 0;
    }

public static double equation(double x, double xDerivative, double u, double uDerivative, double a0, double a1, double b0, double b1, double b2) {

        return (a1*uDerivative + a0*u - (a0+b0)*x - (a1+b1)*xDerivative)/b2; 
    }

 public static void eulerMethod(double h, double A, double f, double a0, double a1, double b0, double b1, double b2, int typeOfSignal) {

        double xn = 0, yn = 0, tn = 0, tn1; //x' = y; y' = f(x, y, u)
        double uDerivative;

        for (int i = 0; i < 10000; i++) {
            tn1 = tn + h;
            uDerivative= (inputSignal(tn1+h, A, f, typeOfSignal)-inputSignal(tn1, A, f, typeOfSignal))/h;
            xn = xn + h*equation(xn, yn, pobudzenie(tn1, A, f, typeOfSignal), uDerivative, a0, a1, b0, b1, b2);
            yn = yn + h*xn;
            System.out.println("Step" + i);
            System.out.println("Y(" + tn1 + ") " + " = " + yn);
            tn = tn1;
            results[i] = yn;
            inputGraph[i] = inputSignal(tn, A, f, typeOfSignal);
        }

    }

Дифференциальное уравнение: b2*x'' = a1*u' + a0*u - (a0+b0)*x - (a1+b1)*x'

Что я хочу получить за euler2(0.0025, 1, 0.01, 1, 5, 1, 2, 1, 1) это , но из моего кода я получаю это.

Как вы можете видеть, в моей функции есть нежелательные колебания, и ее амплитуда ниже ожидаемой (она равна 0,2, а должна быть 0,7).

1 Ответ

0 голосов
/ 15 июня 2019

Наиболее вероятная ошибка

Вы что-то перепутали в своей системе первого заказа.У вас есть

x'' = f(t,x,x',u,u')

и установка y=x', это должно привести к системе первого порядка

x' = y
y' = f(t,x,y,u,u')

Однако вы поменяли правые стороны в вычислении обновлений x и y, эффективно меняя уравнение на x''=f(t,x',x,u,u') и отображая x'.

В вашей полуявной реализации Euler правильная реализация метода будет

yn = yn + h*equation(xn, yn, inputSignal(tn1, A, f, typeOfSignal), uDerivative, a0, a1, b0, b1, b2);
xn = xn + h*yn;

В строгой явной реализации Euler вы не будете использовать недавно вычисленный yn в xn обновление, но старое значение.Необходима некоторая переменная временного кэша.


Улучшенная система первого порядка

Вы бы получили более простую систему первого порядка, установив

y=b2*x'+(a1+b1)*x-a1*u

так что тогда

x' = ( y - (a1+b1)*x+a1*u )/b2;
y' = a0*u-(a0+b0)*x

удалит все производные u из системы первого порядка.

Визуальный тест решателя ODE

Если вы создаете график с разными размерами шагов для любой системы, визуальная конвергенция указывает на правильную реализацию.Тогда любое отличие от контрольного графика означает, что, вероятно, существуют различия в ODE, передаваемом вашему решателю здесь и вашему управляющему решателю.

...