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

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

Only Do What Only You Can Do

正割法

非線形方程式の解法(正割法, 割線法 または セカント法 ともいう)を利用して2の平方根を求める .

考え方はニュートン法と同じだが, 接線の傾きを導関数から求めるのではなく,

で求める.
漸化式は ニュートン法の

に対して,

となる.

VBScript

Option Explicit

Dim x0: x0 = 1.0
Dim x1: x1 = 2.0
WScript.StdOut.Write Right(Space(12) & FormatNumber(secant(x0, x1), 10, -1, 0, 0), 12) & vbNewLine

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

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

    secant = x2
End Function

Private Function f(ByVal x)
    f = x * x - 2
End Function
Z:\>cscript //nologo Z:\0906.vbs
1.3333333333    0.0808802290
1.4000000000    0.0142135624
1.4146341463    0.0004205840
1.4142114385    0.0000021239
1.4142135621    0.0000000003
1.4142135624    0.0000000000
1.4142135624    0.0000000000
1.4142135624

JScript

var x0 = 1
var x1 = 2
WScript.StdOut.Write(("            " + secant(x0, x1).toFixed(10) ).slice(-12) + "\n")

function secant(x0, x1) {
    var x2
    while (true) {
        x2 = x1 - f(x1) * (x1 - x0) / (f(x1) - f(x0))
        WScript.StdOut.Write(("            " + x2.toFixed(10)                  ).slice(-12) + "\t")
        WScript.StdOut.Write(("            " + (x2 - Math.sqrt(2)).toFixed(10) ).slice(-12) + "\n")

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

function f(x) {
    return x * x - 2
}
Z:\>cscript //nologo Z:\0906.js
1.3333333333    0.0808802290
1.4000000000    0.0142135624
1.4146341463    0.0004205840
1.4142114385    0.0000021239
1.4142135621    0.0000000003
1.4142135624    0.0000000000
1.4142135624    0.0000000000
1.4142135624

PowerShell

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

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

function f($x)
{
    return $x * $x - 2
}

$x0 = 1
$x1 = 2
Write-Host ([String]::Format("{0,12:F10}", (secant $x0 $x1)))
Z:\>powershell -file Z:\0906.ps1
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Perl

my $x0 = 1;
my $x1 = 2;
printf("%12.10f\n", secant($x0, $x1));

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

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

sub f
{
    my ($x) = @_;
    $x * $x - 2;
}
Z:\>perl Z:\0906.pl
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

PHP

<?php
$x0 = 1;
$x1 = 2;
printf("%12.10f\n", secant($x0, $x1));

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

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

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

function f($x)
{
    return $x * $x - 2;
}
?>
Z:\>php Z:\0906.php
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Python

# coding: Shift_JIS

import math

def f(x):
    return x * x - 2.0

def secant(x0, x1):
    while True:
        x2 = x1 - f(x1) * (x1 - x0) / (f(x1) - f(x0))
        print "%12.10f\t%13.10f" % (x2, x2 - math.sqrt(2))

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

    return x2

x0 = 1.0
x1 = 2.0
print "%12.10f" % secant(x0, x1)
Z:\>python Z:\0906.py
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Ruby

include Math

def f(x)
    x * x - 2.0
end

def secant(x0, x1)
    while true
        x2 = x1 - f(x1) * (x1 - x0) / (f(x1) - f(x0))
        printf("%12.10f\t%13.10f\n", x2, x2 - sqrt(2))

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

        x0 = x1
        x1 = x2
    end

    x2
end

x0 = 1.0
x1 = 2.0
printf("%12.10f\n", secant(x0, x1))
Z:\>ruby Z:\0906.rb
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Groovy

x0 = 1
x1 = 2
printf ("%12.10f\n" , secant(x0, x1))

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

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

def f(x) {
    x * x - 2
}
Z:\>groovy Groovy0906.groovy
1.3333333333    -0.0808802291
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Pascal

program Pas0906(arg);
{$MODE delphi}

uses
    SysUtils, Math;

function f(x:Double):Double;
begin
    result := x * x - 2;
end;

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

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

    result := x2;
end;

var
    x0:  Double = 1.0;
    x1:  Double = 2.0;
begin
    writeln(format('%12.10f', [secant(x0, x1)]));
end.
Z:\>fpc -v0 -l- Pas0906.pp

Z:\>Pas0906
2.0000000000     0.5857864376
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
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 Ada0906 is

    function f(x:Long_Float) return Long_Float is
    begin
        return x * x - 2.0;
    end f;

    function secant(a:Long_Float; b:Long_Float) return Long_Float is
        x0: Long_Float;
        x1: Long_Float;
        x2: Long_Float;
    begin
        x0 := a;
        x1 := b;
        while true loop
            x2 := x1 - f(x1) * (x1 - x0) / (f(x1) - f(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;
            x1 := x2;
        end loop;

        return x2;
    end secant;

    x0: Long_Float := 1.0;
    x1: Long_Float := 2.0;
begin
    Put(secant(x0, x1), Fore=>2, Aft=>10, Exp=>0);
    New_Line;
end Ada0906;
xxxxxx@yyyyyy /Z
$ gnatmake Ada0906.adb

xxxxxx@yyyyyy /Z
$ Ada0906
 2.0000000000    0.5857864376
 1.3333333333   -0.0808802290
 1.4000000000   -0.0142135624
 1.4146341463    0.0004205840
 1.4142114385   -0.0000021239
 1.4142135621   -0.0000000003
 1.4142135624    0.0000000000
 1.4142135624    0.0000000000
 1.4142135624

VB.NET

Option Explicit

Module VB0906
    Public Sub Main()
        Dim x0 As Double = 1.0
        Dim x1 As Double = 2.0
        Console.WriteLine(String.Format("{0,12:F10}", secant(x0, x1)))
    End Sub

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

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

        Return x2
    End Function

    Private Function f(ByVal x As Double) As Double
        Return x * x - 2
    End Function
End Module
Z:\>vbc -nologo VB0906.vb

Z:\>VB0906
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

C#

using System;

public class CS0906
{
    public static void Main()
    {
        double x0 = 1;
        double x1 = 2;
        Console.WriteLine(string.Format("{0,12:F10}", secant(x0, x1)));
    }

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

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

    private static double f(double x)
    {
        return x * x - 2;
    }
}
Z:\>csc -nologo CS0906.cs

Z:\>CS0906
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Java

import static java.lang.System.out;

public class Java0906 {

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

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

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

    private static double f(double x) {
        return x * x - 2;
    }
}
Z:\>javac Java0906.java

Z:\>java Java0906
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

C++

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

using namespace std;

double f(double x)
{
    return x * x - 2;
}

double secant(double x0, double x1)
{
    double x2;
    while (true)
    {
        x2 = x1 - f(x1) * (x1 - x0) / (f(x1) - f(x0));
        cout << setw(12) << fixed << setprecision(10) << x2 << "\t";
        cout << setw(13) << fixed << setprecision(10) << x2 - sqrt(2) << endl;

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

int main()
{
    double x0 = 1;
    double x1 = 2;
    cout << setw(12) << fixed << setprecision(10) << secant(x0, x1) << endl;
    return 0;
}
Z:\>bcc32 -q CP0906.cpp
cp0906.cpp:

Z:\>CP0906
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Objective-C

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

double f(double x)
{
    return x * x - 2;
}

double secant(double x0, double x1)
{
    double x2;
    while (YES)
    {
        x2 = x1 - f(x1) * (x1 - x0) / (f(x1) - f(x0));
        printf("%12.10f\t%13.10f\n", x2, x2 - sqrt(2));

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

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

xxxxxx@yyyyyy /Z
$ OC0906
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

D

import std.stdio;
import std.math;

void main(string[] args) {
    double x0 = 1;
    double x1 = 2;
    writefln("%12.10f", secant(x0, x1));
}

double secant(double x0, double x1)
{
    double x2;
    while (true)
    {
        x2 = x1 - f(x1) * (x1 - x0) / (f(x1) - f(x0));
        writefln("%12.10f\t%13.10f", x1, x1 - sqrt(2.0));

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

double f(double x)
{
    return x * x - 2;
}
Z:\>dmd D0906.d

Z:\>D0906
2.0000000000     0.5857864376
1.3333333333    -0.0808802290
1.4000000000    -0.0142135623
1.4146341463     0.0004205839
1.4142114385    -0.0000021238
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624

Go

package main

import "fmt"
import "math"

func main() {
    var x0 float64 = 1
    var x1 float64 = 2
    fmt.Printf("%12.10f\n", secant(x0, x1))
}

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

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

func f(x float64) float64 {
    return x * x - 2
}
Z:\>8g GO0906.go

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

Z:\>GO0906
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Scala

object Scala0906 {

    def main(args: Array[String]) {
        val x0 = 1.0
        val x1 = 2.0
        println("%12.10f".format(secant(x0, x1)))
    }

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

        if (Math.abs(x2 - x1) < 0.0000000001)
            x2
        else
            secant(x1, x2)
    }

    def f(x:Double) = {
        x * x - 2
    }
}
Z:\>scala Scala0906.scala
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

F#

module Fs0906

open System

let f (x:double):double =
    x * x - 2.0

let rec secant (x0:double)(x1:double):double =
    let x2 = x1 - f(x1) * (x1 - x0) / (f(x1) - f(x0))
    printfn "%12.10f\t%13.10f" x2 (x2 - Math.Sqrt(2.0))

    if abs(x2 - x1) < 0.0000000001 then
        x2
    else
        secant x1 x2

let x0 = 1.0
let x1 = 2.0
printfn "%12.10f" (secant x0 x1)

exit 0
Z:\>fsi  --nologo --quiet Fs0906.fs
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Clojure

(defn f[x]
    (- (* x x) 2.0))

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

    (if (< (. Math abs (- x2 x1)) 0.00000000001)
        x2
        (secant x1 x2)))

(def x0 1.0)
(def x1 2.0)
(println (format "%12.10f" (secant x0 x1)))
Z:\>java -cp C:\ProgramFiles\clojure-1.5.1\clojure-1.5.1.jar clojure.main Clj0906.clj
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624     0.0000000000
1.4142135624

Haskell

import Text.Printf
import Debug.Trace

f::Double->Double
f x = x * x - 2.0

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

main = do
    let x0 = 1.0
    let x1 = 2.0
    printf "%12.10f\n" (secant x0 x1)
Z:\>runghc Hs0906.hs
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4146341463     0.0004205840
1.4142114385    -0.0000021239
1.4142135621    -0.0000000003
1.4142135624     0.0000000000
1.4142135624
inserted by FC2 system