| 情報学部 | 菅沼ホーム | 目次 | 索引 |
/*********************************/
/* 二分法による exp(x)-3x=0 の根 */
/* coded by Y.Suganuma */
/*********************************/
#include <stdio.h>
#include <math.h>
double bisection(double (*)(double), double, double, double,
double, int, int *);
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 = bisection(snx, x1, x2, eps1, eps2, max, &ind);
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;
}
/*********************************************************/
/* 二分法による非線形方程式(f(x)=0)の解 */
/* f : f(x)を計算する関数名 */
/* x1,x2 : 初期値 */
/* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */
/* eps2 : 終了条件2(|f(x(k))|<eps2) */
/* max : 最大試行回数 */
/* ind : 実際の試行回数 */
/* (負の時は解を得ることができなかった) */
/* return : 解 */
/*********************************************************/
#include <math.h>
double bisection(double(*f)(double), double x1, double x2,
double eps1, double eps2, int max, int *ind)
{
double f0, f1, f2, x0 = 0.0;
int sw;
f1 = (*f)(x1);
f2 = (*f)(x2);
if (f1*f2 > 0.0)
*ind = -1;
else {
*ind = 0;
if (f1*f2 == 0.0)
x0 = (f1 == 0.0) ? x1 : x2;
else {
sw = 0;
while (sw == 0 && *ind >= 0) {
sw = 1;
*ind += 1;
x0 = 0.5 * (x1 + x2);
f0 = (*f)(x0);
if (fabs(f0) > eps2) {
if (*ind <= max) {
if (fabs(x1-x2) > eps1 && fabs(x1-x2) > eps1*fabs(x2)) {
sw = 0;
if (f0*f1 < 0.0) {
x2 = x0;
f2 = f0;
}
else {
x1 = x0;
f1 = f0;
}
}
}
else
*ind = -1;
}
}
}
}
return x0;
}
/*********************************/
/* 二分法による 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.bisection(x1, x2, eps1, eps2, max, ind);
System.out.println(" ind=" + ind[0] + " x=" + x + " f=" + kn.snx(x));
}
}
/****************/
/* 関数値の計算 */
/****************/
class Kansu extends Bisection
{
double snx(double x)
{
double y = Math.exp(x) - 3.0 * x;
return y;
}
}
abstract class Bisection
{
/*********************************************************/
/* 二分法による非線形方程式(f(x)=0)の解 */
/* x1,x2 : 初期値 */
/* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */
/* eps2 : 終了条件2(|f(x(k))|<eps2) */
/* max : 最大試行回数 */
/* ind : 実際の試行回数 */
/* (負の時は解を得ることができなかった) */
/* return : 解 */
/*********************************************************/
abstract double snx(double x); // 定義しておく必要あり
double bisection(double x1, double x2, double eps1, double eps2, int max, int ind[])
{
double f0, f1, f2, x0 = 0.0;
int sw;
f1 = snx(x1);
f2 = snx(x2);
if (f1*f2 > 0.0)
ind[0] = -1;
else {
ind[0] = 0;
if (f1*f2 == 0.0)
x0 = (f1 == 0.0) ? x1 : x2;
else {
sw = 0;
while (sw == 0 && ind[0] >= 0) {
sw = 1;
ind[0] += 1;
x0 = 0.5 * (x1 + x2);
f0 = snx(x0);
if (Math.abs(f0) > eps2) {
if (ind[0] <= max) {
if (Math.abs(x1-x2) > eps1 && Math.abs(x1-x2) > eps1*Math.abs(x2)) {
sw = 0;
if (f0*f1 < 0.0) {
x2 = x0;
f2 = f0;
}
else {
x1 = x0;
f1 = f0;
}
}
}
else
ind[0] = -1;
}
}
}
}
return x0;
}
}
<!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 = bisection(x1, x2, eps1, eps2, max, 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;
}
/**************************************************/
/* 二分法による非線形方程式(f(x)=0)の解 */
/* x1,x2 : 初期値 */
/* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1)*/
/* eps2 : 終了条件2(|f(x(k))|<eps2) */
/* max : 最大試行回数 */
/* fn : 関数値を計算する関数 */
/* return : 解 */
/**************************************************/
function bisection(x1, x2, eps1, eps2, max, fn)
{
let sw, f0, x0 = 0.0;
let f1 = fn(x1);
let f2 = fn(x2);
if (f1*f2 > 0.0)
ind = -1;
else {
ind = 0;
if (f1*f2 == 0.0)
x0 = (f1 == 0.0) ? x1 : x2;
else {
sw = 0;
while (sw == 0 && ind >= 0) {
sw = 1;
ind += 1;
x0 = 0.5 * (x1 + x2);
f0 = fn(x0);
if (Math.abs(f0) > eps2) {
if (ind <= max) {
if (Math.abs(x1-x2) > eps1 && Math.abs(x1-x2) > eps1*Math.abs(x2)) {
sw = 0;
if (f0*f1 < 0.0) {
x2 = x0;
f2 = f0;
}
else {
x1 = x0;
f1 = f0;
}
}
}
else
ind = -1;
}
}
}
}
return x0;
}
</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="bisec.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
/*
データの設定
*/
$eps1 = 1.0e-10;
$eps2 = 1.0e-10;
$max = 100;
$x1 = 0.0;
$x2 = 1.0;
/*
実行と結果
*/
$x = bisection("snx", $x1, $x2, $eps1, $eps2, $max, $ind);
printf(" ind=%d x=%f f= %f\n", $ind, $x, snx($x));
/*********************************/
/* 二分法による exp(x)-3x=0 の根 */
/* coded by Y.Suganuma */
/*********************************/
/****************/
/* 関数値の計算 */
/****************/
function snx($x)
{
return exp($x) - 3.0 * $x;
}
/*********************************************************/
/* 二分法による非線形方程式(f(x)=0)の解 */
/* fn : f(x)を計算する関数名 */
/* x1,x2 : 初期値 */
/* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */
/* eps2 : 終了条件2(|f(x(k))|<eps2) */
/* max : 最大試行回数 */
/* ind : 実際の試行回数 */
/* (負の時は解を得ることができなかった) */
/* return : 解 */
/*********************************************************/
function bisection($fn, $x1, $x2, $eps1, $eps2, $max, &$ind)
{
$x0 = 0.0;
$f1 = $fn($x1);
$f2 = $fn($x2);
if ($f1*$f2 > 0.0)
$ind = -1;
else {
$ind = 0;
if ($f1*$f2 == 0.0)
$x0 = ($f1 == 0.0) ? $x1 : $x2;
else {
$sw = 0;
while ($sw == 0 && $ind >= 0) {
$sw = 1;
$ind += 1;
$x0 = 0.5 * ($x1 + $x2);
$f0 = $fn($x0);
if (abs($f0) > $eps2) {
if ($ind <= $max) {
if (abs($x1-$x2) > $eps1 && abs($x1-$x2) > $eps1*abs($x2)) {
$sw = 0;
if ($f0*$f1 < 0.0) {
$x2 = $x0;
$f2 = $f0;
}
else {
$x1 = $x0;
$f1 = $f0;
}
}
}
else
$ind = -1;
}
}
}
}
return $x0;
}
?>
############################################
# 二分法による exp(x)-3x=0 の根
# coded by Y.Suganuma
############################################
############################################
# 二分法による非線形方程式(f(x)=0)の解
# x1,x2 : 初期値
# eps1 : 終了条件1(|x(k+1)-x(k)|<eps1)
# eps2 : 終了条件2(|f(x(k))|<eps2)
# max : 最大試行回数
# ind : 実際の試行回数
# (負の時は解を得ることができなかった)
# fn : f(x)を計算する関数名
# return : 解
# coded by Y.Suganuma
############################################
def bisection(x1, x2, eps1, eps2, max, ind, &fn)
x0 = 0.0
f1 = fn.call(x1)
f2 = fn.call(x2)
if f1*f2 > 0.0
ind[0] = -1
else
ind[0] = 0
if f1*f2 == 0.0
if f1 == 0.0
x0 = x1
else
x0 = x2
end
else
sw = 0
while sw == 0 && ind[0] >= 0
sw = 1
ind[0] += 1
x0 = 0.5 * (x1 + x2)
f0 = fn.call(x0)
if f0.abs() > eps2
if ind[0] <= max
if (x1-x2).abs() > eps1 && (x1-x2).abs() > eps1*x2.abs()
sw = 0
if f0*f1 < 0.0
x2 = x0
f2 = f0
else
x1 = x0
f1 = f0
end
end
else
ind[0] = -1
end
end
end
end
end
return x0
end
################
# 関数値の計算 #
################
snx = Proc.new { |x|
Math.exp(x) - 3.0 * x
}
# データの設定
eps1 = 1.0e-10
eps2 = 1.0e-10
max = 100
x1 = 0.0
x2 = 1.0
ind = [0]
# 実行と結果
x = bisection(x1, x2, eps1, eps2, max, ind, &snx)
print(" ind=", ind[0], " x=", x, " f= ", snx.call(x), "\n")
# -*- coding: UTF-8 -*-
import numpy as np
from math import *
############################################
# 二分法による非線形方程式(f(x)=0)の解
# fn : f(x)を計算する関数名
# x1,x2 : 初期値
# eps1 : 終了条件1(|x(k+1)-x(k)|<eps1)
# eps2 : 終了条件2(|f(x(k))|<eps2)
# max : 最大試行回数
# ind : 実際の試行回数
# (負の時は解を得ることができなかった)
# return : 解
# coded by Y.Suganuma
############################################
def bisection(fn, x1, x2, eps1, eps2, max, ind) :
x0 = 0.0
f1 = fn(x1)
f2 = fn(x2)
if f1*f2 > 0.0 :
ind[0] = -1
else :
ind[0] = 0
if f1*f2 == 0.0 :
if f1 == 0.0 :
x0 = x1
else :
x0 = x2
else :
sw = 0
while sw == 0 and ind[0] >= 0 :
sw = 1
ind[0] += 1
x0 = 0.5 * (x1 + x2)
f0 = fn(x0)
if abs(f0) > eps2 :
if ind[0] <= max :
if abs(x1-x2) > eps1 and abs(x1-x2) > eps1*abs(x2) :
sw = 0
if f0*f1 < 0.0 :
x2 = x0
f2 = f0
else :
x1 = x0
f1 = f0
else :
ind[0] = -1
return x0
################
# 関数値の計算 #
################
def snx(x) :
return exp(x) - 3.0 * x
############################################
# 二分法による exp(x)-3x=0 の根
# coded by Y.Suganuma
############################################
# データの設定
eps1 = 1.0e-10
eps2 = 1.0e-10
max = 100
x1 = 0.0
x2 = 1.0
ind = [0]
# 実行と結果
x = bisection(snx, x1, x2, eps1, eps2, max, ind)
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 = bisection(x1, x2, eps1, eps2, max, ref ind, snx);
Console.WriteLine(" ind=" + ind + " x=" + x + " f=" + snx(x));
}
/****************/
/* 関数値の計算 */
/****************/
double snx(double x)
{
return Math.Exp(x) - 3.0 * x;
}
/*********************************************************/
/* 二分法による非線形方程式(f(x)=0)の解 */
/* x1,x2 : 初期値 */
/* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */
/* eps2 : 終了条件2(|f(x(k))|<eps2) */
/* max : 最大試行回数 */
/* ind : 実際の試行回数 */
/* (負の時は解を得ることができなかった) */
/* fn : 関数値を計算する関数 */
/* return : 解 */
/*********************************************************/
double bisection(double x1, double x2, double eps1, double eps2, int max,
ref int ind, Func<double, double> fn)
{
double f1 = fn(x1);
double f2 = fn(x2);
double x0 = 0.0;
if (f1*f2 > 0.0)
ind = -1;
else {
ind = 0;
if (f1*f2 == 0.0)
x0 = (f1 == 0.0) ? x1 : x2;
else {
int sw = 0;
while (sw == 0 && ind >= 0) {
sw = 1;
ind += 1;
x0 = 0.5 * (x1 + x2);
double f0 = fn(x0);
if (Math.Abs(f0) > eps2) {
if (ind <= max) {
if (Math.Abs(x1-x2) > eps1 && Math.Abs(x1-x2) > eps1*Math.Abs(x2)) {
sw = 0;
if (f0*f1 < 0.0) {
x2 = x0;
f2 = f0;
}
else {
x1 = x0;
f1 = f0;
}
}
}
else
ind = -1;
}
}
}
}
return x0;
}
}
'''''''''''''''''''''''''''''''''
' 二分法による 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 = bisection(x1, x2, eps1, eps2, max, ind, snx)
Console.WriteLine(" ind=" & ind & " x=" & x & " f=" & snx(x))
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''
' 二分法による非線形方程式(f(x)=0)の解 '
' x1,x2 : 初期値 '
' eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) '
' eps2 : 終了条件2(|f(x(k))|<eps2) '
' max : 最大試行回数 '
' ind : 実際の試行回数 '
' (負の時は解を得ることができなかった) '
' fn : 関数値を計算する関数 '
' return : 解 '
'''''''''''''''''''''''''''''''''''''''''''''''''''''
Function bisection(x1 As Double, x2 As Double, eps1 As Double, eps2 As Double,
max As Integer, ByRef ind As Integer,
fn As Func(Of Double, Double))
Dim f1 As Double = fn(x1)
Dim f2 As Double = fn(x2)
Dim x0 As Double = 0.0
If f1*f2 > 0.0
ind = -1
Else
ind = 0
If f1*f2 = 0.0
If f1 = 0.0
x0 = x1
Else
x0 = x2
End If
Else
Dim sw As Integer = 0
Do While sw = 0 and ind >= 0
sw = 1
ind += 1
x0 = 0.5 * (x1 + x2)
Dim f0 As Double = fn(x0)
If Math.Abs(f0) > eps2
If ind <= max
If Math.Abs(x1-x2) > eps1 and Math.Abs(x1-x2) > eps1*Math.Abs(x2)
sw = 0
If f0*f1 < 0.0
x2 = x0
f2 = f0
Else
x1 = x0
f1 = f0
End If
End If
Else
ind = -1
End If
End If
Loop
End If
End If
Return x0
End Function
End Module
| 情報学部 | 菅沼ホーム | 目次 | 索引 |