情報学部 | 菅沼ホーム | 目次 | 索引 |
/*************************************/ /* セカント法による exp(x)-3x=0 の根 */ /* coded by Y.Suganuma */ /*************************************/ #include#include double secant(double, double, int, double, double, int *, double(*)(double)); double snx(double); int main() { double eps1, eps2, x, x1, x2; int max, ind; /* データの設定 */ eps1 = 1.0e-10; eps2 = 1.0e-10; max = 100; x1 = 0.0; x2 = 1.0; /* 実行と結果 */ x = secant(x1, x2, max, eps1, eps2, &ind, snx); printf(" ind=%d x=%f f= %f\n", ind, x, snx(x)); return 0; } /****************/ /* 関数値の計算 */ /****************/ double snx(double x) { double y; y = exp(x) - 3.0 * x; return y; } /*********************************************************/ /* secant法(はさみうち法)による非線形方程式f(x)=0の解 */ /* x1,x2 : 初期値(x1 < x2) */ /* max : 最大試行回数 */ /* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */ /* eps2 : 終了条件2(|f(x(k))|<eps2) */ /* ind : > 0 : 収束回数 */ /* =-1 : 収束しなかった */ /* g : f(x)を計算する関数名 */ /* return : 解 */ /*********************************************************/ #include double secant(double x1, double x2, int max, double eps1, double eps2, int *ind, double (*g)(double)) { double f, f1, f2, x = 0.0; int count; count = 0; *ind = 0; f1 = (*g)(x1); f2 = (*g)(x2); if (fabs(f1) < eps2) x = x1; else { if (fabs(f2) < eps2) x = x2; else { while (*ind == 0) { count += 1; if (fabs(f2-f1) < eps2) *ind = -1; else { x = x2 - f2 * (x2 - x1) / (f2 - f1); f = (*g)(x); if (fabs(f) < eps2 || fabs(x2-x1) < eps1 || fabs(x2-x1) < eps1*fabs(x2)) *ind = count; else { if (count < max) { if (f1*f2 < 0.0) { x2 = x; f2 = f; } else { x1 = x; f1 = f; } } else *ind = -1; } } } } } return x; }
/*************************************/ /* セカント法による exp(x)-3x=0 の根 */ /* coded by Y.Suganuma */ /*************************************/ import java.io.*; public class Test { public static void main(String args[]) throws IOException { double eps1, eps2, x, x1, x2; int max, ind[] = new int [1]; /* データの設定 */ eps1 = 1.0e-10; eps2 = 1.0e-10; max = 100; x1 = 0.0; x2 = 1.0; /* 実行と結果 */ Kansu kn = new Kansu(); x = kn.secant(x1, x2, max, eps1, eps2, ind); System.out.println(" ind=" + ind[0] + " x=" + x + " f=" + kn.snx(x)); } } /****************/ /* 関数値の計算 */ /****************/ class Kansu extends Secant { double snx(double x) { double y = Math.exp(x) - 3.0 * x; return y; } } abstract class Secant { /*********************************************************/ /* secant法(はさみうち法)による非線形方程式f(x)=0の解 */ /* x1,x2 : 初期値(x1 < x2) */ /* max : 最大試行回数 */ /* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */ /* eps2 : 終了条件2(|f(x(k))|<eps2) */ /* ind : > 0 : 収束回数 */ /* =-1 : 収束しなかった */ /* return : 解 */ /*********************************************************/ abstract double snx(double x); // 定義しておく必要あり double secant(double x1, double x2, int max, double eps1, double eps2, int ind[]) { double f, f1, f2, x = 0.0; int count; count = 0; ind[0] = 0; f1 = snx(x1); f2 = snx(x2); if (Math.abs(f1) < eps2) x = x1; else { if (Math.abs(f2) < eps2) x = x2; else { while (ind[0] == 0) { count += 1; if (Math.abs(f2-f1) < eps2) ind[0] = -1; else { x = x2 - f2 * (x2 - x1) / (f2 - f1); f = snx(x); if (Math.abs(f) < eps2 || Math.abs(x2-x1) < eps1 || Math.abs(x2-x1) < eps1*Math.abs(x2)) ind[0] = count; else { if (count < max) { if (f1*f2 < 0.0) { x2 = x; f2 = f; } else { x1 = x; f1 = f; } } else ind[0] = -1; } } } } } return x; } }
<!DOCTYPE HTML> <HTML> <HEAD> <TITLE>非線形方程式(セカント法)</TITLE> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <SCRIPT TYPE="text/javascript"> str = ""; ind = 0; // 実際の試行回数(負の時は解を得ることができなかった) function main() { str = document.getElementById("func").value + ";"; // データの設定 let eps1 = 1.0e-10; let eps2 = 1.0e-10; let max = parseInt(document.getElementById("max").value); let x1 = parseFloat(document.getElementById("x1").value); let x2 = parseFloat(document.getElementById("x2").value); ind = 0; // 実行 let x = secant(x1, x2, max, eps1, eps2, snx); // 結果 if (ind < 0) document.getElementById("res").value = "解を求めることができませんでした!"; else { let c = 100000; let s1 = Math.round(x * c) / c; document.getElementById("res").value = " x = " + s1 + ", 収束回数:" + ind; } } /****************/ /* 関数値の計算 */ /****************/ function snx(x) { let y = eval(str); return y; } /*********************************************************/ /* secant法(はさみうち法)による非線形方程式f(x)=0の解 */ /* x1,x2 : 初期値(x1 < x2) */ /* max : 最大試行回数 */ /* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */ /* eps2 : 終了条件2(|f(x(k))|<eps2) */ /* fn : 関数値を計算する関数 */ /* return : 解 */ /*********************************************************/ function secant(x1, x2, max, eps1, eps2, fn) { let f, x = 0.0; let count = 0; let f1 = fn(x1); let f2 = fn(x2); if (Math.abs(f1) < eps2) x = x1; else { if (Math.abs(f2) < eps2) x = x2; else { while (ind == 0) { count += 1; if (Math.abs(f2-f1) < eps2) ind = -1; else { x = x2 - f2 * (x2 - x1) / (f2 - f1); f = fn(x); if (Math.abs(f) < eps2 || Math.abs(x2-x1) < eps1 || Math.abs(x2-x1) < eps1*Math.abs(x2)) ind = count; else { if (count < max) { if (f1*f2 < 0.0) { x2 = x; f2 = f; } else { x1 = x; f1 = f; } } else ind = -1; } } } } } return x; } </SCRIPT> </HEAD> <BODY STYLE="font-size: 130%; background-color: #eeffee;"> <H2 STYLE="text-align:center"><B>非線形方程式(セカント法)</B></H2> <DL> <DT> テキストフィールドには,例として,以下に示すような非線形方程式の解を求める場合に対する値が設定されています.他の問題を実行する場合は,それらを適切に修正してください.なお,式は,JavaScript の仕様に適合した形式で記述してあることに注意してください. <P STYLE="text-align:center"><IMG SRC="secant.gif"></P> </DL> <DIV STYLE="text-align:center"> 初期値:<INPUT ID="x1" STYLE="font-size: 100%" TYPE="text" SIZE="5" VALUE="0">, <INPUT ID="x2" STYLE="font-size: 100%" TYPE="text" SIZE="5" VALUE="1"> 最大繰り返し回数:<INPUT ID="max" STYLE="font-size: 100%" TYPE="text" SIZE="5" VALUE="100"><BR><BR> 式:<INPUT ID="func" STYLE="font-size: 100%" TYPE="text" SIZE="50" VALUE="Math.exp(x) - 3.0 * x">= 0 <BUTTON STYLE="font-size: 100%; background-color: pink" onClick="main()">実行</BUTTON><BR><BR> 結果:<INPUT ID="res" STYLE="font-size: 100%" TYPE="text" SIZE="30"> </DIV> </BODY> </HTML>
<?php /*************************************/ /* セカント法による exp(x)-3x=0 の根 */ /* coded by Y.Suganuma */ /*************************************/ /* データの設定 */ $eps1 = 1.0e-10; $eps2 = 1.0e-10; $max = 100; $x1 = 0.0; $x2 = 1.0; /* 実行と結果 */ $x = secant($x1, $x2, $max, $eps1, $eps2, $ind, "snx"); printf(" ind=%d x=%f f= %f\n", $ind, $x, snx($x)); /****************/ /* 関数値の計算 */ /****************/ function snx($x) { return exp($x) - 3.0 * $x; } /*********************************************************/ /* secant法(はさみうち法)による非線形方程式f(x)=0の解 */ /* x1,x2 : 初期値(x1 < x2) */ /* max : 最大試行回数 */ /* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */ /* eps2 : 終了条件2(|f(x(k))|<eps2) */ /* ind : > 0 : 収束回数 */ /* =-1 : 収束しなかった */ /* fun : f(x)を計算する関数名 */ /* return : 解 */ /*********************************************************/ #includefunction secant($x1, $x2, $max, $eps1, $eps2, &$ind, $fun) { $x = 0.0; $count = 0; $ind = 0; $f1 = $fun($x1); $f2 = $fun($x2); if (abs($f1) < $eps2) $x = $x1; else { if (abs($f2) < $eps2) $x = $x2; else { while ($ind == 0) { $count += 1; if (abs($f2-$f1) < $eps2) $ind = -1; else { $x = $x2 - $f2 * ($x2 - $x1) / ($f2 - $f1); $f = $fun($x); if (abs($f) < $eps2 || abs($x2-$x1) < $eps1 || abs($x2-$x1) < $eps1*abs($x2)) $ind = $count; else { if ($count < $max) { if ($f1*$f2 < 0.0) { $x2 = $x; $f2 = $f; } else { $x1 = $x; $f1 = $f; } } else $ind = -1; } } } } } return $x; } ?>
############################################ # セカント法による exp(x)-3x=0 の根 # coded by Y.Suganuma ############################################ ############################################ # secant法(はさみうち法)による非線形方程式f(x)=0の解 # x1,x2 : 初期値(x1 < x2) # max : 最大試行回数 # eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) # eps2 : 終了条件2(|f(x(k))|<eps2) # ind : > 0 : 収束回数 # =-1 : 収束しなかった # fn : f(x)を計算する関数名 # return : 解 # coded by Y.Suganuma ############################################ def secant(x1, x2, max, eps1, eps2, ind, &fn) x = 0.0 count = 0 ind[0] = 0 f1 = fn.call(x1) f2 = fn.call(x2) if f1.abs() < eps2 x = x1 else if f2.abs() < eps2 x = x2 else while ind[0] == 0 count += 1 if (f2-f1).abs() < eps2 ind[0] = -1 else x = x2 - f2 * (x2 - x1) / (f2 - f1) f = fn.call(x) if f.abs() < eps2 or (x2-x1).abs() < eps1 or (x2-x1).abs() < eps1*x2.abs() ind[0] = count else if count < max if f1*f2 < 0.0 x2 = x f2 = f else x1 = x f1 = f end else ind[0] = -1 end end end end end end return x end ################ # 関数値の計算 # ################ snx = Proc.new { |x| Math.exp(x) - 3.0 * x } # データの設定 ind = [0]; eps1 = 1.0e-10 eps2 = 1.0e-10 max = 100 x1 = 0.0 x2 = 1.0 # 実行と結果 x = secant(x1, x2, max, eps1, eps2, ind, &snx) print(" ind=", ind[0], " x=", x, " f= ", snx.call(x), "\n")
# -*- coding: UTF-8 -*- import numpy as np from math import * ############################################ # secant法(はさみうち法)による非線形方程式f(x)=0の解 # x1,x2 : 初期値(x1 < x2) # max : 最大試行回数 # eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) # eps2 : 終了条件2(|f(x(k))|<eps2) # ind : > 0 : 収束回数 # =-1 : 収束しなかった # fn : f(x)を計算する関数名 # return : 解 # coded by Y.Suganuma ############################################ def secant(x1, x2, max, eps1, eps2, ind, fn) : x = 0.0 count = 0 ind[0] = 0 f1 = fn(x1) f2 = fn(x2) if abs(f1) < eps2 : x = x1 else : if abs(f2) < eps2 : x = x2 else : while ind[0] == 0 : count += 1 if abs(f2-f1) < eps2 : ind[0] = -1 else : x = x2 - f2 * (x2 - x1) / (f2 - f1) f = fn(x) if abs(f) < eps2 or abs(x2-x1) < eps1 or abs(x2-x1) < eps1*abs(x2) : ind[0] = count else : if count < max : if f1*f2 < 0.0 : x2 = x f2 = f else : x1 = x f1 = f else : ind[0] = -1 return x ################ # 関数値の計算 # ################ def snx(x) : return exp(x) - 3.0 * x ############################################ # セカント法による exp(x)-3x=0 の根 # coded by Y.Suganuma ############################################ # データの設定 ind = [0]; eps1 = 1.0e-10 eps2 = 1.0e-10 max = 100 x1 = 0.0 x2 = 1.0 # 実行と結果 x = secant(x1, x2, max, eps1, eps2, ind, snx) print(" ind=" + str(ind[0]) + " x=" + str(x) + " f= " + str(snx(x)))
/*************************************/ /* セカント法による exp(x)-3x=0 の根 */ /* coded by Y.Suganuma */ /*************************************/ using System; class Program { static void Main() { Test1 ts = new Test1(); } } class Test1 { public Test1() { /* データの設定 */ double eps1 = 1.0e-10; double eps2 = 1.0e-10; double x1 = 0.0; double x2 = 1.0; int max = 100; int ind = 0; /* 実行と結果 */ double x = secant(x1, x2, max, eps1, eps2, ref ind, snx); Console.WriteLine(" ind=" + ind + " x=" + x + " f=" + snx(x)); } /****************/ /* 関数値の計算 */ /****************/ double snx(double x) { return Math.Exp(x) - 3.0 * x; } /*********************************************************/ /* secant法(はさみうち法)による非線形方程式f(x)=0の解 */ /* x1,x2 : 初期値(x1 < x2) */ /* max : 最大試行回数 */ /* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */ /* eps2 : 終了条件2(|f(x(k))|<eps2) */ /* ind : > 0 : 収束回数 */ /* =-1 : 収束しなかった */ /* fn : 関数値を計算する関数 */ /* return : 解 */ /*********************************************************/ double secant(double x1, double x2, int max, double eps1, double eps2, ref int ind, Func<double, double> fn) { double f1 = fn(x1); double f2 = fn(x2); double x = 0.0; int count = 0; ind = 0; if (Math.Abs(f1) < eps2) x = x1; else { if (Math.Abs(f2) < eps2) x = x2; else { while (ind == 0) { count += 1; if (Math.Abs(f2-f1) < eps2) ind = -1; else { x = x2 - f2 * (x2 - x1) / (f2 - f1); double f = fn(x); if (Math.Abs(f) < eps2 || Math.Abs(x2-x1) < eps1 || Math.Abs(x2-x1) < eps1*Math.Abs(x2)) ind = count; else { if (count < max) { if (f1*f2 < 0.0) { x2 = x; f2 = f; } else { x1 = x; f1 = f; } } else ind = -1; } } } } } return x; } }
''''''''''''''''''''''''''''''''''''' ' セカント法による exp(x)-3x=0 の根 ' ' coded by Y.Suganuma ' ''''''''''''''''''''''''''''''''''''' Module Test Sub Main() ' ' データの設定 ' Dim eps1 As Double = 1.0e-10 Dim eps2 As Double = 1.0e-10 Dim x1 As Double = 0.0 Dim x2 As Double = 1.0 Dim max As Integer = 100 Dim ind As Integer = 0 ' ' 実行と結果 ' Dim snx = Function(v) As Double ' 関数値の計算(ラムダ式) Return Math.Exp(v) - 3.0 * v End Function Dim x As Double = secant(x1, x2, max, eps1, eps2, ind, snx) Console.WriteLine(" ind=" & ind & " x=" & x & " f=" & snx(x)) End Sub ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' secant法(はさみうち法)による非線形方程式f(x)=0の解 ' ' x1,x2 : 初期値(x1 < x2) ' ' max : 最大試行回数 ' ' eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) ' ' eps2 : 終了条件2(|f(x(k))|<eps2) ' ' ind : > 0 : 収束回数 ' ' =-1 : 収束しなかった ' ' fn : 関数値を計算する関数 ' ' return : 解 ' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Function secant(x1 As Double, x2 As Double, max As Integer, eps1 As Double, eps2 As Double, ByRef ind As Integer, fn As Func(Of Double, Double)) Dim f1 As Double = fn(x1) Dim f2 As Double = fn(x2) Dim x As Double = 0.0 Dim count As Integer = 0 ind = 0 If Math.Abs(f1) < eps2 x = x1 Else If Math.Abs(f2) < eps2 x = x2 Else Do While ind = 0 count += 1 If Math.Abs(f2-f1) < eps2 ind = -1 Else x = x2 - f2 * (x2 - x1) / (f2 - f1) Dim f As Double = fn(x) If Math.Abs(f) < eps2 or Math.Abs(x2-x1) < eps1 or Math.Abs(x2-x1) < eps1*Math.Abs(x2) ind = count Else If count < max If f1*f2 < 0.0 x2 = x f2 = f Else x1 = x f1 = f End If Else ind = -1 End If End If End If Loop End If End If Return x End Function End Module
情報学部 | 菅沼ホーム | 目次 | 索引 |