| 情報学部 | 菅沼ホーム | 目次 | 索引 | 
/*************************************/ /* セカント法による 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 : 解                                      */
/*********************************************************/
#include 
function 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
			
| 情報学部 | 菅沼ホーム | 目次 | 索引 |