home > さまざまな言語で数値計算 > 非線形方程式 >

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

Only Do What Only You Can Do

反復法

非線形方程式の解法(反復法 または 単純代入法 とも言う)を利用して2の平方根を求める .

1. まず, 方程式 $ f(x) = 0 $ を, $ x = g(x) $ と変形する.

2. $ g(x) $ の値を 新しい $x$ として処理を繰り返して行くことで解を求める.

ただし, 曲線 $ y = g(x) $ の傾きが, $ y = x $ の傾きより小さくなければ収束しない.

と変形しても収束しない.

そこで一工夫して

と変形してみると

傾きが, $ y = x $ の傾きより小さくなって収束する.

VBScript

Option Explicit

Dim x: x = 1.0
WScript.StdOut.Write Right(Space(12) & FormatNumber(iterative(x), 10, -1, 0, 0), 12) & vbNewLine

Private Function iterative(ByVal x0)
    Dim x1
    Do While(True)
        x1 = g(x0)
        WScript.StdOut.Write Right(Space(12) & FormatNumber(x1,          10, -1, 0, 0), 12) & vbTab
        WScript.StdOut.Write Right(Space(12) & FormatNumber(x1 - Sqr(2), 10, -1, 0, 0), 12) & vbNewLine

        If Abs(x1 - x0) < 0.0000000001 Then Exit Do
        x0 = x1
    Loop

    iterative = x1
End Function

Private Function g(ByVal x)
    g = (x / 2) + (1 / x)
End Function
Z:\>cscript //nologo Z:\0903.vbs
1.5000000000    0.0857864376
1.4166666667    0.0024531043
1.4142156863    0.0000021239
1.4142135624    0.0000000000
1.4142135624    0.0000000000
1.4142135624

JScript

var x = 1
WScript.StdOut.Write(("            " + iterative(x).toFixed(10) ).slice(-12) + "\n")

function iterative(x0) {
    var x1
    while (true) {
        x1 = g(x0)
        WScript.StdOut.Write(("            " + x1.toFixed(10)                  ).slice(-12) + "\t")
        WScript.StdOut.Write(("            " + (x1 - Math.sqrt(2)).toFixed(10) ).slice(-12) + "\n")

        if (Math.abs(x1 - x0) < 0.0000000001) break
        x0 = x1
    }
    return x1
}

function g(x) {
    return (x / 2) + (1 / x)
}
Z:\>cscript //nologo Z:\0903.js
1.5000000000    0.0857864376
1.4166666667    0.0024531043
1.4142156863    0.0000021239
1.4142135624    0.0000000000
1.4142135624    0.0000000000
1.4142135624

PowerShell

function iterative($x0)
{
    while ($true)
    {
        $x1 = g($x0)
        Write-Host ([String]::Format("{0,12:F10}`t{1,13:F10}", $x1, $x1 - [Math]::Sqrt(2)))

        if ([Math]::Abs($x1 - $x0) -lt 0.0000000001)
        {
            break
        }
        $x0 = $x1
    }
    return $x1
}

function g($x)
{
    return ($x / 2) + (1 / $x)
}

$x = 1
Write-Host ([String]::Format("{0,12:F10}", (iterative $x)))
Z:\>powershell -file Z:\0903.ps1
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Perl

my $x = 1;
printf("%12.10f\n", iterative($x));

sub iterative
{
    my ($x0) = @_;
    my $x1;
    while (1)
    {
        $x1 = g($x0);
        printf("%12.10f\t%13.10f\n", $x1, $x1 - sqrt(2));

        if (abs($x1 - $x0) < 0.0000000001)
        {
            last;
        }
        $x0 = $x1;
    }
    $x1;
}

sub g
{
    my ($x) = @_;
    ($x / 2) + (1 / $x);
}
Z:\>perl Z:\0903.pl
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624    -0.0000000000
1.4142135624

PHP

<?php
$x = 1;
printf("%12.10f\n", iterative($x));

function iterative($x0)
{
    while (TRUE)
    {
        $x1 = g($x0);
        printf("%12.10f\t%13.10f\n", $x1, $x1 - sqrt(2));

        if (abs($x1 - $x0) < 0.0000000001) break;

        $x0 = $x1;
    }
    return $x1;
}

function g($x)
{
    return ($x / 2) + (1 / $x);
}
?>
Z:\>php Z:\0903.php
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624    -0.0000000000
1.4142135624

Python

# coding: Shift_JIS

import math

def g(x):
    return (x / 2.0) + (1.0 / x)

def iterative(x0):
    while True:
        x1 = g(x0)
        print "%12.10f\t%13.10f" % (x1, x1 - math.sqrt(2))

        if (abs(x1 - x0) < 0.0000000001):
            break
        x0 = x1

    return x1

x = 1.0
print "%12.10f" % iterative(x)
Z:\>python Z:\0903.py
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624    -0.0000000000
1.4142135624

Ruby

include Math

def g(x)
    (x / 2.0) + (1.0 / x)
end

def iterative(x0)
    while true
        x1 = g(x0)
        printf("%12.10f\t%13.10f\n", x1, x1 - sqrt(2))

        if (x1 - x0).abs < 0.0000000001
            break
        end

        x0 = x1
    end

    x1
end

x = 1.0
printf("%12.10f\n", iterative(x))
Z:\>ruby Z:\0903.rb
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624    -0.0000000000
1.4142135624

Groovy

x = 1
printf ("%12.10f\n" , iterative(x))

def iterative(x0) {
    while (true) {
        x1 = g(x0)
        printf("%12.10f\t%13.10f\n", x1, x1 - Math.sqrt(2))

        if (Math.abs(x1 - x0) < 0.0000000001) break
        x0 = x1
    }
    x1
}

def g(x) {
    (x / 2) + (1 / x)
}
Z:\>groovy Groovy0903.groovy
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Pascal

program Pas0903(arg);
{$MODE delphi}

uses
    SysUtils, Math;

function g(x:Double):Double;
begin
    result := (x / 2) + (1 / x);
end;

function iterative(x0:Double):Double;
var
    x1: Double;
begin
    while true do
    begin
        x1 := g(x0);
        writeln(format('%12.10f'#9'%13.10f', [x1, x1 - Sqrt(2)]));

        if Abs(x1 - x0) < 0.0000000001 then break;
        x0 := x1;
    end;

    result := x1;
end;

var
    x:  Double = 1.0;
begin
    writeln(format('%12.10f', [iterative(x)]));
end.
Z:\>fpc -v0 -l- Pas0903.pp

Z:\>Pas0903
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Ada

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

procedure Ada0903 is

    function g(x:Long_Float) return Long_Float is
    begin
        return (x / 2.0) + (1.0 / x);
    end g;

    function iterative(x:Long_Float) return Long_Float is
        x0: Long_Float;
        x1: Long_Float;
    begin
        x0 := x;
        while true loop
            x1 := g(x0);
            Put(x1,             Fore=>2, Aft=>10, Exp=>0);
            Put(Ascii.HT);
            Put(x1 - Sqrt(2.0), Fore=>2, Aft=>10, Exp=>0);
            New_Line;

            if Abs(x1 - x0) < 0.0000000001 then
                exit;
            end if;
            x0 := x1;
        end loop;

        return x1;
    end iterative;

    x: Long_Float := 1.0;
begin
    Put(iterative(x), Fore=>2, Aft=>10, Exp=>0);
    New_Line;
end Ada0903;
xxxxxx@yyyyyy /Z
$ gnatmake Ada0903.adb

xxxxxx@yyyyyy /Z
$ Ada0903
 1.5000000000    0.0857864376
 1.4166666667    0.0024531043
 1.4142156863    0.0000021239
 1.4142135624    0.0000000000
 1.4142135624    0.0000000000
 1.4142135624

VB.NET

Option Explicit

Module VB0903
    Public Sub Main()
        Dim x As Double = 1.0
        Console.WriteLine(String.Format("{0,12:F10}", iterative(x)))
    End Sub

    Private Function iterative(ByVal x0 As Double)
        Dim x1 As Double
        Do While(True)
            x1 = g(x0)
            Console.WriteLine(String.Format("{0,12:F10}{2}{1,13:F10}", x1, x1 - Math.Sqrt(2), vbTab))

            If Math.Abs(x1 - x0) < 0.0000000001 Then Exit Do
            x0 = x1
        Loop

        Return x1
    End Function

    Private Function g(ByVal x As Double) As Double
        Return (x / 2) + (1 / x)
    End Function
End Module
Z:\>vbc -nologo VB0903.vb

Z:\>VB0903
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

C#

using System;

public class CS0903
{
    public static void Main()
    {
        double x = 1;
        Console.WriteLine(string.Format("{0,12:F10}", iterative(x)));
    }

    private static double iterative(double x0)
    {
        double x1;
        while (true)
        {
            x1 = g(x0);
            Console.WriteLine(string.Format("{0,12:F10}\t{1,13:F10}", x1, x1 - Math.Sqrt(2)));

            if (Math.Abs(x1 - x0) < 0.0000000001) break;
            x0 = x1;
        }
        return x1;
    }

    private static double g(double x)
    {
        return (x / 2) + (1 / x);
    }
}
Z:\>csc -nologo CS0903.cs

Z:\>CS0903
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Java

import static java.lang.System.out;

public class Java0903 {

    public static void main(String []args) {
        double x = 1;
        out.println(String.format("%12.10f", iterative(x)));
    }

    private static double iterative(double x0) {
        double x1;
        while (true) {
            x1 = g(x0);
            out.println(String.format("%12.10f\t%13.10f", x1, x1 - Math.sqrt(2)));

            if (Math.abs(x1 - x0) < 0.0000000001) break;
            x0 = x1;
        }
        return x1;
    }

    private static double g(double x) {
        return (x / 2) + (1 / x);
    }
}
Z:\>javac Java0903.java

Z:\>java Java0903
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624    -0.0000000000
1.4142135624

C++

#include <iostream>
#include <iomanip>
#include <math.h>

using namespace std;

double g(double x)
{
    return (x / 2) + (1 / x);
}

double iterative(double x0)
{
    double x1;
    while (true)
    {
        x1 = g(x0);
        cout << setw(12) << fixed << setprecision(10) << x1 << "\t";
        cout << setw(13) << fixed << setprecision(10) << x1 - sqrt(2) << endl;

        if (fabs(x1 - x0) < 0.0000000001) break;
        x0 = x1;
    }
    return x1;
}

int main()
{
    double x = 1.0;
    cout << setw(12) << fixed << setprecision(10) << iterative(x) << endl;
    return 0;
}
Z:\>bcc32 -q CP0903.cpp
cp0903.cpp:

Z:\>CP0903
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Objective-C

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

double g(double x)
{
    return (x / 2) + (1 / x);
}

double iterative(double x0)
{
    double x1;
    while (YES)
    {
        x1 = g(x0);
        printf("%12.10f\t%13.10f\n", x1, x1 - sqrt(2));

        if (fabs(x1 - x0) < 0.0000000001) break;
        x0 = x1;
    }
    return x1;
}

int main()
{
    double x = 1;
    printf("%12.10f\n", iterative(x));
    return 0;
}
xxxxxx@yyyyyy /Z
$ gcc -o OC0903 OC0903.m -lobjc -lgnustep-base -I $INCLUDE -L $LIB $CFLAGS

xxxxxx@yyyyyy /Z
$ OC0903
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

D

import std.stdio;
import std.math;

void main(string[] args)
{
    double x = 1;
    writefln("%12.10f", iterative(x));
}

double iterative(double x0)
{
    double x1;
    while (true)
    {
        x1 = g(x0);
        writefln("%12.10f\t%13.10f", x1, x1 - sqrt(2.0));

        if (fabs(x1 - x0) < 0.0000000001) break;
        x0 = x1;
    }
    return x1;
}

double g(double x)
{
    return (x / 2) + (1 / x);
}
Z:\>dmd D0903.d

Z:\>D0903
1.5000000000     0.0857864376
1.4166666667     0.0024531042
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Go

package main

import "fmt"
import "math"

func main() {
    var x float64 = 1
    fmt.Printf("%12.10f\n", iterative(x))
}

func iterative(x0 float64) float64 {
    var x1 float64
    for {
        x1 = g(x0)
        fmt.Printf("%12.10f\t%13.10f\n", x1, x1 - math.Sqrt(2))

        if math.Fabs(x1 - x0) < 0.0000000001 {
            break
        }
        x0 = x1
    }
    return x1
}

func g(x float64) float64 {
    return (x / 2) + (1 / x)
}
Z:\>8g GO0903.go

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

Z:\>GO0903
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624    -0.0000000000
1.4142135624

Scala

object Scala0903 {

    def main(args: Array[String]) {
        val x = 1.0
        println("%12.10f".format(iterative(x)))
    }

    def iterative(x0:Double):Double = {
        val x1 = g(x0)
        println("%12.10f\t%13.10f".format(x1, x1 - Math.sqrt(2)))

        if (Math.abs(x1 - x0) < 0.0000000001)
            x1
        else
            iterative(x1)
    }

    def g(x:Double) = {
        (x / 2) + (1 / x)
    }
}
Z:\>scala Scala0903.scala
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624    -0.0000000000
1.4142135624

F#

module Fs0903

open System

let g (x:double):double =
    (x / 2.0) + (1.0 / x)

let rec iterative (x0:double):double =
    let x1 = g(x0)
    printfn "%12.10f\t%13.10f" x1 (x1 - Math.Sqrt(2.0))

    if abs(x1 - x0) < 0.0000000001 then
        x1
    else
        iterative x1

let x = 1.0
printfn "%12.10f" (iterative x)

exit 0
Z:\>fsi  --nologo --quiet Fs0903.fs
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Clojure

(defn g[x]
    (+ (/ x 2.0) (/ 1.0 x)))

(defn iterative [x0]
    (def x1 (g x0))
    (println (format "%12.10f\t%13.10f" x1 (- x1 (Math/sqrt 2))))

    (if (< (. Math abs (- x1 x0)) 0.00000000001)
        x1
        (iterative x1)))

(def x 1.0)
(println (format "%12.10f" (iterative x)))
Z:\>java -cp C:\ProgramFiles\clojure-1.5.1\clojure-1.5.1.jar clojure.main Clj0903.clj
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624    -0.0000000000
1.4142135624

Haskell

import Text.Printf
import Debug.Trace

g::Double->Double
g x = (x / 2.0) + (1.0 / x)

iterative::Double->Double
iterative x0 =
    let
        x1 = (g x0)
    in
        if abs(x1 - x0) < 0.0000000001 then
            x1
        else
            trace (printf "%12.10f\t%13.10f" x1 (x1 - ((sqrt 2.0)::Double)))
            iterative x1

main = do
    let x = 1.0
    printf "%12.10f\n" (iterative x)
Z:\>runghc Hs0903.hs
1.5000000000     0.0857864376
1.4166666667     0.0024531043
1.4142156863     0.0000021239
1.4142135624     0.0000000000
1.4142135624
inserted by FC2 system