蒙特卡洛自動求函數積分的Javascript(Nodejs)演算法實現與測試

來源:互聯網
上載者:User

用Javascript實現了函數積分的演算法。

從計算結果可以看出,演算法精度受隨機數發生器的影響較大。

 

 

[javascript]
//Monte carro求給定函數的定積分  
//給定一個函數  
function f1(x, xmin, xmax) 

    if (x >= xmin && x <= xmax) 
        return x * x * Math.sqrt(1 + x * x * x) - 1;     

 
function f2(x, xmin, xmax) 

    if (x >= xmin && x <= xmax) 
        return x * Math.log(1 + x);  

 
function f3(x, xmin, xmax) 

    if (x >= xmin && x <= xmax) 
        return Math.sqrt(1 - x * x); 

 
function f4(x, xmin, xmax) 

    if (x >= xmin && x <= xmax) 
        return Math.cos(x) - 0.9; 

 
 
//取得函數的上下極限——其精確度影響很大---由於用於積分,故若y>0,底限0;若y<0,則高限0;若y穿越x軸,則不修改預設極限  
function getLimit(func, xmin, xmax) 
{    
    //邊界極限  
    var t1 = func(xmin, xmin, xmax), t2 = func(xmax, xmin, xmax); 
    var limit = {y0: Math.min(t1, t2), y1: Math.max(t1, t2)};            
    var delta = 1e-3, lastX, lastY; 
    for(var x = xmin, i = 0; x <= xmax; x += delta, i++) 
    {        
        y = func(x, xmin, xmax);             
        if (y < limit.y0) 
            limit.y0 = y;        
        if (y > limit.y1) 
            limit.y1 = y; 
        if (i == 0) 
        { 
            lastX = x; 
            lastY = y; 
        } 
        else 
        { 
            var tx = (lastX + x) / 2; 
            var ty = func(tx, xmin, xmax);           
            if (Math.abs(lastY) > Math.abs(y)) 
            { 
                if (Math.abs(lastY) < Math.abs(ty)) 
                { 
                    lastX = tx; 
                    lastY = ty;              
                    if (ty < 0 && limit.y0 > ty) 
                        limit.y0 = ty; 
                    else if (ty >= 0 && limit.y1 <= ty) 
                        limit.y1 = ty; 
                }                
            }            
            if (Math.abs(lastY) < Math.abs(y)) 
            { 
                if (Math.abs(y) < Math.abs(ty)) 
                { 
                    lastX = tx; 
                    lastY = ty;              
                    if (ty < 0 && limit.y0 > ty) 
                        limit.y0 = ty; 
                    else if (ty >= 0 && limit.y1 <= ty) 
                        limit.y1 = ty; 
                }                
            }                        
        } 
    } 
    if (limit.y0 > 0) 
        limit.y0 = 0; 
    if (limit.y1 < 0) 
        limit.y1 = 0; 
    return limit; 

 
//積分  
function cumulate(func, N, xmin, xmax) 

    var limit = getLimit(func, xmin, xmax); 
    //console.log('Limit=', limit.y0, limit.y1);  
    var x, yr, y; 
    var cntA = 0, cntB = 0; 
    for(var i = 0; i < N; i++) 
    { 
        x = xmin + (xmax - xmin) * Math.random(); 
        yr = limit.y0 + (limit.y1 - limit.y0) * Math.random(); 
        y = func(x, xmin, xmax); 
        if ( y >= 0 && yr >= 0 && yr <= y) 
            cntA++; 
        else 
        if (y <= 0 && yr <= 0 && yr >= y) 
            cntB++; 
    } 
    //console.log('counts=', cntA, cntB);     
    return (cntA - cntB) * (xmax - xmin) * (limit.y1 - limit.y0) / N; 

 
//測試  
var t1, t2; 
var rst; 
var N = 1e7; 
var fs = [f1, f2, f3, f4]; 
var ans = [-0.593682861167513, 0.25, Math.PI/4, -0.058529015192103493347497678369701]; 
for(var i = 0; i < 4; i++) 

    t1 = new Date(); 
    rst = cumulate(fs[i], N, 0, 1); 
    t2 = new Date(); 
    console.log('[', i, ']=', ans[i].toFixed(15), rst.toFixed(15), t2 - t1, 'ms'); 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.