静岡理工科大学 菅沼ホーム 目次 索引

補間法(ラグランジュ)

    1. A. C++
    2. B. Java
    3. C. JavaScript
    4. D. PHP
    5. E. Ruby
    6. F. Python
    7. G. C#
    8. H. VB

  プログラムは,ラグランジュ補間法のプログラムです.

  1. C++

    /****************************/
    /* 補間法(ラグランジュ)   */
    /*      coded by Y.Suganuma */
    /****************************/
    #include <stdio.h>
    
    double Lagrange(int, double *, double *, double);
    
    int main()
    {
    	double x[3], x1, y[3], y1;
    	int i1, n;
    					// 線形補間
    	n    = 1;
    	x[0] = 0.0;
    	x[1] = 2.0;
    	y[0] = 0.0;
    	y[1] = 4.0;
    
    	printf("線形補間\n");
    	x1 = 0.0;
    	for (i1 = 0; i1 <= 8; i1++) {
    		y1 = Lagrange(n, x, y, x1);
    		printf("   x %f y %f\n", x1, y1);
    		x1 += 0.25;
    	}
    
    					// 2次補間
    	n    = 2;
    	x[0] = 0.0;
    	x[1] = 1.0;
    	x[2] = 2.0;
    	y[0] = 0.0;
    	y[1] = 1.0;
    	y[2] = 4.0;
    
    	printf("2次補間\n");
    	x1 = 0.0;
    	for (i1 = 0; i1 <= 8; i1++) {
    		y1 = Lagrange(n, x, y, x1);
    		printf("   x %f y %f\n", x1, y1);
    		x1 += 0.25;
    	}
    
    	return 0;
    }
    
    /**********************************/
    /* ラグランジュ補間法             */
    /*      n : 次数(n=1は線形補間) */
    /*      x, y : (n+1)個の点の座標  */
    /*      x1 : 補間したい点のx座標 */
    /*      return : 補間結果         */
    /**********************************/
    double Lagrange(int n, double *x, double *y, double x1)
    {
    	double s1, s2, y1 = 0.0;
    	int i1, i2;
    
    	for (i1 = 0; i1 <= n; i1++) {
    		s1 = 1.0;
    		s2 = 1.0;
    		for (i2 = 0; i2 <= n; i2++) {
    			if (i2 != i1) {
    				s1 *= (x1 - x[i2]);
    				s2 *= (x[i1] - x[i2]);
    			}
    		}
    		y1 += y[i1] * s1 / s2;
    	}
    
    	return y1;
    }
    			

  2. Java

      アプレット版では,n 次補間多項式による計算結果を画面上で求めることができます.
    /****************************/
    /* 補間法(ラグランジュ)   */
    /*      coded by Y.Suganuma */
    /****************************/
    import java.io.*;
    
    public class Test {
    	public static void main(String args[]) throws IOException
    	{
    		double x[], x1, y[], y1;
    		int i1, n;
    
    		x = new double [3];
    		y = new double [3];
    					// 線形補間
    		n    = 1;
    		x[0] = 0.0;
    		x[1] = 2.0;
    		y[0] = 0.0;
    		y[1] = 4.0;
    
    		System.out.println("線形補間");
    		x1 = 0.0;
    		for (i1 = 0; i1 <= 8; i1++) {
    			y1 = lagrange(n, x, y, x1);
    			System.out.println("   x " + x1 + " y " + y1);
    			x1 += 0.25;
    		}
    
    					// 2次補間
    		n    = 2;
    		x[0] = 0.0;
    		x[1] = 1.0;
    		x[2] = 2.0;
    		y[0] = 0.0;
    		y[1] = 1.0;
    		y[2] = 4.0;
    
    		System.out.println("2次補間\n");
    		x1 = 0.0;
    		for (i1 = 0; i1 <= 8; i1++) {
    			y1 = lagrange(n, x, y, x1);
    			System.out.println("   x " + x1 + " y " + y1);
    			x1 += 0.25;
    		}
    	}
    
    	/**********************************/
    	/* ラグランジュ補間法             */
    	/*      n : 次数(n=1は線形補間) */
    	/*      x, y : (n+1)個の点の座標  */
    	/*      x1 : 補間したい点のx座標 */
    	/*      return : 補間結果         */
    	/**********************************/
    	static double lagrange(int n, double x[], double y[], double x1)
    	{
    		double s1, s2, y1 = 0.0;
    		int i1, i2;
    
    		for (i1 = 0; i1 <= n; i1++) {
    			s1 = 1.0;
    			s2 = 1.0;
    			for (i2 = 0; i2 <= n; i2++) {
    				if (i2 != i1) {
    					s1 *= (x1 - x[i2]);
    					s2 *= (x[i1] - x[i2]);
    				}
    			}
    			y1 += y[i1] * s1 / s2;
    		}
    
    		return y1;
    	}
    }
    			
    アプレット版
    /****************************/
    /* 補間法(ラグランジュ)   */
    /*      coded by Y.Suganuma */
    /****************************/
    import java.awt.*;
    import java.awt.event.*;
    import java.applet.*;
    import java.util.StringTokenizer;
    
    public class Lagrange extends Applet implements ActionListener {
    	TextField order, step;
    	TextArea ta1, ta2;
    	Button bt;
    	Font f = new Font("TimesRoman", Font.BOLD, 20);
    
    	/************/
    	/* 初期設定 */
    	/************/
    	public void init()
    	{
    					// レイアウト,背景色,フォント
    		setLayout(new BorderLayout(5, 5));
    		setBackground(new Color(225, 255, 225));
    		setFont(f);
    					// 上のパネル
    		Panel pn1 = new Panel();
    		add(pn1, BorderLayout.NORTH);
    
    		pn1.add(new Label("次数:"));
    		order = new TextField("2", 3);
    		pn1.add(order);
    
    		pn1.add(new Label("ステップ:"));
    		step = new TextField("0.25", 3);
    		pn1.add(step);
    
    		pn1.add(new Label(" "));
    		bt = new Button("OK");
    		bt.setBackground(Color.pink);
    		bt.addActionListener(this);
    		pn1.add(bt);
    					// 中央のパネル(データ)
    		Panel pn2 = new Panel();
    		add(pn2, BorderLayout.CENTER);
    
    		pn2.add(new Label("データ(x y):"));
    		ta1 = new TextArea("0.0 0.0\n1.0 1.0\n2.0 4.0\n", 10, 30);
    		pn2.add(ta1);
    					// 下のパネル(補間値)
    		Panel pn3 = new Panel();
    		add(pn3, BorderLayout.SOUTH);
    
    		ta2 = new TextArea(10, 30);
    		pn3.add(ta2);
    	}
    
    	/******************************/
    	/* ボタンが押されたときの処理 */
    	/******************************/
    	public void actionPerformed(ActionEvent e)
    	{
    		if (e.getSource() == bt) {
    					// 問題の設定
    			int n = Integer.parseInt(order.getText());
    			double sp = Double.parseDouble(step.getText());
    			double x[] = new double[n+1];
    			double y[] = new double[n+1];
    
    			String s = ta1.getText();
    			StringTokenizer str = new StringTokenizer(s, " \n");
    			int k = 0;
    			while (str.hasMoreTokens() && k < n+1) {
    				x[k] = Double.parseDouble(str.nextToken());
    				y[k] = Double.parseDouble(str.nextToken());
    				k++;
    			}
    					// 計算
    			ta2.setText("");
    			double x1 = x[0];
    			while (x1 < x[n]+0.01*sp) {
    				double y1 = lagrange(n, x, y, x1);
    				ta2.append("x " + String.format("%.5f",x1) + " y " + String.format("%.5f",y1) + "\n");
    				x1 += sp;
    			}
    		}
    	}
    
    	/**********************************/
    	/* ラグランジュ補間法             */
    	/*      n : 次数(n=1は線形補間) */
    	/*      x, y : (n+1)個の点の座標  */
    	/*      x1 : 補間したい点のx座標 */
    	/*      return : 補間結果         */
    	/**********************************/
    	double lagrange(int n, double x[], double y[], double x1)
    	{
    		double s1, s2, y1 = 0.0;
    		int i1, i2;
    
    		for (i1 = 0; i1 <= n; i1++) {
    			s1 = 1.0;
    			s2 = 1.0;
    			for (i2 = 0; i2 <= n; i2++) {
    				if (i2 != i1) {
    					s1 *= (x1 - x[i2]);
    					s2 *= (x[i1] - x[i2]);
    				}
    			}
    			y1 += y[i1] * s1 / s2;
    		}
    
    		return y1;
    	}
    }
    			

  3. JavaScript

      ここをクリックすると,n 次補間多項式による計算結果を画面上で求めることができます.
    <!DOCTYPE HTML>
    
    <HTML>
    
    <HEAD>
    
    	<TITLE>補間法(ラグランジュ)</TITLE>
    	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    	<SCRIPT TYPE="text/javascript">
    		function main()
    		{
    					// データの設定
    			let n  = parseInt(document.getElementById("order").value);
    			let sp = parseFloat(document.getElementById("step").value);
    			let x  = new Array();
    			let y  = new Array();
    			let s = (document.getElementById("data").value).split(/ {1,}|\n{1,}/);
    			let k = 0;
    			for (let i1 = 0; i1 < 2*(n+1); i1 += 2) {
    				x[k] = parseFloat(s[i1]);
    				y[k] = parseFloat(s[i1+1]);
    				k++;
    			}
    					// 出力
    			let str = "";
    			let x1 = x[0];
    			while (x1 < x[n]+0.01*sp) {
    				let y1 = lagrange(n, x, y, x1);
    				str = str + "x " + x1 + " y " + y1 + "\n";
    				x1 += sp;
    			}
    			document.getElementById("ans").value = str;
    		}
    
    		/**********************************/
    		/* ラグランジュ補間法             */
    		/*      n : 次数(n=1は線形補間) */
    		/*      x, y : (n+1)個の点の座標  */
    		/*      x1 : 補間したい点のx座標 */
    		/*      return : 補間結果         */
    		/**********************************/
    		function lagrange(n, x, y, x1)
    		{
    			let s1;
    			let s2;
    			let y1 = 0.0;
    			let i1;
    			let i2;
    
    			for (i1 = 0; i1 <= n; i1++) {
    				s1 = 1.0;
    				s2 = 1.0;
    				for (i2 = 0; i2 <= n; i2++) {
    					if (i2 != i1) {
    						s1 *= (x1 - x[i2]);
    						s2 *= (x[i1] - x[i2]);
    					}
    				}
    				y1 += y[i1] * s1 / s2;
    			}
    
    			return y1;
    		}
    	</SCRIPT>
    
    </HEAD>
    
    <BODY STYLE="font-size: 130%; background-color: #eeffee;">
    
    	<H2 STYLE="text-align:center"><B>補間法(ラグランジュ)</B></H2>
    
    	<DL>
    		<DT>  テキストフィールドおよびテキストエリアには,例として,3 点 ( 0, 0 ), ( 1, 1 ), ( 2, 4 ) を使用して 2 次のラグランジュ補間を実行するための値が設定されています.他の問題を実行する場合は,それらを適切に修正してください.
    	</DL>
    
    	<DIV STYLE="text-align:center">
    		次数(n):<INPUT ID="order" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="2"> 
    		ステップ:<INPUT ID="step" STYLE="font-size: 100%;" TYPE="text" SIZE="5" VALUE="0.25"> 
    		<BUTTON STYLE="font-size: 100%; background-color: pink" onClick="main()">OK</BUTTON><BR><BR>
    		データ(x y,(n+1)個):<TEXTAREA ID="data" COLS="30" ROWS="15" STYLE="font-size: 100%">0.0 0.0
    1.0 1.0
    2.0 4.0</TEXTAREA><BR><BR>
    		<TEXTAREA ID="ans" COLS="50" ROWS="15" STYLE="font-size: 100%"></TEXTAREA>
    	</DIV>
    
    </BODY>
    
    </HTML>
    			

  4. PHP

    <?php
    
    /****************************/
    /* 補間法(ラグランジュ)   */
    /*      coded by Y.Suganuma */
    /****************************/
    
    	$x    = array(3);
    	$y    = array(3);
    					// 線形補間
    	$n    = 1;
    	$x[0] = 0.0;
    	$x[1] = 2.0;
    	$y[0] = 0.0;
    	$y[1] = 4.0;
    
    	printf("線形補間\n");
    	$x1 = 0.0;
    	for ($i1 = 0; $i1 <= 8; $i1++) {
    		$y1 = Lagrange($n, $x, $y, $x1);
    		printf("   x %f y %f\n", $x1, $y1);
    		$x1 += 0.25;
    	}
    
    					// 2次補間
    	$n    = 2;
    	$x[0] = 0.0;
    	$x[1] = 1.0;
    	$x[2] = 2.0;
    	$y[0] = 0.0;
    	$y[1] = 1.0;
    	$y[2] = 4.0;
    
    	printf("2次補間\n");
    	$x1 = 0.0;
    	for ($i1 = 0; $i1 <= 8; $i1++) {
    		$y1 = Lagrange($n, $x, $y, $x1);
    		printf("   x %f y %f\n", $x1, $y1);
    		$x1 += 0.25;
    	}
    
    /**********************************/
    /* ラグランジュ補間法             */
    /*      n : 次数(n=1は線形補間) */
    /*      x, y : (n+1)個の点の座標  */
    /*      x1 : 補間したい点のx座標 */
    /*      return : 補間結果         */
    /**********************************/
    function Lagrange($n, $x, $y, $x1)
    {
    	$y1 = 0.0;
    
    	for ($i1 = 0; $i1 <= $n; $i1++) {
    		$s1 = 1.0;
    		$s2 = 1.0;
    		for ($i2 = 0; $i2 <= $n; $i2++) {
    			if ($i2 != $i1) {
    				$s1 *= ($x1 - $x[$i2]);
    				$s2 *= ($x[$i1] - $x[$i2]);
    			}
    		}
    		$y1 += $y[$i1] * $s1 / $s2;
    	}
    
    	return $y1;
    }
    
    ?>
    			

  5. Ruby

    #***************************/
    # 補間法(ラグランジュ)   */
    #      coded by Y.Suganuma */
    #***************************/
    
    #*********************************/
    # ラグランジュ補間法             */
    #      n : 次数(n=1は線形補間) */
    #      x, y : (n+1)個の点の座標  */
    #      x1 : 補間したい点のx座標 */
    #      return : 補間結果         */
    #*********************************/
    def Lagrange(n, x, y, x1)
    
    	y1 = 0.0
    
    	for i1 in 0 ... n+1
    		s1 = 1.0
    		s2 = 1.0
    		for i2 in 0 ... n+1
    			if i2 != i1
    				s1 *= (x1 - x[i2])
    				s2 *= (x[i1] - x[i2])
    			end
    		end
    		y1 += y[i1] * s1 / s2
    	end
    
    	return y1
    end
    
    x = Array.new(3)
    y = Array.new(3)
    				# 線形補間
    n    = 1
    x[0] = 0.0
    x[1] = 2.0
    y[0] = 0.0
    y[1] = 4.0
    
    printf("線形補間\n")
    x1 = 0.0
    for i1 in 0 ... 9
    	y1 = Lagrange(n, x, y, x1)
    	printf("   x %f y %f\n", x1, y1)
    	x1 += 0.25
    end
    
    				# 2次補間
    n    = 2
    x[0] = 0.0
    x[1] = 1.0
    x[2] = 2.0
    y[0] = 0.0
    y[1] = 1.0
    y[2] = 4.0
    
    printf("2次補間\n")
    x1 = 0.0
    for i1 in 0 ... 9
    	y1 = Lagrange(n, x, y, x1)
    	printf("   x %f y %f\n", x1, y1)
    	x1 += 0.25
    end
    			

  6. Python

    # -*- coding: UTF-8 -*-
    import numpy as np
    from math import *
    
    ############################################
    # ラグランジュ補間法
    #      n : 次数(n=1は線形補間)
    #      x, y : (n+1)個の点の座標
    #      x1 : 補間したい点のx座標
    #      return : 補間結果
    #      coded by Y.Suganuma
    ############################################
    
    def Lagrange(n, x, y, x1) :
    
    	y1 = 0.0
    
    	for i1 in range(0, n+1) :
    		s1 = 1.0
    		s2 = 1.0
    		for i2 in range(0, n+1) :
    			if i2 != i1 :
    				s1 *= (x1 - x[i2])
    				s2 *= (x[i1] - x[i2])
    		y1 += y[i1] * s1 / s2
    
    	return y1
    
    ############################################
    # 補間法(ラグランジュ)
    #      coded by Y.Suganuma
    ############################################
    
    x = np.array([0, 2, 2], np.float)
    y = np.array([0, 4, 4], np.float)
    			# 線形補間
    n = 1
    print("線形補間")
    x1 = 0.0
    for i1 in range(0, 9) :
    	y1 = Lagrange(n, x, y, x1)
    	print("   x " + str(x1) + " y " + str(y1))
    	x1 += 0.25
    
    			# 2次補間
    n    = 2
    x[1] = 1.0
    y[1] = 1.0
    print("2次補間")
    x1 = 0.0
    for i1 in range(0, 9) :
    	y1 = Lagrange(n, x, y, x1)
    	print("   x " + str(x1) + " y " + str(y1))
    	x1 += 0.25
    			

  7. C#

    /****************************/
    /* 補間法(ラグランジュ)   */
    /*      coded by Y.Suganuma */
    /****************************/
    using System;
    
    class Program
    {
    	static void Main()
    	{
    		Test1 ts = new Test1();
    	}
    }
    
    class Test1
    {
    	public Test1()
    	{
    		double[] x = new double [3];
    		double[] y = new double [3];
    					// 線形補間
    		int n = 1;
    		x[0]  = 0.0;
    		x[1]  = 2.0;
    		y[0]  = 0.0;
    		y[1]  = 4.0;
    
    		Console.WriteLine("線形補間");
    		double x1 = 0.0;
    		for (int i1 = 0; i1 <= 8; i1++) {
    			double y1 = lagrange(n, x, y, x1);
    			Console.WriteLine("   x " + x1 + " y " + y1);
    			x1 += 0.25;
    		}
    
    					// 2次補間
    		n    = 2;
    		x[0] = 0.0;
    		x[1] = 1.0;
    		x[2] = 2.0;
    		y[0] = 0.0;
    		y[1] = 1.0;
    		y[2] = 4.0;
    
    		Console.WriteLine("2次補間\n");
    		x1 = 0.0;
    		for (int i1 = 0; i1 <= 8; i1++) {
    			double y1 = lagrange(n, x, y, x1);
    			Console.WriteLine("   x " + x1 + " y " + y1);
    			x1 += 0.25;
    		}
    	}
    
    	/**********************************/
    	/* ラグランジュ補間法             */
    	/*      n : 次数(n=1は線形補間) */
    	/*      x, y : (n+1)個の点の座標  */
    	/*      x1 : 補間したい点のx座標 */
    	/*      return : 補間結果         */
    	/**********************************/
    	double lagrange(int n, double[] x, double[] y, double x1)
    	{
    		double y1 = 0.0;
    
    		for (int i1 = 0; i1 <= n; i1++) {
    			double s1 = 1.0;
    			double s2 = 1.0;
    			for (int i2 = 0; i2 <= n; i2++) {
    				if (i2 != i1) {
    					s1 *= (x1 - x[i2]);
    					s2 *= (x[i1] - x[i2]);
    				}
    			}
    			y1 += y[i1] * s1 / s2;
    		}
    
    		return y1;
    	}
    }
    			

  8. VB

    ''''''''''''''''''''''''''''
    ' 補間法(ラグランジュ)   '
    '      coded by Y.Suganuma '
    ''''''''''''''''''''''''''''
    Module Test
    
    	Sub Main()
    
    		Dim x(3) As Double
    		Dim y(3) As Double
    					' 線形補間
    		Dim n As Integer = 1
    		x(0) = 0.0
    		x(1) = 2.0
    		y(0) = 0.0
    		y(1) = 4.0
    
    		Console.WriteLine("線形補間")
    		Dim x1 As Double = 0.0
    		For i1 As Integer = 0 To 8
    			Dim y1 As Double = lagrange(n, x, y, x1)
    			Console.WriteLine("   x " & x1 & " y " & y1)
    			x1 += 0.25
    		Next
    
    					' 2次補間
    		n    = 2
    		x(0) = 0.0
    		x(1) = 1.0
    		x(2) = 2.0
    		y(0) = 0.0
    		y(1) = 1.0
    		y(2) = 4.0
    
    		Console.WriteLine("2次補間\n")
    		x1 = 0.0
    		For i1 As Integer = 0 To 8
    			Dim y1 As Double = lagrange(n, x, y, x1)
    			Console.WriteLine("   x " & x1 & " y " & y1)
    			x1 += 0.25
    		Next
    
    	End Sub
    
    	''''''''''''''''''''''''''''''''''
    	' ラグランジュ補間法             '
    	'      n : 次数(n=1は線形補間) '
    	'      x, y : (n+1)個の点の座標  '
    	'      x1 : 補間したい点のx座標 '
    	'      return : 補間結果         '
    	''''''''''''''''''''''''''''''''''
    	Function lagrange(n As Integer, x() As Double, y() As Double, x1 As Double)
    
    		Dim y1 As Double = 0.0
    
    		For i1 As Integer = 0 To n
    			Dim s1 As Double = 1.0
    			Dim s2 As Double = 1.0
    			For i2 As Integer = 0  To n
    				If i2 <> i1
    					s1 *= (x1 - x(i2))
    					s2 *= (x(i1) - x(i2))
    				End If
    			Next
    			y1 += y(i1) * s1 / s2
    		Next
    
    		Return y1
    
    	End Function
    
    End Module
    			

静岡理工科大学 菅沼ホーム 目次 索引