home > さまざまな言語で数値計算 > 数値積分 >

さまざまな言語で数値計算

Only Do What Only You Can Do

ロンバーグ積分

台形則を使って近似を行ったあと,Richardsonの補外法を用いて近似をより正確にする.

まず, $ T_{1,1} $ から $ T_{n,1} $ を, 台形則を使って求める.
次に, $ T_{2,2} $ から $ T_{n,n} $ まで, 以下の計算を行う.

例題として, $ 4/(1+x^2) $ を $0$ から $1$ まで積分し $\pi$ を求める.

VBScript

Option Explicit

Const PI = 3.14159265359
Const a = 0
Const b = 1

Dim t(6, 6)

'台形則で積分
Dim n: n = 2
Dim i, j
For i = 1 To 6
    Dim h: h = (b - a) / n
    Dim s: s = 0
    Dim x: x = a
    For j = 1 To n - 1
        x = x + h
        s = s + f(x)
    Next
    '結果を保存
    t(i,1) = h * ((f(a) + f(b)) / 2 + s)
    n = n * 2
Next

'Richardsonの補外法
n = 4
For j = 2 To 6
    For i = j To 6
        t(i,j) = t(i, j - 1) + (t(i, j - 1) - t(i - 1, j - 1)) / (n - 1)
        If i = j Then
            '結果を π と比較
            WScript.StdOut.Write Right(Space(2)  & j,                                        2) & " : "
            WScript.StdOut.Write Right(Space(13) & FormatNumber(t(i,j),      10, -1, 0, 0), 13) & ", "
            WScript.StdOut.Write Right(Space(13) & FormatNumber(t(i,j) - PI, 10, -1, 0, 0), 13) & vbNewLine
        End If
    Next
    n = n * 4
Next

Private Function f(x)
    f = 4 / (1 + x * x)
End Function
Z:\>cscript //nologo Z:\0604.vbs
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536, -0.0000000000

JScript

var a = 0
var b = 1

var t = []

// 台形則で積分
var n = 2;
for (var i = 1; i <= 6; i++)
{
    var h = (b - a) / n
    var s = 0
    var x = a
    for (var j = 1; j <= n - 1; j++)
    {
        x += h
        s += f(x)
    }
    // 結果を保存
    t[i]    = []
    t[i][1] = h * ((f(a) + f(b)) / 2 + s)
    n *= 2
}

// Richardsonの補外法
n = 4
for (var j = 2; j <= 6; j++)
{
    for (var i = j; i <= 6; i++)
    {
        t[i][j] = t[i][j - 1] + (t[i][j - 1] - t[i - 1][j - 1]) / (n - 1)
        if (i == j)
        {
            // 結果を π と比較
            WScript.StdOut.Write(("  "            + j                              ).slice( -2) + " : ");
            WScript.StdOut.Write(("             " + t[i][j].toFixed(10)            ).slice(-13) + ", ");
            WScript.StdOut.Write(("             " + (t[i][j] - Math.PI).toFixed(10)).slice(-13) + "\n" );
        }
    }
    n *= 4
}

function f(x)
{
    return 4 / (1 + x * x)
}
Z:\>cscript //nologo Z:\0604.js
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000000
 6 :  3.1415926536, -0.0000000000

PowerShell

function f($x)
{
    4 / (1 + $x * $x)
}

$a = 0
$b = 1

$t = New-Object "double[,]" 7,7

# 台形則で積分
$n = 2;
foreach ($i in 1..6)
{
    $h = ($b - $a) / $n
    $s = 0
    $x = $a
    foreach ($j in 1..($n - 1))
    {
        $x += $h
        $s += (f $x)
    }
    # 結果を保存
    $t[$i,1] = $h * (((f $a) + (f $b)) / 2 + $s)
    $n *= 2
}

# Richardsonの補外法
$n = 4
foreach ($j in 2..6)
{
    foreach ($i in $j..6)
    {
        $t1 = $t[ $i     ,($j - 1)]
        $t2 = $t[($i - 1),($j - 1)]
        $t[$i,$j] = $t1 + ($t1 - $t2) / ($n - 1)
        if ($i -eq $j)
        {
            # 結果を π と比較
            $s = $t[$i,$j]
            Write-Host ([String]::Format("{0,2:D} : {1,13:F10}, {2,13:F10}", $j, $s, ($s - [Math]::PI)))
        }
    }
    $n *= 4;
}
Z:\>powershell -file Z:\0604.ps1
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536,  0.0000000000

Perl

use Math::Trig 'pi';

my $a = 0;
my $b = 1;

my @t = ();

# 台形則で積分
my $n = 2;
for $i (1..6)
{
    my $h = ($b - $a) / $n;
    my $s = 0;
    my $x = $a;
    for $j (1..($n - 1))
    {
        $x += $h;
        $s += f($x);
    }
    # 結果を保存
    $t[$i][1] = $h * ((f($a) + f($b)) / 2 + $s);
    $n *= 2;
}

# Richardsonの補外法
$n = 4;
for $j (2..6)
{
    for $i ($j..6)
    {
        $t[$i][$j] = $t[$i][$j - 1] + ($t[$i][$j - 1] - $t[$i - 1][$j - 1]) / ($n - 1);
        if ($i == $j)
        {
            # 結果を π と比較
            printf("%2d : %13.10f, %13.10f\n", $j, $t[$i][$j], $t[$i][$j] - pi);
        }
    }
    $n *= 4;
}

sub f
{
    my ($x) = @_;
    4 / (1 + $x * $x);
}
Z:\>perl Z:\0604.pl
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536, -0.0000000000

PHP

<?php
$a = 0;
$b = 1;

$t = array();

# 台形則で積分
$n = 2;
foreach (range(1, 6) as $i)
{
    $h = ($b - $a) / $n;
    $s = 0;
    $x = $a;
    foreach (range(1, ($n - 1)) as $j)
    {
        $x += $h;
        $s += f($x);
    }
    # 結果を保存
    $t[$i][1] = $h * ((f($a) + f($b)) / 2 + $s);
    $n *= 2;
}

# Richardsonの補外法
$n = 4;
foreach (range(2, 6) as $j)
{
    foreach (range($j, 6) as $i)
    {
        $t[$i][$j] = $t[$i][$j - 1] + ($t[$i][$j - 1] - $t[$i - 1][$j - 1]) / ($n - 1);
        if ($i == $j)
        {
            # 結果を π と比較
            printf("%2d : %13.10f, %13.10f\n", $j, $t[$i][$j], $t[$i][$j] - M_PI);
        }
    }
    $n *= 4;
}

function f($x)
{
    return 4 / (1 + $x * $x);
}
?>
Z:\>php Z:\0604.php
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536, -0.0000000000

Python

# coding: Shift_JIS

import math

def f(x):
    return 4 / (1 + x * x)

a = 0
b = 1

t = [[0 for j in range(7)] for i in range(7)]

# 台形則で積分
n = 2
for i in range(1, 7):
    h = (b - a) / float(n)
    s = 0
    x = a
    for j in range(1, n):
        x += h
        s += f(x)
    # 結果を保存
    t[i][1] = h * ((f(a) + f(b)) / 2 + s)
    n *= 2

# Richardsonの補外法
n = 4
for j in range(2, 7):
    for i in range(j, 7):
        t[i][j] = t[i][j - 1] + (t[i][j - 1] - t[i - 1][j - 1]) / (n - 1)
        if (i == j):
            # 結果を π と比較
            print "%2d : %13.10f, %13.10f" % (j, t[i][j], t[i][j] - math.pi)
    n *= 4
Z:\>python Z:\0604.py
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536, -0.0000000000

Ruby

def f(x)
    4 / (1 + x * x)
end

a = 0
b = 1

t = Array.new(7) { Array.new(7) }

# 台形則で積分
n = 2
(1..6).each do |i|
    h = (b - a) / n.to_f
    s = 0
    x = a
    (1..(n - 1)).each do |j|
        x += h
        s += f(x)
    end
    # 結果を保存
    t[i][1] = h * ((f(a) + f(b)) / 2 + s)
    n *= 2
end

# Richardsonの補外法
n = 4
(2..6).each do |j|
    (j..6).each do |i|
        t[i][j] = t[i][j - 1] + (t[i][j - 1] - t[i - 1][j - 1]) / (n - 1)
        if i == j
            # 結果を π と比較
            printf("%2d : %13.10f, %13.10f\n", j, t[i][j], t[i][j] - Math::PI)
        end
    end
    n *= 4
end
Z:\>ruby Z:\0604.rb
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536, -0.0000000000

Groovy

Pascal

program Pas0604(arg);
{$MODE delphi}

uses
    SysUtils, Math;

function f(x:Double):Double;
begin
    result := 4 / (1 + x * x);
end;

const
    a:Double = 0;
    b:Double = 1;
var
    n, i, j:Integer;
    h, s, x:Double;
    t:array [1..6, 1..6] of Double;
begin
    // 台形則で積分
    n := 2;
    for i := 1 to 6 do
    begin
        h := (b - a) / n;
        s := 0;
        x := a;
        for j := 1 to n - 1 do
        begin
            x := x + h;
            s := s + f(x);
        end;
        // 結果を保存
        t[i,1] := h * ((f(a) + f(b)) / 2 + s);
        n      := n * 2;
    end;

    // Richardsonの補外法
    n := 4;
    for j := 2 to 6 do
    begin
        for i := j to 6 do
        begin
            t[i,j] := t[i, j - 1] + (t[i, j - 1] - t[i - 1, j - 1]) / (n - 1);
            if i = j then
            begin
                // 結果を π と比較
                writeln(format('%2d : %13.10f, %13.10f', [j, t[i,j], t[i,j] - PI]));
            end;
        end;
        n := n * 4;
    end;
end.
Z:\>fpc -v0 -l- Pas0604.pp

Z:\>Pas0604
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536,  0.0000000000

Ada

with TEXT_IO, Ada.Long_Float_Text_IO, Ada.Integer_Text_IO, Ada.Numerics;
use  TEXT_IO, Ada.Long_Float_Text_IO, Ada.Integer_Text_IO, Ada.Numerics;

procedure Ada0604 is
    a : Constant Long_Float := 0.0;
    b : Constant Long_Float := 1.0;

    h, s, x : Long_Float;
    n : Integer;
    t : array (1..6, 1..6) of Long_Float;

    function f(x:Long_Float) return Long_Float is
    begin
        return 4.0 / (1.0 + x * x);
    end f;

begin
    -- 台形則で積分
    n := 2;
    for i in 1..6 loop
        h := (b - a) / Long_Float(n);
        s := 0.0;
        x := a;
        for j in 1..(n - 1) loop
            x := x + h;
            s := s + f(x);
        end loop;
        -- 結果を保存
        t(i,1) := h * ((f(a) + f(b)) / 2.0 + s);
        n := n * 2;
    end loop;

    -- Richardsonの補外法
    n := 4;
    for j in 2..6 loop
        for i in j..6 loop
            t(i,j) := t(i, j - 1) + (t(i, j - 1) - t(i - 1, j - 1)) / Long_Float(n - 1);
            if i = j then
                -- 結果を π と比較
                Put(j,                        Width=> 2);
                Put(" : ");
                Put(t(i,j) ,                  Fore=>3, Aft=>10, Exp=>0);
                Put(", ");
                Put(t(i,j) - Ada.Numerics.Pi, Fore=>3, Aft=>10, Exp=>0);
                New_Line;
            end if;
        end loop;
        n := n * 4;
    end loop;
end Ada0604;
xxxxxx@yyyyyy /Z
$ gnatmake Ada0604.adb

xxxxxx@yyyyyy /Z
$ Ada0604
 2 :   3.1415686275,  -0.0000240261
 3 :   3.1415940941,   0.0000014405
 4 :   3.1415926384,  -0.0000000152
 5 :   3.1415926536,   0.0000000001
 6 :   3.1415926536,  -0.0000000000

VB.NET

Module VB0604
    Public Sub Main()
        Const a As Double = 0
        Const b As Double = 1

        Dim t(6, 6) As Double

        '台形則で積分
        Dim n As Integer = 2
        For i As Integer = 1 To 6
            Dim h As Double = (b - a) / n
            Dim s As Double = 0
            Dim x As Double = a
            For j As Integer = 1 To n - 1
                x += h
                s += f(x)
            Next
            '結果を保存
            t(i,1) = h * ((f(a) + f(b)) / 2 + s)
            n *= 2
        Next

        'Richardsonの補外法
        n = 4
        For j As Integer = 2 To 6
            For i As Integer = j To 6
                t(i,j) = t(i, j - 1) + (t(i, j - 1) - t(i - 1, j - 1)) / (n - 1)
                If i = j Then
                    '結果を π と比較
                    Console.WriteLine(String.Format("{0,2:D} : {1,13:F10}, {2,13:F10}", j, t(i,j), t(i,j) - Math.PI))
                End If
            Next
            n *= 4
        Next
    End Sub

    Private Function f(ByVal x As Double) As Double
        Return 4 / (1 + x * x)
    End Function
End Module
Z:\>vbc -nologo VB0604.vb

Z:\>VB0604
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536,  0.0000000000

C#

using System;

public class CS0604
{
    private static double f(double x)
    {
        return 4 / (1 + x * x);
    }

    public static void Main()
    {
        const double a = 0;
        const double b = 1;

        double[,] t = new double[7,7];

        // 台形則で積分
        int n = 2;
        for (int i = 1; i <= 6; i++)
        {
            double h = (b - a) / n;
            double s = 0;
            double x = a;
            for (int j = 1; j <= n - 1; j++)
            {
                x += h;
                s += f(x);
            }
            // 結果を保存
            t[i,1] = h * ((f(a) + f(b)) / 2 + s);
            n *= 2;
        }

        // Richardsonの補外法
        n = 4;
        for (int j = 2; j <= 6; j++)
        {
            for (int i = j; i <= 6; i++)
            {
                t[i,j] = t[i, j - 1] + (t[i, j - 1] - t[i - 1, j - 1]) / (n - 1);
                if (i == j)
                {
                    // 結果を π と比較
                    Console.WriteLine(string.Format("{0,2:D} : {1,13:F10}, {2,13:F10}", j, t[i,j], t[i,j] - Math.PI));
                }
            }
            n *= 4;
        }
    }
}
Z:\>csc -nologo CS0604.cs

Z:\>CS0604
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536,  0.0000000000

Java

public class Java0604 {

    private static double f(double x) {
        return 4 / (1 + x * x);
    }

    public static void main(String []args) {
        final double a = 0;
        final double b = 1;

        double[][] t = new double[7][7];

        // 台形則で積分
        int n = 2;
        for (int i = 1; i <= 6; i++) {
            double h = (b - a) / n;
            double s = 0;
            double x = a;
            for (int j = 1; j <= n - 1; j++) {
                x += h;
                s += f(x);
            }
            // 結果を保存
            t[i][1] = h * ((f(a) + f(b)) / 2 + s);
            n *= 2;
        }

        // Richardsonの補外法
        n = 4;
        for (int j = 2; j <= 6; j++) {
            for (int i = j; i <= 6; i++) {
                t[i][j] = t[i][j - 1] + (t[i][j - 1] - t[i - 1][j - 1]) / (n - 1);
                if (i == j) {
                    // 結果を π と比較
                    System.out.println(String.format("%2d : %13.10f, %13.10f", j, t[i][j], t[i][j] - Math.PI));
                }
            }
            n *= 4;
        }
    }
}
Z:\>javac Java0604.java

Z:\>java Java0604
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536, -0.0000000000

C++

#include <iostream>
#include <iomanip>
#include <math>

using namespace std;

double f(double x)
{
    return 4 / (1 + x * x);
}

int main()
{
    const double a = 0;
    const double b = 1;

    double t[7][7];

    // 台形則で積分
    int n = 2;
    for (int i = 1; i <= 6; i++)
    {
        double h = (b - a) / n;
        double s = 0;
        double x = a;
        for (int j = 1; j <= n - 1; j++)
        {
            x += h;
            s += f(x);
        }
        // 結果を保存
        t[i][1] = h * ((f(a) + f(b)) / 2 + s);
        n *= 2;
    }

    // Richardsonの補外法
    n = 4;
    for (int j = 2; j <= 6; j++)
    {
        for (int i = j; i <= 6; i++)
        {
            t[i][j] = t[i][j - 1] + (t[i][j - 1] - t[i - 1][j - 1]) / (n - 1);
            if (i == j)
            {
                // 結果を π と比較
                cout << setw(2)  << j << ":";
                cout << setw(13) << fixed << setprecision(10) << t[i][j]        << ", ";
                cout << setw(13) << fixed << setprecision(10) << t[i][j] - M_PI << endl;
            }
        }
        n *= 4;
    }

    return 0;
}
Z:\>bcc32 -q CP0604.cpp
cp0604.cpp:

Z:\>CP0604
 2: 3.1415686275, -0.0000240261
 3: 3.1415940941,  0.0000014405
 4: 3.1415926384, -0.0000000152
 5: 3.1415926536,  0.0000000001
 6: 3.1415926536, -0.0000000000

Objective-C

#import <Foundation/Foundation.h>
#import <math.h>

double f(double x)
{
    return 4 / (1 + x * x);
}

int main()
{
    const double a = 0;
    const double b = 1;

    double t[7][7];

    // 台形則で積分
    int n = 2;
    int i, j;
    for (i = 1; i <= 6; i++)
    {
        double h = (b - a) / n;
        double s = 0;
        double x = a;
        for (j = 1; j <= n - 1; j++)
        {
            x += h;
            s += f(x);
        }
        // 結果を保存
        t[i][1] = h * ((f(a) + f(b)) / 2 + s);
        n *= 2;
    }

    // Richardsonの補外法
    n = 4;
    for (j = 2; j <= 6; j++)
    {
        for (i = j; i <= 6; i++)
        {
            t[i][j] = t[i][j - 1] + (t[i][j - 1] - t[i - 1][j - 1]) / (n - 1);
            if (i == j)
            {
                // 結果を π と比較
                printf("%2d : %13.10f, %13.10f\n", j, t[i][j], t[i][j] - M_PI);
            }
        }
        n *= 4;
    }

    return 0;
}
xxxxxx@yyyyyy /Z
$ gcc -o OC0604 OC0604.m -lobjc -lgnustep-base -I $INCLUDE -L $LIB $CFLAGS

xxxxxx@yyyyyy /Z
$ OC0604
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536, -0.0000000000

D

import std.stdio;
import std.math;

void main(string[] args)
{
    const double a = 0;
    const double b = 1;

    double t[7][7];

    // 台形則で積分
    int n = 2;
    for (int i = 1; i <= 6; i++)
    {
        double h = (b - a) / n;
        double s = 0;
        double x = a;
        for (int j = 1; j <= n - 1; j++)
        {
            x += h;
            s += f(x);
        }
        // 結果を保存
        t[i][1] = h * ((f(a) + f(b)) / 2 + s);
        n *= 2;
    }

    // Richardsonの補外法
    n = 4;
    for (int j = 2; j <= 6; j++)
    {
        for (int i = j; i <= 6; i++)
        {
            t[i][j] = t[i][j - 1] + (t[i][j - 1] - t[i - 1][j - 1]) / (n - 1);
            if (i == j)
            {
                // 結果を π と比較
                writefln("%2d : %13.10f, %13.10f", j, t[i][j], t[i][j] - PI);
            }
        }
        n *= 4;
    }
}

double f(double x)
{
    return 4 / (1 + x * x);
}
Z:\>dmd D0604.d

Z:\>D0604
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000151
 5 :  3.1415926536,  0.0000000000
 6 :  3.1415926536, -0.0000000000

Go

package main

import "fmt"
import "math"

func main() {
    const a = 0
    const b = 1

    var t[7][7] float64

    // 台形則で積分
    var n int = 2
    for i := 1; i <= 6; i++ {
        var h float64 = (b - a) / float64(n)
        var s float64 = 0
        var x float64 = a
        for j := 1; j <= n - 1; j++ {
            x += h
            s += f(x)
        }
        // 結果を保存
        t[i][1] = h * ((f(a) + f(b)) / 2 + s)
        n *= 2
    }

    // Richardsonの補外法
    n = 4
    for j := 2; j <= 6; j++ {
        for i := j; i <= 6; i++ {
            t[i][j] = t[i][j - 1] + (t[i][j - 1] - t[i - 1][j - 1]) / float64(n - 1)
            if i == j {
                // 結果を π と比較
                fmt.Printf("%2d : %13.10f, %13.10f\n", j, t[i][j], t[i][j] - math.Pi)
            }
        }
        n *= 4
    }

}

func f(x float64) float64 {
    return (4 / (1 + x * x))
}
Z:\>8g GO0604.go

Z:\>8l -o GO0604.exe GO0604.8

Z:\>GO0604
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536, -0.0000000000

Scala

object Scala0604 {
    def main(args: Array[String]) {
        val a:Double = 0
        val b:Double = 1

        val t = Array.ofDim[Double](7, 7)

        // 台形則で積分
        var n:Int = 2
        for (i <- 1 to 6) {
            var h:Double = (b - a) / n
            var s:Double = 0
            var x:Double = a
            for (j <- 1 to (n - 1)) {
                x += h
                s += f(x)
            }
            // 結果を保存
            t(i)(1) = h * ((f(a) + f(b)) / 2 + s)
            n *= 2
        }

        // Richardsonの補外法
        n = 4
        for (j <- 2 to 6) {
            for (i <- j to 6) {
                t(i)(j) = t(i)(j - 1) + (t(i)(j - 1) - t(i - 1)(j - 1)) / (n - 1)
                if (i == j) {
                    // 結果を π と比較
                    println("%3d : %13.10f, %13.10f".format(j, t(i)(j), t(i)(j) - Math.PI))
                }
            }
            n *= 4
        }
    }

    def f(x:Double):Double = {
        4 / (1 + x * x)
    }
}
Z:\>scala Scala0604.scala
  2 :  3.1415686275, -0.0000240261
  3 :  3.1415940941,  0.0000014405
  4 :  3.1415926384, -0.0000000152
  5 :  3.1415926536,  0.0000000001
  6 :  3.1415926536, -0.0000000000

F#

module Fs0604

open System

let f(x:double):double =
    4.0 / (1.0 + x * x)

let a:double = 0.0
let b:double = 1.0

let t = Array2D.zeroCreate<double> 7 7

// 台形則で積分
let mutable n = 2
for i in [1..6] do
    let         h:double = (b - a) / (double n)
    let mutable s:double = 0.0
    let mutable x:double = a

    for j in [1..(n - 1)] do
        x <- x + h
        s <- s + (f x)

    // 結果を保存
    t.[i,1] <- h * (((f a) + (f b)) / 2.0 + s)
    n <- n * 2

// Richardsonの補外法
n <- 4
for j in [2..6] do
    for i in [j..6] do
        t.[i,j] <- t.[i, j - 1] + (t.[i, j - 1] - t.[i - 1, j - 1]) / (double (n - 1))
        if i = j then
            // 結果を π と比較
            printfn "%3d : %13.10f, %13.10f" j t.[i,j] (t.[i,j] - Math.PI)
    n <- n * 4

exit 0
Z:\>fsi  --nologo --quiet Fs0604.fs
  2 :  3.1415686275, -0.0000240261
  3 :  3.1415940941,  0.0000014405
  4 :  3.1415926384, -0.0000000152
  5 :  3.1415926536,  0.0000000001
  6 :  3.1415926536,  0.0000000000

Clojure

(defn f[x]
    (/ 4 (+ 1 (* x x))))

(def a 0)
(def b 1)

(def t (list))
; 台形則で積分
(doseq [j (range 1 11)]
    (def n (Math/pow 2 j))
    (def h (/ (- b a) n))
    (def x a)
    (def s 0)
    (doseq [i (range 1 n)]
        (def x (+ x h))
        (def s (+ s (f x))))
    (def t1 (double (* h (+ (/ (+ (f a) (f b)) 2) s))))
    (def t2 (- t1 (. Math PI)))
    ; 結果を保存
    (def t (cons t1 t)))

; Richardsonの補外法
(def t (reverse t))
(doseq [j (range 2 7)]
    (def n (Math/pow 4 (- j 1)))
    (def s (list))
    (doseq [i (range j 7)]
        (def t1 (+ (second t) (/ (- (second t) (first t)) (- n 1))))
        (def t2 (- t1 (. Math PI)))
        ; 結果を π と比較
        (if (= i j)
            (println (format "%2d : %13.10f, %13.10f" j t1 t2)))
        (def t (rest t))
        (def s (cons t1 s)))
    (def t (reverse s)))
Z:\>java -cp C:\ProgramFiles\clojure-1.5.1\clojure-1.5.1.jar clojure.main Clj0604.clj
 2 :  3.1415686275, -0.0000240261
 3 :  3.1415940941,  0.0000014405
 4 :  3.1415926384, -0.0000000152
 5 :  3.1415926536,  0.0000000001
 6 :  3.1415926536, -0.0000000000

Haskell

import Text.Printf
import Control.Monad

f::Double->Double
f x = 4 / (1 + (x * x))

-- Richardsonの補外法
rich_sub n []     ss = ss
rich_sub n (x:[]) ss = ss
rich_sub n (x:xs) ss =
    let
        x2 = (head xs)
        s  = x2 + (x2 - x) / (fromIntegral (n - 1))
    in
        rich_sub n xs (s:ss)

richardson n ([])   = 0
richardson n (x:[]) = x
richardson n (x:xs) =
    let
        s = rich_sub n (x:xs) []
    in
        richardson (n * 4) (reverse s)

main = do
    let a = 0.0
    let b = 1.0
    t <- forM ([1..6::Integer]) $ \j -> do
        let n = 2 ^ j
        let h = (b - a) / (fromIntegral n)
        -- 台形則で積分
        let w1 = sum $ map(\x -> f x) $ map(\i -> (fromIntegral i) * h + a) $ [1..(n - 1)]
        let w2 = ((f a) + (f b)) / 2
        let t1 = h * (w1 + w2)
        return t1

    -- Richardsonの補外法で積分して, 結果を π と比較
    forM_ ([2..6::Int]) $ \i -> do
        let s = richardson 4 (take i t)
        printf "%3d : %13.10f, %13.10f\n" i s (s - pi)
Z:\>runghc Hs0604.hs
  2 :  3.1415686275, -0.0000240261
  3 :  3.1415940941,  0.0000014405
  4 :  3.1415926384, -0.0000000152
  5 :  3.1415926536,  0.0000000001
  6 :  3.1415926536, -0.0000000000
inserted by FC2 system