2019年1月2日 星期三

尤拉方法 常微分

C++ Coding - Euler's Method

Question
Consider an initial value ODE of the following form
dy-
dx = f (x,y),
x ∈ [a,b] and y (a ) = α
write a function to return the value of y at x=b given
            3x
f (x, y) = xe  −  2y,
a = 0,   b = 1, and α = 0
For this example we are going to implement the Euler method as given by
w0  = α
xi = a + ih, and h = b-−-a
                       n
wi+1 = wi + hf (xi,wi), for i = 0,1,...,n − 1
where w at the nth step gives an estimate for the value of y at x=b.
As with all programs we start by thinking about what are the parameters and local variables in the problem. It is clear from the specification here that the parameters are a, b, n, as well as the function to be integrated itself although as we are not interested in writing a generic algorithm we can ignore the last one. Start with an empty program with libraries for input/output to screen/file and mathematical functions.

#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

double eulersMethod(int n,double a,double b,double alpha)
{
  // local variables
  double h,x,w;
  // intialise values
  h=(b-a)/(double)(n);
  x=a;
  w=alpha;
  // implement Euler's method
  for(int i=0;i<n;i++)
  {
    x = a + i*h; // update value of x to x_i
    w = w + h*(x*exp(3.*x)-2.*w); // update w to w_{i+1}
  }
  return w;
}

int main()
{
  
  // evaulate the convergence of the method
  // using an empirical method, relies on there
  // being smooth convergence
  // ratio between number of steps at each stage
  int k=4;
  
  // store previous values and differences
  double valueOld=1.,diffOld=1.;
  for(int i=1;i<=10;i++)
  {
    int n=pow(k,i);
    // calculate value with n
    double value = eulersMethod(n,0.,1.,0.);
    // and difference from last time
    double diff=value-valueOld;
    // calculate R
    double R=diffOld/diff;
    // can show that R = k^c where c is convergence rate
    double c=log(R)/log(k);
    // use c to estimate A
    double A=pow(n,c)/(1-pow(k,c))*diff;
    // output stage, steps, value, constant A, ratio R, convergence rate c and error
    cout << i << " " << n << " " << value << " " << A << " " << R << " " << c << " " << fabs(A/pow(n,c)) <<endl;
    
    // store old values
    valueOld = value;
    diffOld = diff;
  }
//   output from this code
//   1 4 2.09213 11.8537 0.915638 -0.063575 12.9459
//   2 16 2.93241 -4.73586 1.29973 0.189106 2.80345
//   3 64 3.14744 -4.41281 3.90769 0.983158 0.0739528
//   4 256 3.20119 -4.58885 4.00079 1.00014 0.0179111
//   5 1024 3.21462 -4.59139 4.00162 1.00029 0.00447473
//   6 4096 3.21798 -4.58666 4.00049 1.00009 0.00111896
//   7 16384 3.21882 -4.58472 4.00013 1.00002 0.000279766
//   8 65536 3.21903 -4.58409 4.00003 1.00001 6.99432e-05
//   9 262144 3.21908 -4.58391 4.00001 1 1.74859e-05
//   10 1048576 3.21909 -4.58385 4 1 4.37148e-06 
  return 0;
}




輸出結果

1 4 2.09213 11.8537 0.915638 -0.063575 12.9459
2 16 2.93241 -4.73586 1.29973 0.189106 2.80345
3 64 3.14744 -4.41281 3.90769 0.983158 0.0739528
4 256 3.20119 -4.58885 4.00079 1.00014 0.0179111
5 1024 3.21462 -4.59139 4.00162 1.00029 0.00447473
6 4096 3.21798 -4.58666 4.00049 1.00009 0.00111896
7 16384 3.21882 -4.58472 4.00013 1.00002 0.000279766
8 65536 3.21903 -4.58409 4.00003 1.00001 6.99432e-05
9 262144 3.21908 -4.58391 4.00001 1 1.74859e-05
10 1048576 3.21909 -4.58385 4 1 4.37148e-06


沒有留言:

張貼留言

FUXA + WOKWI ESP32 (1)

FUXA 是一款基於 Web 的開源工業視覺化軟體(SCADA/HMI) ,能讓使用者透過瀏覽器快速搭建工業監控儀表板、連線 PLC 設備與物聯網裝置。 核心操作 5 大步驟 要讓 FUXA 成功運作並顯示數據,請遵循以下核心流程:   1. 配置設備連線(Devices) 點擊...