以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 Dot NET,C#,ASP,VB 』  (http://bbs.xml.org.cn/list.asp?boardid=43)
----  C#快餐-16  (http://bbs.xml.org.cn/dispbbs.asp?boardid=43&rootid=&id=11730)


--  作者:admin
--  发布时间:11/9/2004 2:25:00 AM

--  C#快餐-16


发信人: nice (春天), 信区: DotNET        
标  题: C#快餐-16
发信站: BBS 水木清华站 (Thu Jul 26 02:20:14 2001)


Lesson 16. Numerical methods in C#.


   In this lesson I will show how to numerically solve algebraic  and ordinary  
differential equations, and perform numerical integration with Simpson method. I will start with the solution of algebraic equations. The secant method  
is one of the simplest methods for solving algebraic equations. It is usually
used as a part of a larger algorithm to improve convergence. As in any  
numerical algorithm, we need to check that the method is converging to a given  
precision in a certain number of steps. This is a precaution to avoid an  
infinite loop.

//secant method

using System;
class Secant
{
    public delegate double Function(double x); //declare a delegate that tak
es double and returns double
    public static void secant(int step_number, double point1,double point2,F
unction f)
    {
        double p2,p1,p0,prec=.0001f; //set precision to .0001
        int i;
        p0=f(point1);
        p1=f(point2);
        p2=p1-f(p1)*(p1-p0)/(f(p1)-f(p0)); //secant formula
        for(i=0;System.Math.Abs(p2)>prec &&i<step_number;i++) //iterate till
precision goal is not met or the maximum //number of steps is reached
        {
            p0=p1;
            p1=p2;
            p2=p1-f(p1)*(p1-p0)/(f(p1)-f(p0));
        }
        if(i<step_number)
            Console.WriteLine(p2); //method converges
        else
            Console.WriteLine("{0}.The method did not converge",p2);//method
does not converge
    }
}
class Demo
{//equation f1(x)==0;
    public static double f1( double x)
    {
        return x*x*x-2*x-5;
    }
    public static void Main()
    {
    Secant.secant(5,0,1,new Secant.Function(f1));
    }
}
Our second example is a Simpson integration algorithm. We have introduced  
numerical integration in our discussion of delegates in Lesson12. The Simpson  
algorithm is more precise the naive integration algorithm I have used there.

The basic idea of the Simpson algorithm is to sample the integrand in a  
number of points to get a better estimate of its variations in a given  
interval. So Simpson method is more precise than the method shown in Lesson12,
however since Simpson method samples more points it is slower.


//Simpson integration algorithm
using System;
//calculate the integral of f(x) between x=a and x=b by spliting the interva
l in step_number steps
class Integral
{
    public delegate double Function(double x); //declare a delegate that tak
es and returns double
    public static double integral(Function f,double a, double b,int step_num
ber)
    {
          double sum=0;
          double step_size=(b-a)/step_number;
         for(int i=0;i<step_number;i=i+2) //Simpson algorithm samples the in
tegrand in several point which significantly improves //precision.
        sum=sum+(f(a+i*step_size)+4*f(a+(i+1)*step_size)+f(a+(i+2)*step_size
))*step_size/3; //divide the area under f(x)     //into step_number rectangl
es and sum their areas
          return sum;
    }
}
class Test
{
    //simple functions to be integrated
    public static double f1( double x)
    {
    return x*x;
    }
    public static double f2(double x)
    {
    return x*x*x;
    }
    public static void Main()
    {//output the value of the integral.
    Console.WriteLine(Integral.integral(new Integral.Function(f1),1,10,20));

    }
}


Finally, let me show a simple code for solving first order ordinary  
differential equations. The code uses a Runge-Kutta method. The simplest
method to solve ODE is to do a Taylor expansion, which is called Euler's  
method. Euler's method approximates the solution with the series of  
consecutive secants. The error in Euler's method is O(h) on every step  
of size h. The Runge-Kutta method has an error O(h^4)


using System;
//fourth order Runge Kutte method for y'=f(t,y);
//solve first order ode in the interval (a,b) with a given initial condition
at x=a and fixed step h.
class Runge{
    public delegate double Function(double t,double y); //declare a delegate
that takes a double and returns
//double
    public static void runge(double a, double b,double value, double step, F
unction f)
    {
          double t,w,k1,k2,k3,k4;
        t=a;
        w=value;
        for(int i=0;i<(b-a)/step;i++){
            k1=step*f(t,w);
            k2=step*f(t+step/2,w+k1/2);
            k3=step*f(t+step/2,w+k2/2);
            k4=step*f(t+step,w+k3);
            w=w+(k1+2*k2+2*k3+k4)/6;
            t=a+i*step;
            Console.WriteLine("{0} {1} ",t,w);
           }
    }
}
class Test
{
    public static double f1(double t, double y)
    {
    return -y+t+1;
    }
    public static void Main()
    {
    Runge.runge(0,1,1,.1f,new Runge.Function(Test.f1));
    }
}

Runge-Kutta methods with a variable step size are often used in practice
since they converge faster than fixed size methods.

--

※ 修改:·walts 於 Jul 26 10:35:59 修改本文·[FROM: 166.111.142.118]
※ 来源:·BBS 水木清华站 smth.org·[FROM: 166.111.176.234]
上一篇
返回上一页
回到目录
回到页首
下一篇



W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
62.500ms