情報学部 菅沼ホーム 目次 索引

ファジイ推論

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

  プログラム(使用方法)は,以下に示すような m 個の変数を使用した n 個の規則を基にしてファジイ推論を行うものです.なお,このプログラムは,クラスを使用して記述しています.

if x1 = A11, x2 = A12, ・・・ ,xm=A1m then y = B1
if x1 = A21, x2 = A22, ・・・ ,xm=A2m then y = B2
     ・・・・・・・・・・・・・
if x1 = An1, x2 = An2, ・・・ ,xm=Anm then y = Bn

  1. C++

    /****************************/
    /* ファジイ推論             */
    /*      coded by Y.Suganuma */
    /****************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    /*********************/
    /* クラスFuzzyの定義 */
    /*********************/
    class Fuzzy {
    		double ***left;   // [i][j][0] : 中心
                              //       [1] : 幅
    		double **right;   // [i][0] : 中心
                              //    [1] : 幅
    		double *omega;   // ωの値
    		int bun;   // 積分の分割数
    		int method;   // 推論方法
                          //    =0 : and,or
                          //    =1 : *,or
                          //    =2 : *,+
    		int n_rule;   // 規則の数
    		int n_val;   // 変数の数
    		int **rule;   // [i][j] =0 : i番目の規則はj番目の変数を使用しない
                          //        =1 : i番目の規則はj番目の変数を使用する
    	public:
    		Fuzzy(char *);   // コンストラクタ
    		~Fuzzy();   // デストラクタ
    		double Cross(double, double, double, double);
    		double Height(double, double *);
    		double Inf(double *);   // 推論の実行
    		double Result(double *);
    };
    
    /************************************/
    /* コンストラクタ                   */
    /*      name : 入力データファイル名 */
    /************************************/
    Fuzzy::Fuzzy(char *name)
    {
    	int i1, i2;
    	FILE *in;
    
    	in = fopen(name, "r");
    /*
         基本データの入力
    */
    	fscanf(in, "%*s %d %*s %d %*s %d %*s %d",
               &method, &n_rule, &n_val, &bun);
    /*
         領域の確保
    */
    	left  = new double ** [n_rule];
    	right = new double * [n_rule];
    	omega = new double [n_rule];
    	rule  = new int * [n_rule];
    
    	for (i1 = 0; i1 < n_rule; i1++) {
    		left[i1]  = new double * [n_val];
    		right[i1] = new double [2];
    		rule[i1]  = new int [n_val];
    		for (i2 = 0; i2 < n_val; i2++)
    			left[i1][i2]  = new double [2];
    	}
    /*
         規則データの入力
    */
    	for (i1 = 0; i1 < n_rule; i1++) {
    
    		fscanf(in, "%*s");
    						// 左辺
    		for (i2 = 0; i2 < n_val; i2++) {
    			fscanf(in, "%*s %d", &(rule[i1][i2]));
    			if (rule[i1][i2] > 0)
    				fscanf(in, "%*s %lf %lf", &(left[i1][i2][0]), &(left[i1][i2][1]));
    		}
    						// 右辺
    		fscanf(in, "%*s %lf %lf", &(right[i1][0]), &(right[i1][1]));
    	}
    
    	fclose(in);
    }
    
    /****************/
    /* デストラクタ */
    /****************/
    Fuzzy::~Fuzzy()
    {
    	int i1, i2;
    
    	for (i1 = 0; i1 < n_rule; i1++) {
    		for (i2 = 0; i2 < n_val; i2++)
    			delete [] left[i1][i2];
    		delete [] left[i1];
    		delete [] right[i1];
    		delete [] rule[i1];
    	}
    
    	delete [] left;
    	delete [] right;
    	delete [] rule;
    }
    
    /*******************************************/
    /* 交点の計算                              */
    /*      x : x                              */
    /*      c : 中心                           */
    /*      h : 幅                             */
    /*      r : < 0 : 左辺のメンバーシップ関数 */
    /*          >=0 : 右辺(ω)                 */
    /*      return : 交点                      */
    /*******************************************/
    double Fuzzy::Cross(double x, double c, double h, double r)
    {
    	double x1, x2, y, y1, y2;
    
    	if (x < c) {
    		x1 = c - h;
    		x2 = c;
    		y1 = 0.0;
    		y2 = (r < 0.0 || (r >= 0.0 && method == 0)) ? 1.0 : r;
    	}
    	else {
    		x1 = c;
    		x2 = c + h;
    		y1 = (r < 0.0 || (r >= 0.0 && method == 0)) ? 1.0 : r;
    		y2 = 0.0;
    	}
    
    	y = y1 + (y2 - y1) * (x - x1) / (x2 - x1);
    
    	if (y < 0.0)
    		y = 0.0;
    	else {
    		if (r >= 0.0 && method == 0 && y > r)
    			y = r;
    	}
    
    	return y;
    }
    
    /**********************************************/
    /* 右辺の計算                                 */
    /*      x : 値                                */
    /*      om[i] : < 0 : i番目の規則を使用しない*/
    /*              >=0 : ωの値                  */
    /*      return : xにおける右辺の値           */
    /**********************************************/
    double Fuzzy::Height(double x, double *om)
    {
    	double y = 0.0, y1;
    	int i1, sw;
    
    	sw = 0;
    
    	for (i1 = 0; i1 < n_rule; i1++) {
    
    		if (om[i1] >= 0.0) {
    
    			y1 = Cross(x, right[i1][0], right[i1][1], om[i1]);
    
    			if (sw == 0) {
    				y  = y1;
    				sw = 1;
    			}
    
    			else {
    				if (method < 2) {
    					if (y1 > y)
    						y = y1;
    				}
    				else
    					y += y1;
    			}
    		}
    	}
    
    	return y;
    }
    
    /**************************/
    /* 推論の実行             */
    /*      x[i] : 各変数の値 */
    /*      return : 推論値   */
    /**************************/
    double Fuzzy::Inf(double *x)
    {
    
    	double x1, y;
    	int i1, i2;
    /*
         ωの計算
    */
    	for (i1 = 0; i1 < n_rule; i1++) {
    
    		omega[i1] = -1.0;
    
    		for (i2 = 0; i2 < n_val; i2++) {
    
    			if (rule[i1][i2] > 0) {
    
    				if (x[i2] > left[i1][i2][0]-left[i1][i2][1] &&
                        x[i2] < left[i1][i2][0]+left[i1][i2][1])
    					x1 = Cross(x[i2], left[i1][i2][0], left[i1][i2][1], -1.0);
    				else
    					x1 = 0.0;
    
    				if (omega[i1] < 0.0)
    					omega[i1] = x1;
    				else {
    					if (method == 0) {
    						if (x1 < omega[i1])
    							omega[i1] = x1;
    					}
    					else
    						omega[i1] *= x1;
    				}
    			}
    		}
    	}
    /*
         右辺の計算
    */
    	y = Result(omega);
    
    	return y;
    }
    
    /**********************************************/
    /* 右辺による推論                             */
    /*      om[i] : < 0 : i番目の規則を使用しない*/
    /*              >=0 : ωの値                  */
    /*      return : 推論値                       */
    /**********************************************/
    double Fuzzy::Result(double *om)
    {
    	double h, max = 0.0, min = 0.0, x1, x2, y = 0.0, y1, y2, z1, z2;
    	int i1, sw;
    /*
         積分範囲と積分幅の計算
    */
    	sw = 0;
    
    	for (i1 = 0; i1 < n_rule; i1++) {
    		if (om[i1] >= 0.0) {
    			x1 = right[i1][0] - right[i1][1];
    			x2 = right[i1][0] + right[i1][1];
    			if (sw == 0) {
    				min = x1;
    				max = x2;
    				sw  = 1;
    			}
    			else {
    				if (x1 < min)
    					min = x1;
    				if (x2 > max)
    					max = x2;
    			}
    		}
    	}
    
    	h = (max - min) / bun;
    
    	if (h < 1.0e-15) {
    		printf("***error  invalid data (h = 0) ***\n");
    		exit(1);
    	}
    /*
         積分(重心の計算,台形則)
    */
    	z1 = Height(min, om);
    	z2 = Height(max, om);
    	y1 = 0.5 * (min * z1 + max * z2);
    	y2 = 0.5 * (z1 + z2);
    	x1 = min;
    
    	for (i1 = 0; i1 < bun-1; i1++) {
    		x1 += h;
    		z1  = Height(x1, om);
    		y1 += x1 * z1;
    		y2 += z1;
    	}
    
    	y1 *= h;
    	y2 *= h;
    
    	if (fabs(y2) > 1.0e-10)
    		y = y1 / y2;
    	else {
    		printf("***error  invalid data (y2 = 0) ***\n");
    		exit(1);
    	}
    
    	return y;
    }
    
    /****************/
    /* main program */
    /****************/
    int main(int argc, char *argv[])
    {
    	double *x, **xx, y;
    	int i1, i2, n_d, n_val;
    	FILE *in, *out;
    
    	if (argc == 4) {
    					// オブジェクトの生成
    		Fuzzy fz(argv[1]);
    					// 推論データの読み込み
    		in = fopen(argv[2], "r");
    		fscanf(in, "%*s %d %*s %d", &n_val, &n_d);
    		x  = new double [n_val];
    		xx = new double * [n_val];
    		for (i1 = 0; i1 < n_val; i1++) {
    			fscanf(in, "%*s");
    			xx[i1] = new double [n_d];
    			for (i2 = 0; i2 < n_d; i2++)
    				fscanf(in, "%lf", &xx[i1][i2]);
    		}
    		fclose(in);
    					// 推論とその結果の出力
    		out = fopen(argv[3], "w");
    		for (i1 = 0; i1 < n_d; i1++) {
    			for (i2 = 0; i2 < n_val; i2++) {
    				x[i2] = xx[i2][i1];
    				fprintf(out, "%f ", x[i2]);
    			}
    			y = fz.Inf(x);   // 推論
    			fprintf(out, "%f\n", y);
    		}
    		fclose(out);
    	}
    
    	else {
    		printf("***error   入力データファイル名を指定して下さい\n");
    		exit(1);
    	}
    
    	return 0;
    }
    
    /*
    ------------------------規則ファイル--------------
    推論方法 0 規則の数 3 変数の数 1 積分の分割数 100
    規則1
     変数1 1 中心と幅 1.0 1.0
     右辺(中心と幅) 1.0 15.0
    規則2
     変数1 1 中心と幅 2.0 1.0
     右辺(中心と幅) 11.0 15.0
    規則3
     変数1 1 中心と幅 3.0 1.0
     右辺(中心と幅) 21.0 15.0
    
    ------------------------推論ファイル--------------
    変数の数 1 データ数 21
    変数1 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0
    */
    			

  2. Java

    /****************************/
    /* ファジイ推論             */
    /*      coded by Y.Suganuma */
    /****************************/
    import java.io.*;
    import java.util.StringTokenizer;
    
    public class Test {
    	/****************/
    	/* main program */
    	/****************/
    	public static void main(String args[]) throws IOException, FileNotFoundException
    	{
    		double x[], xx[][], y;
    		int i1, i2, n_d, n_val;
    		StringTokenizer str;
    					// エラー
    		if (args.length != 3) {
    			System.out.print("***error   入力データファイル名を指定して下さい\n");
    			System.exit(1);
    		}
    
    		else {
    					// オブジェクトの生成
    			Fuzzy fz = new Fuzzy (args[0]);
    					// 推論データの読み込み
    			BufferedReader in = new BufferedReader(new FileReader(args[1]));
    			str = new StringTokenizer(in.readLine(), " ");
    			str.nextToken();
    			n_val = Integer.parseInt(str.nextToken());
    			str.nextToken();
    			n_d = Integer.parseInt(str.nextToken());
    			x  = new double [n_val];
    			xx = new double [n_val][n_d];
    			for (i1 = 0; i1 < n_val; i1++) {
    				str = new StringTokenizer(in.readLine(), " ");
    				str.nextToken();
    				for (i2 = 0; i2 < n_d; i2++) {
    					if (!str.hasMoreTokens())
    						str = new StringTokenizer(in.readLine(), " ");
    					xx[i1][i2] = Double.parseDouble(str.nextToken());
    				}
    			}
    			in.close();
    					// 推論とその結果の出力
    			PrintStream out = new PrintStream(new FileOutputStream(args[2]));
    			for (i1 = 0; i1 < n_d; i1++) {
    				for (i2 = 0; i2 < n_val; i2++) {
    					x[i2] = xx[i2][i1];
    					out.print(x[i2] + " ");
    				}
    				y = fz.Inf(x);   // 推論
    				out.println(y);
    			}
    		}
    	}
    }
    
    class Fuzzy {
    	private double left[][][];   // [i][j][0] : 中心
                                     //       [1] : 幅
    	private double right[][];   // [i][0] : 中心
                                    //    [1] : 幅
    	private double omega[];   // ωの値
    	private int bun;   // 積分の分割数
    	private int method;   // 推論方法
                              //    =0 : and,or
                              //    =1 : *,or
                              //    =2 : *,+
    	private int n_rule;   // 規則の数
    	private int n_val;   // 変数の数
    	private int rule[][];   // [i][j] =0 : i番目の規則はj番目の変数を使用しない
                                //        =1 : i番目の規則はj番目の変数を使用する
    
    	/************************************/
    	/* コンストラクタ                   */
    	/*      name : 入力データファイル名 */
    	/************************************/
    	Fuzzy (String name) throws IOException, FileNotFoundException
    	{
    		int i1, i2;
    		StringTokenizer str;
    
    		BufferedReader in = new BufferedReader(new FileReader(name));
    	/*
    	     基本データの入力
    	*/
    		str = new StringTokenizer(in.readLine(), " ");
    		str.nextToken();
    		method = Integer.parseInt(str.nextToken());
    		str.nextToken();
    		n_rule = Integer.parseInt(str.nextToken());
    		str.nextToken();
    		n_val = Integer.parseInt(str.nextToken());
    		str.nextToken();
    		bun = Integer.parseInt(str.nextToken());
    	/*
    	     領域の確保
    	*/
    		left  = new double [n_rule][n_val][2];
    		right = new double [n_rule][2];
    		omega = new double [n_rule];
    		rule  = new int [n_rule][n_val];
    	/*
    	     規則データの入力
    	*/
    		for (i1 = 0; i1 < n_rule; i1++) {
    
    			in.readLine();
    						// 左辺
    			for (i2 = 0; i2 < n_val; i2++) {
    				str = new StringTokenizer(in.readLine(), " ");
    				str.nextToken();
    				rule[i1][i2] = Integer.parseInt(str.nextToken());
    				if (rule[i1][i2] > 0) {
    					str.nextToken();
    					left[i1][i2][0] = Double.parseDouble(str.nextToken());
    					left[i1][i2][1] = Double.parseDouble(str.nextToken());
    				}
    			}
    						// 右辺
    			str = new StringTokenizer(in.readLine(), " ");
    			str.nextToken();
    			right[i1][0] = Double.parseDouble(str.nextToken());
    			right[i1][1] = Double.parseDouble(str.nextToken());
    		}
    
    		in.close();
    	}
    
    	/*******************************************/
    	/* 交点の計算                              */
    	/*      x : x                              */
    	/*      c : 中心                           */
    	/*      h : 幅                             */
    	/*      r : <0 : 左辺のメンバーシップ関数  */
    	/*          >=0 : 右辺(ω)                 */
    	/*      return : 交点                      */
    	/*******************************************/
    	double Cross(double x, double c, double h, double r)
    	{
    		double x1, x2, y, y1, y2;
    
    		if (x < c) {
    			x1 = c - h;
    			x2 = c;
    			y1 = 0.0;
    			y2 = (r < 0.0 || (r >= 0.0 && method == 0)) ? 1.0 : r;
    		}
    		else {
    			x1 = c;
    			x2 = c + h;
    			y1 = (r < 0.0 || (r >= 0.0 && method == 0)) ? 1.0 : r;
    			y2 = 0.0;
    		}
    
    		y = y1 + (y2 - y1) * (x - x1) / (x2 - x1);
    
    		if (y < 0.0)
    			y = 0.0;
    		else {
    			if (r >= 0.0 && method == 0 && y > r)
    				y = r;
    		}
    
    		return y;
    	}
    
    	/**********************************************/
    	/* 右辺の計算                                 */
    	/*      x : 値                                */
    	/*      om[i] : <0 : i番目の規則を使用しない */
    	/*              >=0 : ωの値                  */
    	/*      return : xにおける右辺の値           */
    	/**********************************************/
    	double Height(double x, double [] om)
    	{
    		double y = 0.0, y1;
    		int i1, sw;
    
    		sw = 0;
    
    		for (i1 = 0; i1 < n_rule; i1++) {
    
    			if (om[i1] >= 0.0) {
    
    				y1 = Cross(x, right[i1][0], right[i1][1], om[i1]);
    
    				if (sw == 0) {
    					y  = y1;
    					sw = 1;
    				}
    
    				else {
    					if (method < 2) {
    						if (y1 > y)
    							y = y1;
    					}
    					else
    						y += y1;
    				}
    			}
    		}
    
    		return y;
    	}
    
    	/**************************/
    	/* 推論の実行             */
    	/*      x[i] : 各変数の値 */
    	/*      return : 推論値   */
    	/**************************/
    	double Inf(double [] x)
    	{
    
    		double x1, y;
    		int i1, i2;
    	/*
    	     ωの計算
    	*/
    		for (i1 = 0; i1 < n_rule; i1++) {
    
    			omega[i1] = -1.0;
    
    			for (i2 = 0; i2 < n_val; i2++) {
    
    				if (rule[i1][i2] > 0) {
    
    					if (x[i2] > left[i1][i2][0]-left[i1][i2][1] &&
                            x[i2] < left[i1][i2][0]+left[i1][i2][1])
    						x1 = Cross(x[i2], left[i1][i2][0], left[i1][i2][1], -1.0);
    					else
    						x1 = 0.0;
    
    					if (omega[i1] < 0.0)
    						omega[i1] = x1;
    					else {
    						if (method == 0) {
    							if (x1 < omega[i1])
    								omega[i1] = x1;
    						}
    						else
    							omega[i1] *= x1;
    					}
    				}
    			}
    		}
    	/*
    	     右辺の計算
    	*/
    		y = Result(omega);
    
    		return y;
    	}
    
    	/**********************************************/
    	/* 右辺による推論                             */
    	/*      om[i] : <0 : i番目の規則を使用しない */
    	/*              >=0 : ωの値                  */
    	/*      return : 推論値                       */
    	/**********************************************/
    	double Result(double [] om)
    	{
    		double h, max = 0.0, min = 0.0, x1, x2, y = 0.0, y1, y2, z1, z2;
    		int i1, sw;
    	/*
    	     積分範囲と積分幅の計算
    	*/
    		sw = 0;
    
    		for (i1 = 0; i1 < n_rule; i1++) {
    			if (om[i1] >= 0.0) {
    				x1 = right[i1][0] - right[i1][1];
    				x2 = right[i1][0] + right[i1][1];
    				if (sw == 0) {
    					min = x1;
    					max = x2;
    					sw  = 1;
    				}
    				else {
    					if (x1 < min)
    						min = x1;
    					if (x2 > max)
    						max = x2;
    				}
    			}
    		}
    
    		h = (max - min) / bun;
    
    		if (h < 1.0e-15) {
    			System.out.print("***error  invalid data (h = 0) ***\n");
    			System.exit(1);
    		}
    	/*
    	     積分(重心の計算,台形則)
    	*/
    		z1 = Height(min, om);
    		z2 = Height(max, om);
    		y1 = 0.5 * (min * z1 + max * z2);
    		y2 = 0.5 * (z1 + z2);
    		x1 = min;
    
    		for (i1 = 0; i1 < bun-1; i1++) {
    			x1 += h;
    			z1  = Height(x1, om);
    			y1 += x1 * z1;
    			y2 += z1;
    		}
    
    		y1 *= h;
    		y2 *= h;
    
    		if (Math.abs(y2) > 1.0e-10)
    			y = y1 / y2;
    		else {
    			System.out.print("***error  invalid data (y2 = 0) ***\n");
    			System.exit(1);
    		}
    
    		return y;
    	}
    }
    
    /*
    ------------------------規則ファイル--------------
    推論方法 0 規則の数 3 変数の数 1 積分の分割数 100
    規則1
     変数1 1 中心と幅 1.0 1.0
     右辺(中心と幅) 1.0 15.0
    規則2
     変数1 1 中心と幅 2.0 1.0
     右辺(中心と幅) 11.0 15.0
    規則3
     変数1 1 中心と幅 3.0 1.0
     右辺(中心と幅) 21.0 15.0
    
    ------------------------推論ファイル--------------
    変数の数 1 データ数 21
    変数1 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0
    */
    			

  3. JavaScript

      ここをクリックして表示された画面においてデータを設定し,「実行」ボタンをクリックすれば画面上で実行可能です.

    <!DOCTYPE HTML>
    
    <HTML>
    
    <HEAD>
    
    	<TITLE>ファジー推論</TITLE>
    	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    	<SCRIPT TYPE="text/javascript">
    		res = "";
    		fz  = null;
    		/****************/
    		/* main program */
    		/****************/
    		function main()
    		{
    					// オブジェクトの生成
    			fz = new Fuzzy();
    					// 推論データの読み込み
    			let lines = (document.getElementById("data2").value).split('\n');
    			let str   = lines[0].split(' ').filter(function(e){return e.length > 0;});
    			let n_val = parseInt(str[1]);
    			let n_d   = parseInt(str[3]);
    			let x     = new Array(n_val);
    			let xx    = new Array(n_val);
    			for (let i1 = 0; i1 < n_val; i1++) {
    				xx[i1] = new Array(n_d);
    				str    = lines[i1+1].split(' ').filter(function(e){return e.length > 0;});
    				for (let i2 = 0; i2 < n_d; i2++)
    					xx[i1][i2] = parseFloat(str[i2+1]);
    			}
    					// 推論とその結果の出力
    			for (let i1 = 0; i1 < n_d; i1++) {
    				for (let i2 = 0; i2 < n_val; i2++) {
    					x[i2] = xx[i2][i1];
    					res  += (x[i2] + " ");
    				}
    				let y = fz.Inf(x);   // 推論
    				res  += (y + "\n");
    			}
    			document.getElementById("result").value = res;
    		}
    
    		/**********************/
    		/* Fuzzy オブジェクト */
    		/**********************/
    		function Fuzzy ()
    		{
    				//
    				// 基本データの入力
    				//
    			let lines   = (document.getElementById("data1").value).split('\n');
    			let str     = lines[0].split(' ').filter(function(e){return e.length > 0;});
    			this.method = parseInt(str[1]);
    			this.n_rule = parseInt(str[3]);
    			this.n_val  = parseInt(str[5]);
    			this.bun    = parseInt(str[7]);
    				//
    				// 領域の確保
    				//
    			this.omega = new Array(this.n_rule);   // ωの値
    			this.right = new Array(this.n_rule);
    			     // [i][0] : 中心
    			     //    [1] : 幅
    			this.rule  = new Array(this.n_rule);
    			     // [i][j] =0 : i番目の規則はj番目の変数を使用しない
    			     //        =1 : i番目の規則はj番目の変数を使用する
    			this.left  = new Array(this.n_rule);
    			     // [i][j][0] : 中心
    			     //       [1] : 幅
    			for (let i1 = 0; i1 < this.n_rule; i1++) {
    				this.right[i1] = new Array(2);
    				this.rule[i1]  = new Array(this.n_val);
    				this.left[i1]  = new Array(this.n_val);
    				for (let i2 = 0; i2 < this.n_val; i2++)
    					this.left[i1][i2] = new Array(2);
    			}
    				//
    				// 規則データの入力
    				//
    			for (let i1 = 0; i1 < this.n_rule; i1++) {
    						// 左辺
    				for (let i2 = 0; i2 < this.n_val; i2++) {
    					str = lines[(this.n_val+2)*i1+i2+2].split(' ').filter(function(e){return e.length > 0;});
    					this.rule[i1][i2] = parseInt(str[1]);
    					if (this.rule[i1][i2] > 0) {
    						this.left[i1][i2][0] = parseFloat(str[3]);
    						this.left[i1][i2][1] = parseFloat(str[4]);
    					}
    				}
    						// 右辺
    				str = lines[(this.n_val+2)*i1+this.n_val+2].split(' ').filter(function(e){return e.length > 0;});
    				this.right[i1][0] = parseFloat(str[1]);
    				this.right[i1][1] = parseFloat(str[2]);
    			}
    		}
    
    		/*******************************************/
    		/* 交点の計算                              */
    		/*      x : x                              */
    		/*      c : 中心                           */
    		/*      h : 幅                             */
    		/*      r : <0 : 左辺のメンバーシップ関数  */
    		/*          >=0 : 右辺(ω)                 */
    		/*      return : 交点                      */
    		/*******************************************/
    		Fuzzy.prototype.Cross = function(x, c, h, r)
    		{
    			let x1, x2, y1, y2;
    
    			if (x < c) {
    				x1 = c - h;
    				x2 = c;
    				y1 = 0.0;
    				y2 = (r < 0.0 || (r >= 0.0 && fz.method == 0)) ? 1.0 : r;
    			}
    			else {
    				x1 = c;
    				x2 = c + h;
    				y1 = (r < 0.0 || (r >= 0.0 && fz.method == 0)) ? 1.0 : r;
    				y2 = 0.0;
    			}
    
    			let y = y1 + (y2 - y1) * (x - x1) / (x2 - x1);
    
    			if (y < 0.0)
    				y = 0.0;
    			else {
    				if (r >= 0.0 && fz.method == 0 && y > r)
    					y = r;
    			}
    
    			return y;
    		}
    
    		/**********************************************/
    		/* 右辺の計算                                 */
    		/*      x : 値                                */
    		/*      om[i] : <0 : i番目の規則を使用しない */
    		/*              >=0 : ωの値                  */
    		/*      return : xにおける右辺の値           */
    		/**********************************************/
    		Fuzzy.prototype.Height = function(x, om)
    		{
    			let y  = 0.0;
    			let sw = 0;
    
    			for (let i1 = 0; i1 < fz.n_rule; i1++) {
    
    				if (om[i1] >= 0.0) {
    
    					let y1 = fz.Cross(x, fz.right[i1][0], fz.right[i1][1], om[i1]);
    
    					if (sw == 0) {
    						y  = y1;
    						sw = 1;
    					}
    
    					else {
    						if (fz.method < 2) {
    							if (y1 > y)
    								y = y1;
    						}
    						else
    							y += y1;
    					}
    				}
    			}
    
    			return y;
    		}
    
    		/**************************/
    		/* 推論の実行             */
    		/*      x[i] : 各変数の値 */
    		/*      return : 推論値   */
    		/**************************/
    		Fuzzy.prototype.Inf = function(x)
    		{
    				//
    				// ωの計算
    				//
    			for (let i1 = 0; i1 < fz.n_rule; i1++) {
    
    				fz.omega[i1] = -1.0;
    
    				for (let i2 = 0; i2 < fz.n_val; i2++) {
    
    					if (fz.rule[i1][i2] > 0) {
    
    						let x1 = 0.0;
    						if (x[i2] > fz.left[i1][i2][0]-fz.left[i1][i2][1] &&
            	                x[i2] < fz.left[i1][i2][0]+fz.left[i1][i2][1])
    							x1 = fz.Cross(x[i2], fz.left[i1][i2][0], fz.left[i1][i2][1], -1.0);
    						else
    							x1 = 0.0;
    
    						if (fz.omega[i1] < 0.0)
    							fz.omega[i1] = x1;
    						else {
    							if (fz.method == 0) {
    								if (x1 < fz.omega[i1])
    									fz.omega[i1] = x1;
    							}
    							else
    								fz.omega[i1] *= x1;
    						}
    					}
    				}
    			}
    				//
    				// 右辺の計算
    				//
    			let y = fz.Result(fz.omega);
    
    			return y;
    		}
    
    		/**********************************************/
    		/* 右辺による推論                             */
    		/*      om[i] : <0 : i番目の規則を使用しない */
    		/*              >=0 : ωの値                  */
    		/*      return : 推論値                       */
    		/**********************************************/
    		Fuzzy.prototype.Result = function(om)
    		{
    				//
    				// 積分範囲と積分幅の計算
    				//
    			let max = 0.0, min = 0.0, x1, x2, y = 0.0, y1, y2, z1, z2;
    			let sw = 0;
    
    			for (let i1 = 0; i1 < fz.n_rule; i1++) {
    				if (om[i1] >= 0.0) {
    					x1 = fz.right[i1][0] - fz.right[i1][1];
    					x2 = fz.right[i1][0] + fz.right[i1][1];
    					if (sw == 0) {
    						min = x1;
    						max = x2;
    						sw  = 1;
    					}
    					else {
    						if (x1 < min)
    							min = x1;
    						if (x2 > max)
    							max = x2;
    					}
    				}
    			}
    
    			let h = (max - min) / fz.bun;
    
    			if (h < 1.0e-15)
    				alert("***error  invalid data (h = 0) ***");
    				//
    				// 積分(重心の計算,台形則)
    				//
    			z1 = fz.Height(min, om);
    			z2 = fz.Height(max, om);
    			y1 = 0.5 * (min * z1 + max * z2);
    			y2 = 0.5 * (z1 + z2);
    			x1 = min;
    
    			for (let i1 = 0; i1 < fz.bun-1; i1++) {
    				x1 += h;
    				z1  = fz.Height(x1, om);
    				y1 += x1 * z1;
    				y2 += z1;
    			}
    
    			y1 *= h;
    			y2 *= h;
    
    			if (Math.abs(y2) > 1.0e-10)
    				y = y1 / y2;
    			else
    				alert("***error  invalid data (y2 = 0) ***");
    
    			return y;
    		}
    	</SCRIPT>
    
    </HEAD>
    
    <BODY STYLE="font-size: 130%; text-align:center; background-color: #eeffee;">
    
    	<H2><B>ファジー推論</B></H2>
    
    	<BUTTON STYLE="font-size: 100%; background-color: pink" onClick="return main()">実行</BUTTON><BR>
    	<DIV STYLE="width: 800px; margin-right: auto; margin-left: auto">
    		<DIV STYLE="text-align:center; float: right; width: 400px">
    			<DIV STYLE="text-align:center">推論ファイル</DIV>
    			<TEXTAREA ID="data2" COLS="40" ROWS="10" STYLE="font-size: 100%; width: 380px">
    変数の数 1 データ数 21
    変数1 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0
    			</TEXTAREA>
    		</DIV>
    		<DIV STYLE="text-align:center; width: 400px">
    			<DIV STYLE="text-align:center">規則ファイル</DIV>
    			<TEXTAREA ID="data1" COLS="40" ROWS="10" STYLE="font-size: 100%; width: 380px">
    推論方法 0 規則の数 3 変数の数 1 積分の分割数 100
    規則1
     変数1 1 中心と幅 1.0 1.0
     右辺(中心と幅) 1.0 15.0
    規則2
     変数1 1 中心と幅 2.0 1.0
     右辺(中心と幅) 11.0 15.0
    規則3
     変数1 1 中心と幅 3.0 1.0
     右辺(中心と幅) 21.0 15.0
    			</TEXTAREA>
    		</DIV>
    	</DIV>
    	<DIV STYLE="text-align:center">推論結果</DIV>
    	<TEXTAREA ID="result" COLS="50" ROWS="10" STYLE="font-size: 100%;"></TEXTAREA>
    </BODY>
    
    </HTML>
    			

  4. PHP

    <?php
    
    /****************************/
    /* ファジイ推論             */
    /*      coded by Y.Suganuma */
    /****************************/
    
    /*********************/
    /* クラスFuzzyの定義 */
    /*********************/
    class Fuzzy {
    	private $left;   // [i][j][0] : 中心
                         //       [1] : 幅
    	private $right;   // [i][0] : 中心
                          //    [1] : 幅
    	private $omega;   // ωの値
    	private $bun;   // 積分の分割数
    	private $method;   // 推論方法
                           //    =0 : and,or
                           //    =1 : *,or
                           //    =2 : *,+
    	private $n_rule;   // 規則の数
    	private $n_val;   // 変数の数
    	private $rule;   // [i][j] =0 : i番目の規則はj番目の変数を使用しない
                         //        =1 : i番目の規則はj番目の変数を使用する
    	
        /************************************/
    	/* コンストラクタ                   */
        /*      name : 入力データファイル名 */
    	/************************************/
    	function Fuzzy($name)
    	{
        	$in = fopen($name, "r");
        /*
             基本データの入力
    	*/
    		fscanf($in, "%*s %d %*s %d %*s %d %*s %d", $this->method, $this->n_rule, $this->n_val, $this->bun);
        /*
    	     領域の確保
        */
    		$this->left  = array($this->n_rule);
        	$this->right = array($this->n_rule);
    		$this->omega = array($this->n_rule);
    		$this->rule  = array($this->n_rule);
    	
        	for ($i1 = 0; $i1 < $this->n_rule; $i1++) {
        		$this->left[$i1]  = array($this->n_val);
        		$this->right[$i1] = array(2);
    			$this->rule[$i1]  = array($this->n_val);
    			for ($i2 = 0; $i2 < $this->n_val; $i2++)
    				$this->left[$i1][$i2]  = array(2);
        	}
    	/*
             規則データの入力
    	*/
        	for ($i1 = 0; $i1 < $this->n_rule; $i1++) {
    	
    			fgets($in);
    							// 左辺
        		for ($i2 = 0; $i2 < $this->n_val; $i2++) {
     			 	$str = trim(fgets($in));
    			    strtok($str, " ");
       				$this->rule[$i1][$i2] = intval(strtok(" "));
        			if ($this->rule[$i1][$i2] > 0) {
    			    	strtok(" ");
    					$this->left[$i1][$i2][0] = floatval(strtok(" "));
    					$this->left[$i1][$i2][1] = floatval(strtok(" "));
    				}
    			}
    							// 右辺
        		fscanf($in, "%*s %lf %lf", $this->right[$i1][0], $this->right[$i1][1]);
    		}
        
    		fclose($in);
        }
    	
    	/*******************************************/
    	/* 交点の計算                              */
        /*      x : x                              */
        /*      c : 中心                           */
        /*      h : 幅                             */
    	/*      r : <0 : 左辺のメンバーシップ関数  */
    	/*          >=0 : 右辺(ω)                 */
    	/*      return : 交点                      */
        /*******************************************/
    	function Cross($x, $c, $h, $r)
        {
    		if ($x < $c) {
        		$x1 = $c - $h;
    			$x2 = $c;
    			$y1 = 0.0;
    			$y2 = ($r < 0.0 || ($r >= 0.0 && $this->method == 0)) ? 1.0 : $r;
        	}
        	else {
        		$x1 = $c;
    			$x2 = $c + $h;
    			$y1 = ($r < 0.0 || ($r >= 0.0 && $this->method == 0)) ? 1.0 : $r;
    			$y2 = 0.0;
        	}
    	
        	$y = $y1 + ($y2 - $y1) * ($x - $x1) / ($x2 - $x1);
    	
        	if ($y < 0.0)
    			$y = 0.0;
    		else {
    			if ($r >= 0.0 && $this->method == 0 && $y > $r)
        			$y = $r;
        	}
        
    		return $y;
    	}
    	
        /**********************************************/
    	/* 右辺の計算                                 */
        /*      x : 値                                */
    	/*      om[i] : <0 : i番目の規則を使用しない */
        /*              >=0 : ωの値                  */
    	/*      return : xにおける右辺の値           */
    	/**********************************************/
    	function Height($x, $om)
        {
        	$y  = 0.0;
        	$sw = 0;
    	
    		for ($i1 = 0; $i1 < $this->n_rule; $i1++) {
    	
        		if ($om[$i1] >= 0.0) {
    	
        			$y1 = $this->Cross($x, $this->right[$i1][0], $this->right[$i1][1], $om[$i1]);
    	
        			if ($sw == 0) {
    					$y  = $y1;
    					$sw = 1;
    				}
        
        			else {
        				if ($this->method < 2) {
    						if ($y1 > $y)
    							$y = $y1;
    					}
        				else
    						$y += $y1;
        			}
    			}
        	}
    	
    		return $y;
    	}
        
        /**************************/
        /* 推論の実行             */
    	/*      x[i] : 各変数の値 */
    	/*      return : 推論値   */
    	/**************************/
        function Inf($x)
    	{
        /*
    	     ωの計算
        */
    		for ($i1 = 0; $i1 < $this->n_rule; $i1++) {
    	
    			$this->omega[$i1] = -1.0;
        
        		for ($i2 = 0; $i2 < $this->n_val; $i2++) {
        
    				if ($this->rule[$i1][$i2] > 0) {
    	
    					if ($x[$i2] > $this->left[$i1][$i2][0]-$this->left[$i1][$i2][1] &&
                            $x[$i2] < $this->left[$i1][$i2][0]+$this->left[$i1][$i2][1])
    						$x1 = $this->Cross($x[$i2], $this->left[$i1][$i2][0], $this->left[$i1][$i2][1], -1.0);
        				else
    						$x1 = 0.0;
        
    					if ($this->omega[$i1] < 0.0)
    						$this->omega[$i1] = $x1;
    					else {
        					if ($this->method == 0) {
        						if ($x1 < $this->omega[$i1])
        							$this->omega[$i1] = $x1;
    						}
    						else
    							$this->omega[$i1] *= $x1;
        				}
    				}
        		}
    		}
        /*
    	     右辺の計算
    	*/
    		$y = $this->Result($this->omega);
        
        	return $y;
        }
    	
    	/**********************************************/
    	/* 右辺による推論                             */
        /*      om[i] : <0 : i番目の規則を使用しない */
    	/*              >=0 : ωの値                  */
        /*      return : 推論値                       */
    	/**********************************************/
        function Result($om)
    	{
    		$max = 0.0;
    		$min = 0.0;
        	$y   = 0.0;
        	$sw  = 0;
        /*
    	     積分範囲と積分幅の計算
    	*/
    		for ($i1 = 0; $i1 < $this->n_rule; $i1++) {
        		if ($om[$i1] >= 0.0) {
    				$x1 = $this->right[$i1][0] - $this->right[$i1][1];
        			$x2 = $this->right[$i1][0] + $this->right[$i1][1];
    				if ($sw == 0) {
        				$min = $x1;
    					$max = $x2;
    					$sw  = 1;
    				}
        			else {
        				if ($x1 < $min)
        					$min = $x1;
    					if ($x2 > $max)
    						$max = $x2;
    				}
        		}
    		}
        
    		$h = ($max - $min) / $this->bun;
        
    		if ($h < 1.0e-15)
    			exit("***error  invalid data (h = 0) ***\n");
        /*
             積分(重心の計算,台形則)
    	*/
    		$z1 = $this->Height($min, $om);
    		$z2 = $this->Height($max, $om);
        	$y1 = 0.5 * ($min * $z1 + $max * $z2);
    		$y2 = 0.5 * ($z1 + $z2);
        	$x1 = $min;
    	
        	for ($i1 = 0; $i1 < $this->bun-1; $i1++) {
    			$x1 += $h;
    			$z1  = $this->Height($x1, $om);
    			$y1 += $x1 * $z1;
        		$y2 += $z1;
        	}
        
    		$y1 *= $h;
    		$y2 *= $h;
    	
        	if (abs($y2) > 1.0e-10)
    			$y = $y1 / $y2;
        	else
    			exit("***error  invalid data (y2 = 0) ***\n");
    	
    		return $y;
        }
    }
        
    /****************/
    /* main program */
    /****************/
    
    	if (count($argv) == 4) {
    					// オブジェクトの生成
    		$fz = new Fuzzy($argv[1]);
    					// 推論データの読み込み
    		$in = fopen($argv[2], "rb");
    		fscanf($in, "%*s %d %*s %d", $n_val, $n_d);
    		$x  = array($n_val);
    		$xx = array($n_val);
    		for ($i1 = 0; $i1 < $n_val; $i1++) {
     			$xx[$i1] = array($n_d);
    		 	$str = trim(fgets($in));
    			strtok($str, " ");
    			for ($i2 = 0; $i2 < $n_d; $i2++)
    				$xx[$i1][$i2] = floatval(strtok(" "));
    		}
    		fclose($in);
    					// 推論とその結果の出力
    		$out = fopen($argv[3], "w");
    		for ($i1 = 0; $i1 < $n_d; $i1++) {
    			$str = "";
    			for ($i2 = 0; $i2 < $n_val; $i2++) {
    				$x[$i2] = $xx[$i2][$i1];
    				$str = $str.$x[$i2]." ";
    			}
    			$y = $fz->Inf($x);   // 推論
    			$str = $str."res ".$y."\n";
    			fwrite($out, $str);
    		}
    		fclose($out);
    	}
    
    	else
    		exit("***error   入力データファイル名を指定して下さい\n");
    
    /*
    ------------------------規則ファイル--------------
    推論方法 0 規則の数 3 変数の数 1 積分の分割数 100
    規則1
     変数1 1 中心と幅 1.0 1.0
     右辺(中心と幅) 1.0 15.0
    規則2
     変数1 1 中心と幅 2.0 1.0
     右辺(中心と幅) 11.0 15.0
    規則3
     変数1 1 中心と幅 3.0 1.0
     右辺(中心と幅) 21.0 15.0
    
    ------------------------推論ファイル--------------
    変数の数 1 データ数 21
    変数1 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0
    */
    
    ?>
    			

  5. Ruby

    ############################
    # ファジイ推論
    #      coded by Y.Suganuma
    ############################
    
    ############################
    # クラスFuzzyの定義
    #      coded by Y.Suganuma
    ############################
    
    class Fuzzy
    	
    	#####################################
    	# コンストラクタ
    	#      name : 入力データファイル名
    	#####################################
    	
    	def initialize(name)
    
    		in_f = open(name, "r")
    			# 基本データの入力
    		s        = in_f.gets().split(" ")
    		@_method = Integer(s[1])   # 推論方法
    	                               #    =0 : and,or
    	                               #    =1 : *,or
    	                               #    =2 : *,+
    		@_n_rule = Integer(s[3])   # 規則の数
    		@_n_val  = Integer(s[5])   # 変数の数
    		@_bun    = Integer(s[7])   # 積分の分割数
    			# 領域の確保
    		@_omega = Array.new(@_n_rule)   # ωの値
    		@_rule  = Array.new(@_n_rule)
    		               # [i][j] =0 : i番目の規則はj番目の変数を使用しない
    		               #        =1 : i番目の規則はj番目の変数を使用する
    		@_right = Array.new(@_n_rule)
    		               # [i][0] : 中心
    		               # [i][1] : 幅
    		@_left  = Array.new(@_n_rule)
    		               # [i][j][0] : 中心
    		               # [i][j][1] : 幅
    		for i1 in 0 ... @_n_rule
    			@_rule[i1]  = Array.new(@_n_val)
    			@_right[i1] = Array.new(2)
    			@_left[i1]  = Array.new(@_n_rule)
    			for i2 in 0 ... @_n_rule
    				@_left[i1][i2]  = Array.new(2)
    			end
    		end
    			# 規則データの入力
    		for i1 in 0 ... @_n_rule
    	
    			in_f.gets()
    							# 左辺
    			for i2 in 0 ... @_n_val
    				s              = in_f.gets().split(" ")
    				@_rule[i1][i2] = Integer(s[1])
    				if @_rule[i1][i2] > 0
    					@_left[i1][i2][0] = Float(s[3])
    					@_left[i1][i2][1] = Float(s[4])
    				end
    			end
    							# 右辺
    			s              = in_f.gets().split(" ")
    			@_right[i1][0] = Float(s[1])
    			@_right[i1][1] = Float(s[2])
    		end
    	
    		in_f.close()
    	end
    	
    	###########################################
    	# 交点の計算
    	#      x : x
    	#      c : 中心
    	#      h : 幅
    	#      r : <0 : 左辺のメンバーシップ関数
    	#          >=0 : 右辺(ω) 
    	#      return : 交点
    	###########################################
    	
    	def Cross(x, c, h, r)
    	
    		if x < c
    			x1 = c - h
    			x2 = c
    			y1 = 0.0
    			if r < 0.0 or (r >= 0.0 and @_method == 0)
    				y2 = 1.0
    			else
    				y2 = r
    			end
    		else
    			x1 = c
    			x2 = c + h
    			if r < 0.0 or (r >= 0.0 and @_method == 0)
    				y1 = 1.0
    			else
    				y1 = r
    			end
    			y2 = 0.0
    		end
    	
    		y = y1 + (y2 - y1) * (x - x1) / (x2 - x1)
    	
    		if y < 0.0
    			y = 0.0
    		else
    			if r >= 0.0 and @_method == 0 and y > r
    				y = r
    			end
    		end
    	
    		return y
    	end
    	
    	##############################################
    	# 右辺の計算
    	#      x : 値
    	#      om[i] : <0 : i番目の規則を使用しない
    	#              >=0 : ωの値
    	#      return : xにおける右辺の値
    	##############################################
    	
    	def Height(x, om)
    
    		y  = 0.0
    		sw = 0
    	
    		for i1 in 0 ... @_n_rule
    	
    			if om[i1] >= 0.0
    	
    				y1 = Cross(x, @_right[i1][0], @_right[i1][1], om[i1])
    	
    				if sw == 0
    					y  = y1
    					sw = 1
    				else
    					if @_method < 2
    						if y1 > y
    							y = y1
    						end
    					else
    						y += y1
    					end
    				end
    			end
    		end
    	
    		return y
    	end
    	
    	##########################
    	# 推論の実行
    	#      x[i] : 各変数の値
    	#      return : 推論値
    	##########################
    	
    	def Inf(x)
    	
    			# ωの計算
    		for i1 in 0 ... @_n_rule
    	
    			@_omega[i1] = -1.0
    	
    			for i2 in 0 ... @_n_val
    	
    				if @_rule[i1][i2] > 0
    	
    					if x[i2] > @_left[i1][i2][0]-@_left[i1][i2][1] and x[i2] < @_left[i1][i2][0]+@_left[i1][i2][1]
    						x1 = Cross(x[i2], @_left[i1][i2][0], @_left[i1][i2][1], -1.0)
    					else
    						x1 = 0.0
    					end
    	
    					if @_omega[i1] < 0.0
    						@_omega[i1] = x1
    					else
    						if @_method == 0
    							if x1 < @_omega[i1]
    								@_omega[i1] = x1
    							end
    						else
    							@_omega[i1] *= x1
    						end
    					end
    				end
    			end
    		end
    			# 右辺の計算
    		y = Result(@_omega)
    	
    		return y
    	end
    	
    	##############################################
    	# 右辺による推論
    	#      om[i] : <0 : i番目の規則を使用しない
    	#              >=0 : ωの値
    	#      return : 推論値
    	##############################################
    	
    	def Result(om)
    
    		max = 0.0
    		min = 0.0
    		y   = 0.0
    		sw  = 0
    			# 積分範囲と積分幅の計算
    		for i1 in 0 ... @_n_rule
    			if om[i1] >= 0.0
    				x1 = @_right[i1][0] - @_right[i1][1]
    				x2 = @_right[i1][0] + @_right[i1][1]
    				if sw == 0
    					min = x1
    					max = x2
    					sw  = 1
    				else
    					if x1 < min
    						min = x1
    					end
    					if x2 > max
    						max = x2
    					end
    				end
    			end
    		end
    	
    		h = (max - min) / @_bun
    	
    		if h < 1.0e-15
    			print("***error  invalid data (h = 0) ***\n")
    		end
    			# 積分(重心の計算,台形則)
    		z1 = Height(min, om)
    		z2 = Height(max, om)
    		y1 = 0.5 * (min * z1 + max * z2)
    		y2 = 0.5 * (z1 + z2)
    		x1 = min
    	
    		for i1 in 0 ... @_bun-1
    			x1 += h
    			z1  = Height(x1, om)
    			y1 += x1 * z1
    			y2 += z1
    		end
    	
    		y1 *= h
    		y2 *= h
    	
    		if y2.abs() > 1.0e-10
    			y = y1 / y2
    		else
    			print("***error  invalid data (y2 = 0) ***\n")
    		end
    	
    		return y
    	end
    end
    
    if ARGV.length == 3
    	file1 = ARGV[0]
    	file2 = ARGV[1]
    	file3 = ARGV[2]
    				# オブジェクトの生成
    	fz = Fuzzy.new(file1)
    				# 推論データの読み込み
    	in_f  = open(file2, "r")
    	s     = in_f.gets().split(" ")
    	n_val = Integer(s[1])
    	n_d   = Integer(s[3])
    	x     = Array.new(n_val)
    	xx    = Array.new(n_val)
    	for i1 in 0 ... n_val
    		xx[i1] = Array.new(n_d)
    		s      = in_f.gets().split(" ")
    		for i2 in 0 ... n_d
    			xx[i1][i2] = Float(s[i2+1])
    		end
    	end
    	in_f.close()
    				# 推論とその結果の出力
    	out = open(file3, "w")
    	for i1 in 0 ... n_d
    		for i2 in 0 ... n_val
    			x[i2] = xx[i2][i1]
    			out.print(String(x[i2]) + " ")
    		end
    		y = fz.Inf(x)   # 推論
    		out.print(String(y) + "\n")
    	end
    	out.close()
    
    else
    	print("***error   入力データファイル名を指定して下さい\n")
    end
    
    =begin
    ------------------------規則ファイル--------------
    推論方法 0 規則の数 3 変数の数 1 積分の分割数 100
    規則1
     変数1 1 中心と幅 1.0 1.0
     右辺(中心と幅) 1.0 15.0
    規則2
     変数1 1 中心と幅 2.0 1.0
     右辺(中心と幅) 11.0 15.0
    規則3
     変数1 1 中心と幅 3.0 1.0
     右辺(中心と幅) 21.0 15.0
    
    ------------------------推論ファイル--------------
    変数の数 1 データ数 21
    変数1 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0
    =end
    			

  6. Python

    # -*- coding: UTF-8 -*-
    import numpy as np
    import sys
    from math import *
    from random import *
    
    ############################
    # クラスFuzzyの定義
    #      coded by Y.Suganuma
    ############################
    
    class Fuzzy :
    	
    	#####################################
    	# コンストラクタ
    	#      name : 入力データファイル名
    	#####################################
    	
    	def __init__(self, name) :
    
    		in_f = open(name, "r")
    			# 基本データの入力
    		s           = in_f.readline().split()
    		self.method = int(s[1])   # 推論方法
    	                              #    =0 : and,or
    	                              #    =1 : *,or
    	                              #    =2 : *,+
    		self.n_rule = int(s[3])   # 規則の数
    		self.n_val = int(s[5])   # 変数の数
    		self.bun = int(s[7])   # 積分の分割数
    			# 領域の確保
    		self.omega = np.empty(self.n_rule, np.float)   # ωの値
    		self.rule  = np.empty((self.n_rule, self.n_val), np.int)
    		               # [i][j] =0 : i番目の規則はj番目の変数を使用しない
    		               #        =1 : i番目の規則はj番目の変数を使用する
    		self.right = np.empty((self.n_rule, 2), np.float)
    		               # [i][0] : 中心
    		               # [i][1] : 幅
    		self.left  = np.empty((self.n_rule, self.n_rule, 2), np.float)
    		               # [i][j][0] : 中心
    		               # [i][j][1] : 幅
    			# 規則データの入力
    		for i1 in range(0, self.n_rule) :
    	
    			in_f.readline()
    							# 左辺
    			for i2 in range(0, self.n_val) :
    				s                 = in_f.readline().split()
    				self.rule[i1][i2] = int(s[1])
    				if self.rule[i1][i2] > 0 :
    					self.left[i1][i2][0] = float(s[3])
    					self.left[i1][i2][1] = float(s[4])
    							# 右辺
    			s                 = in_f.readline().split()
    			self.right[i1][0] = float(s[1])
    			self.right[i1][1] = float(s[2])
    	
    		in_f.close()
    	
    	###########################################
    	# 交点の計算
    	#      x : x
    	#      c : 中心
    	#      h : 幅
    	#      r : <0 : 左辺のメンバーシップ関数
    	#          >=0 : 右辺(ω) 
    	#      return : 交点
    	###########################################
    	
    	def Cross(self, x, c, h, r) :
    	
    		if x < c :
    			x1 = c - h
    			x2 = c
    			y1 = 0.0
    			if r < 0.0 or (r >= 0.0 and self.method == 0) :
    				y2 = 1.0
    			else :
    				y2 = r
    		else :
    			x1 = c
    			x2 = c + h
    			if r < 0.0 or (r >= 0.0 and self.method == 0) :
    				y1 = 1.0
    			else :
    				y1 = r
    			y2 = 0.0
    	
    		y = y1 + (y2 - y1) * (x - x1) / (x2 - x1)
    	
    		if y < 0.0 :
    			y = 0.0
    		else :
    			if r >= 0.0 and self.method == 0 and y > r :
    				y = r
    	
    		return y
    	
    	##############################################
    	# 右辺の計算
    	#      x : 値
    	#      om[i] : <0 : i番目の規則を使用しない
    	#              >=0 : ωの値
    	#      return : xにおける右辺の値
    	##############################################
    	
    	def Height(self, x, om) :
    
    		y  = 0.0
    		sw = 0
    	
    		for i1 in range(0, self.n_rule) :
    	
    			if om[i1] >= 0.0 :
    	
    				y1 = self.Cross(x, self.right[i1][0], self.right[i1][1], om[i1])
    	
    				if sw == 0 :
    					y  = y1
    					sw = 1
    				else :
    					if self.method < 2 :
    						if y1 > y :
    							y = y1
    					else :
    						y += y1
    	
    		return y
    	
    	##########################
    	# 推論の実行
    	#      x[i] : 各変数の値
    	#      return : 推論値
    	##########################
    	
    	def Inf(self, x) :
    	
    			# ωの計算
    		for i1 in range(0, self.n_rule) :
    	
    			self.omega[i1] = -1.0
    	
    			for i2 in range(0, self.n_val) :
    	
    				if self.rule[i1][i2] > 0 :
    	
    					if x[i2] > self.left[i1][i2][0]-self.left[i1][i2][1] and x[i2] < self.left[i1][i2][0]+self.left[i1][i2][1] :
    						x1 = self.Cross(x[i2], self.left[i1][i2][0], self.left[i1][i2][1], -1.0)
    					else :
    						x1 = 0.0
    	
    					if self.omega[i1] < 0.0 :
    						self.omega[i1] = x1
    					else :
    						if self.method == 0 :
    							if x1 < self.omega[i1] :
    								self.omega[i1] = x1
    						else :
    							self.omega[i1] *= x1
    			# 右辺の計算
    		y = self.Result(self.omega)
    	
    		return y
    	
    	##############################################
    	# 右辺による推論
    	#      om[i] : <0 : i番目の規則を使用しない
    	#              >=0 : ωの値
    	#      return : 推論値
    	##############################################
    	
    	def Result(self, om) :
    
    		max = 0.0
    		min = 0.0
    		y   = 0.0
    		sw  = 0
    			# 積分範囲と積分幅の計算
    		for i1 in range(0, self.n_rule) :
    			if om[i1] >= 0.0 :
    				x1 = self.right[i1][0] - self.right[i1][1]
    				x2 = self.right[i1][0] + self.right[i1][1]
    				if sw == 0 :
    					min = x1
    					max = x2
    					sw  = 1
    				else :
    					if x1 < min :
    						min = x1
    					if x2 > max :
    						max = x2
    	
    		h = (max - min) / self.bun
    	
    		if h < 1.0e-15 :
    			print("***error  invalid data (h = 0) ***")
    			# 積分(重心の計算,台形則)
    		z1 = self.Height(min, om)
    		z2 = self.Height(max, om)
    		y1 = 0.5 * (min * z1 + max * z2)
    		y2 = 0.5 * (z1 + z2)
    		x1 = min
    	
    		for i1 in range(0, self.bun-1) :
    			x1 += h
    			z1  = self.Height(x1, om)
    			y1 += x1 * z1
    			y2 += z1
    	
    		y1 *= h
    		y2 *= h
    	
    		if abs(y2) > 1.0e-10 :
    			y = y1 / y2
    		else :
    			print("***error  invalid data (y2 = 0) ***")
    	
    		return y
    
    ############################
    # ファジイ推論
    #      coded by Y.Suganuma
    ############################
    
    if len(sys.argv) == 4 :
    				# オブジェクトの生成
    	fz = Fuzzy(sys.argv[1])
    				# 推論データの読み込み
    	in_f  = open(sys.argv[2], "r")
    	s     = in_f.readline().split()
    	n_val = int(s[1])
    	n_d   = int(s[3])
    	x     = np.empty(n_val, np.float)
    	xx    = np.empty((n_val, n_d), np.float)
    	for i1 in range(0, n_val) :
    		s = in_f.readline().split()
    		for i2 in range(0, n_d) :
    			xx[i1][i2] = float(s[i2+1])
    	in_f.close()
    				# 推論とその結果の出力
    	out = open(sys.argv[3], "w")
    	for i1 in range(0, n_d) :
    		for i2 in range(0, n_val) :
    			x[i2] = xx[i2][i1]
    			out.write(str(x[i2]) + " ")
    		y = fz.Inf(x)   # 推論
    		out.write(str(y) + "\n")
    	out.close()
    
    else :
    	print("***error   入力データファイル名を指定して下さい")
    
    """
    ------------------------規則ファイル--------------
    推論方法 0 規則の数 3 変数の数 1 積分の分割数 100
    規則1
     変数1 1 中心と幅 1.0 1.0
     右辺(中心と幅) 1.0 15.0
    規則2
     変数1 1 中心と幅 2.0 1.0
     右辺(中心と幅) 11.0 15.0
    規則3
     変数1 1 中心と幅 3.0 1.0
     右辺(中心と幅) 21.0 15.0
    
    ------------------------推論ファイル--------------
    変数の数 1 データ数 21
    変数1 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0
    """
    			

  7. C#

    /****************************/
    /* ファジイ推論             */
    /*      coded by Y.Suganuma */
    /****************************/
    using System;
    using System.IO;
    
    class Program
    {
    	/****************/
    	/* main program */
    	/****************/
    	static void Main(String[] args)
    	{
    					// エラー
    		if (args.Length != 3) {
    			Console.WriteLine("***error   入力データファイル名を指定して下さい");
    			Environment.Exit(1);
    		}
    
    		else {
    					// オブジェクトの生成
    			Fuzzy fz = new Fuzzy (args[0]);
    					// 推論データの読み込み
    			char[] charSep = new char[] {' '};
    			String[] lines = File.ReadAllLines(args[1]);
    			String[] str   = lines[0].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    			int n_val      = int.Parse(str[1]);
    			int n_d        = int.Parse(str[3]);
    			double[] x     = new double [n_val];
    			double[][] xx  = new double [n_val][];
    			for (int i1 = 0; i1 < n_val; i1++) {
    				xx[i1] = new double [n_d];
    				str    = lines[i1+1].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    				for (int i2 = 0; i2 < n_d; i2++)
    					xx[i1][i2] = double.Parse(str[i2+1]);
    			}
    					// 推論とその結果の出力
    			StreamWriter OUT = new StreamWriter(args[2]); 
    			for (int i1 = 0; i1 < n_d; i1++) {
    				for (int i2 = 0; i2 < n_val; i2++) {
    					x[i2] = xx[i2][i1];
    					OUT.Write(x[i2] + " ");
    				}
    				double y = fz.Inf(x);   // 推論
    				OUT.WriteLine(y);
    			}
    			OUT.Close();
    		}
    	}
    }
    
    class Fuzzy {
    
    	double[][][] left;   // [i][j][0] : 中心
                             //       [1] : 幅
    	double[][] right;   // [i][0] : 中心
                            //    [1] : 幅
    	double[] omega;   // ωの値
    	int bun;   // 積分の分割数
    	int method;   // 推論方法
                      //    =0 : and,or
                      //    =1 : *,or
                      //    =2 : *,+
    	int n_rule;   // 規則の数
    	int n_val;   // 変数の数
    	int[][] rule;   // [i][j] =0 : i番目の規則はj番目の変数を使用しない
                        //        =1 : i番目の規則はj番目の変数を使用する
    
    	/************************************/
    	/* コンストラクタ                   */
    	/*      name : 入力データファイル名 */
    	/************************************/
    	public Fuzzy (String name)
    	{
    		char[] charSep = new char[] {' '};
    		String[] lines = File.ReadAllLines(name);
    				//
    				// 基本データの入力
    				//
    		String[] str = lines[0].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    		method       = int.Parse(str[1]);
    		n_rule       = int.Parse(str[3]);
    		n_val        = int.Parse(str[5]);
    		bun          = int.Parse(str[7]);
    				//
    				// 領域の確保
    				//
    		omega = new double [n_rule];
    		right = new double [n_rule][];
    		rule  = new int [n_rule][];
    		left  = new double [n_rule][][];
    		for (int i1 = 0; i1 < n_rule; i1++) {
    			right[i1] = new double [2];
    			rule[i1]  = new int [n_val];
    			left[i1]  = new double [n_val][];
    			for (int i2 = 0; i2 < n_val; i2++)
    				left[i1][i2]  = new double [2];
    		}
    				//
    				// 規則データの入力
    				//
    		for (int i1 = 0; i1 < n_rule; i1++) {
    						// 左辺
    			for (int i2 = 0; i2 < n_val; i2++) {
    				str = lines[(n_val+2)*i1+i2+2].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    				rule[i1][i2] = int.Parse(str[1]);
    				if (rule[i1][i2] > 0) {
    					left[i1][i2][0] = double.Parse(str[3]);
    					left[i1][i2][1] = double.Parse(str[4]);
    				}
    			}
    						// 右辺
    			str = lines[(n_val+2)*i1+n_val+2].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    			right[i1][0] = double.Parse(str[1]);
    			right[i1][1] = double.Parse(str[2]);
    		}
    	}
    
    	/*******************************************/
    	/* 交点の計算                              */
    	/*      x : x                              */
    	/*      c : 中心                           */
    	/*      h : 幅                             */
    	/*      r : <0 : 左辺のメンバーシップ関数  */
    	/*          >=0 : 右辺(ω)                 */
    	/*      return : 交点                      */
    	/*******************************************/
    	double Cross(double x, double c, double h, double r)
    	{
    		double x1, x2, y1, y2;
    
    		if (x < c) {
    			x1 = c - h;
    			x2 = c;
    			y1 = 0.0;
    			y2 = (r < 0.0 || (r >= 0.0 && method == 0)) ? 1.0 : r;
    		}
    		else {
    			x1 = c;
    			x2 = c + h;
    			y1 = (r < 0.0 || (r >= 0.0 && method == 0)) ? 1.0 : r;
    			y2 = 0.0;
    		}
    
    		double y = y1 + (y2 - y1) * (x - x1) / (x2 - x1);
    
    		if (y < 0.0)
    			y = 0.0;
    		else {
    			if (r >= 0.0 && method == 0 && y > r)
    				y = r;
    		}
    
    		return y;
    	}
    
    	/**********************************************/
    	/* 右辺の計算                                 */
    	/*      x : 値                                */
    	/*      om[i] : <0 : i番目の規則を使用しない */
    	/*              >=0 : ωの値                  */
    	/*      return : xにおける右辺の値           */
    	/**********************************************/
    	double Height(double x, double [] om)
    	{
    		double y = 0.0;
    		int sw = 0;
    
    		for (int i1 = 0; i1 < n_rule; i1++) {
    
    			if (om[i1] >= 0.0) {
    
    				double y1 = Cross(x, right[i1][0], right[i1][1], om[i1]);
    
    				if (sw == 0) {
    					y  = y1;
    					sw = 1;
    				}
    
    				else {
    					if (method < 2) {
    						if (y1 > y)
    							y = y1;
    					}
    					else
    						y += y1;
    				}
    			}
    		}
    
    		return y;
    	}
    
    	/**************************/
    	/* 推論の実行             */
    	/*      x[i] : 各変数の値 */
    	/*      return : 推論値   */
    	/**************************/
    	public double Inf(double[] x)
    	{
    				//
    				// ωの計算
    				//
    		for (int i1 = 0; i1 < n_rule; i1++) {
    
    			omega[i1] = -1.0;
    
    			for (int i2 = 0; i2 < n_val; i2++) {
    
    				if (rule[i1][i2] > 0) {
    
    					double x1 = 0.0;
    					if (x[i2] > left[i1][i2][0]-left[i1][i2][1] &&
                            x[i2] < left[i1][i2][0]+left[i1][i2][1])
    						x1 = Cross(x[i2], left[i1][i2][0], left[i1][i2][1], -1.0);
    					else
    						x1 = 0.0;
    
    					if (omega[i1] < 0.0)
    						omega[i1] = x1;
    					else {
    						if (method == 0) {
    							if (x1 < omega[i1])
    								omega[i1] = x1;
    						}
    						else
    							omega[i1] *= x1;
    					}
    				}
    			}
    		}
    				//
    				// 右辺の計算
    				//
    		double y = Result(omega);
    
    		return y;
    	}
    
    	/**********************************************/
    	/* 右辺による推論                             */
    	/*      om[i] : <0 : i番目の規則を使用しない */
    	/*              >=0 : ωの値                  */
    	/*      return : 推論値                       */
    	/**********************************************/
    	double Result(double [] om)
    	{
    				//
    				// 積分範囲と積分幅の計算
    				//
    		double max = 0.0, min = 0.0, x1, x2, y = 0.0, y1, y2, z1, z2;
    		int sw = 0;
    
    		for (int i1 = 0; i1 < n_rule; i1++) {
    			if (om[i1] >= 0.0) {
    				x1 = right[i1][0] - right[i1][1];
    				x2 = right[i1][0] + right[i1][1];
    				if (sw == 0) {
    					min = x1;
    					max = x2;
    					sw  = 1;
    				}
    				else {
    					if (x1 < min)
    						min = x1;
    					if (x2 > max)
    						max = x2;
    				}
    			}
    		}
    
    		double h = (max - min) / bun;
    
    		if (h < 1.0e-15) {
    			Console.WriteLine("***error  invalid data (h = 0) ***");
    			Environment.Exit(1);
    		}
    				//
    				// 積分(重心の計算,台形則)
    				//
    		z1 = Height(min, om);
    		z2 = Height(max, om);
    		y1 = 0.5 * (min * z1 + max * z2);
    		y2 = 0.5 * (z1 + z2);
    		x1 = min;
    
    		for (int i1 = 0; i1 < bun-1; i1++) {
    			x1 += h;
    			z1  = Height(x1, om);
    			y1 += x1 * z1;
    			y2 += z1;
    		}
    
    		y1 *= h;
    		y2 *= h;
    
    		if (Math.Abs(y2) > 1.0e-10)
    			y = y1 / y2;
    		else {
    			Console.WriteLine("***error  invalid data (y2 = 0) ***");
    			Environment.Exit(1);
    		}
    
    		return y;
    	}
    }
    
    /*
    ------------------------規則ファイル--------------
    推論方法 0 規則の数 3 変数の数 1 積分の分割数 100
    規則1
     変数1 1 中心と幅 1.0 1.0
     右辺(中心と幅) 1.0 15.0
    規則2
     変数1 1 中心と幅 2.0 1.0
     右辺(中心と幅) 11.0 15.0
    規則3
     変数1 1 中心と幅 3.0 1.0
     右辺(中心と幅) 21.0 15.0
    
    ------------------------推論ファイル--------------
    変数の数 1 データ数 21
    変数1 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0
    */
    			

  8. VB

    '**************************'
    ' ファジイ推論             '
    '      coded by Y.Suganuma '
    '**************************'
    Imports System.IO
    Imports System.Text.RegularExpressions
    
    Module Test
    
    	Sub Main(args() As String)
    
    					' エラー
    		If args.Length <> 3
    			Console.WriteLine("***error   入力データファイル名を指定して下さい")
    			Environment.Exit(1)
    
    		Else
    					' オブジェクトの生成
    			Dim fz As Fuzzy = new Fuzzy (args(0))
    					' 推論データの読み込み
    			Dim inp As StreamReader = New StreamReader(args(1))
    			Dim MS As Regex         = New Regex("\s+") 
    			Dim str() As String     = MS.Split(inp.ReadLine().Trim())
    			Dim n_val As Integer    = Integer.Parse(str(1))
    			Dim n_d As Integer      = Integer.Parse(str(3))
    			Dim x(n_val) As Double
    			Dim xx(n_val,n_d) As Double
    			For i1 As Integer = 0 To n_val-1
    				str = MS.Split(inp.ReadLine().Trim())
    				For i2 As Integer = 0 To n_d-1
    					xx(i1,i2) = Double.Parse(str(i2+1))
    				Next
    			Next
    			inp.Close()
    					' 推論とその結果の出力
    			Dim OUT As StreamWriter = new StreamWriter(args(2)) 
    			For i1 As Integer = 0 To n_d-1
    				For i2 As Integer = 0 To n_val-1
    					x(i2) = xx(i2,i1)
    					OUT.Write(x(i2) & " ")
    				Next
    				Dim y As Double = fz.Inf(x)   ' 推論
    				OUT.WriteLine(y)
    			Next
    			OUT.Close()
    		End If
    
    	End Sub
    
    	Class Fuzzy
    	
    		Private left(,,) As Double   ' (i,j,0) : 中心
    	                                 ' (i,j,1) : 幅
    		Private right(,) As Double   ' (i,0) : 中心
    	                                 ' (i,1) : 幅
    		Private omega() As Double   ' ωの値
    		Private bun As Integer   ' 積分の分割数
    		Private method As Integer   ' 推論方法
    	                                '    =0 : and,or
    	                                '    =1 : *,or
    	                                '    =2 : *,+
    		Private n_rule As Integer   ' 規則の数
    		Private n_val As Integer   ' 変数の数
    		Private rule(,) As Integer   ' (i,j) =0 : i番目の規則はj番目の変数を使用しない
    	                                 '       =1 : i番目の規則はj番目の変数を使用する
    	
    		'**********************************'
    		' コンストラクタ                   '
    		'      name : 入力データファイル名 '
    		'**********************************'
    		Public Sub New(name As String)
    
    					'
    					' 基本データの入力
    					'
    			Dim inp As StreamReader = New StreamReader(name)
    			Dim MS As Regex         = New Regex("\s+") 
    			Dim str() As String     = MS.Split(inp.ReadLine().Trim())
    			method                  = Integer.Parse(str(1))
    			n_rule                  = Integer.Parse(str(3))
    			n_val                   = Integer.Parse(str(5))
    			bun                     = Integer.Parse(str(7))
    					'
    					' 領域の確保
    					'
    			ReDim omega(n_rule)
    			ReDim right(n_rule,2)
    			ReDim rule(n_rule,n_val)
    			ReDim left(n_rule,n_val,2)
    					'
    					' 規則データの入力
    					'
    			For i1 As Integer = 0 To n_rule-1
    				inp.ReadLine()
    							' 左辺
    				For i2 As Integer = 0 To n_val-1
    					str = MS.Split(inp.ReadLine().Trim())
    					rule(i1,i2) = Integer.Parse(str(1))
    					If rule(i1,i2) > 0
    						left(i1,i2,0) = Double.Parse(str(3))
    						left(i1,i2,1) = Double.Parse(str(4))
    					End If
    				Next
    							' 右辺
    				str         = MS.Split(inp.ReadLine().Trim())
    				right(i1,0) = Double.Parse(str(1))
    				right(i1,1) = Double.Parse(str(2))
    			Next
    			inp.Close()
    
    		End Sub
    	
    		'*****************************************'
    		' 交点の計算                              '
    		'      x : x                              '
    		'      c : 中心                           '
    		'      h : 幅                             '
    		'      r : <0 : 左辺のメンバーシップ関数  '
    		'          >=0 : 右辺(ω)                 '
    		'      return : 交点                      '
    		'*****************************************'
    		Function Cross(x As Double, c As Double, h As Double, r As Double)
    
    			Dim x1 As Double
    			Dim x2 As Double
    			Dim y1 As Double
    			Dim y2 As Double
    	
    			If x < c
    				x1 = c - h
    				x2 = c
    				y1 = 0.0
    				If r < 0.0 or (r >= 0.0 and method = 0)
    					y2 = 1.0
    				Else
    					y2 = r
    				End If
    			Else
    				x1 = c
    				x2 = c + h
    				if r < 0.0 or (r >= 0.0 and method = 0)
    					y1 = 1.0
    				Else
    					y1 = r
    				End If
    				y2 = 0.0
    			End If
    	
    			Dim y As Double = y1 + (y2 - y1) * (x - x1) / (x2 - x1)
    	
    			If y < 0.0
    				y = 0.0
    			Else
    				If r >= 0.0 and method = 0 and y > r
    					y = r
    				End If
    			End If
    	
    			Return y
    
    		End Function
    	
    		'********************************************'
    		' 右辺の計算                                 '
    		'      x : 値                                '
    		'      om(i) : <0 : i番目の規則を使用しない '
    		'              >=0 : ωの値                  '
    		'      return : xにおける右辺の値           '
    		'********************************************'
    		Function Height(x As Double, om() As Double)
    
    			Dim y As Double   = 0.0
    			Dim sw As Integer = 0
    	
    			For i1 As Integer = 0 To n_rule-1
    	
    				If om(i1) >= 0.0
    	
    					Dim y1 As Double = Cross(x, right(i1,0), right(i1,1), om(i1))
    	
    					If sw = 0
    						y  = y1
    						sw = 1
    	
    					Else
    						If method < 2
    							If y1 > y
    								y = y1
    							End If
    						Else
    							y += y1
    						End If
    					End If
    				End If
    			Next
    	
    			Return y
    
    		End Function
    	
    		'************************'
    		' 推論の実行             '
    		'      x(i) : 各変数の値 '
    		'      return : 推論値   '
    		'************************'
    		Function Inf(x() As Double)
    					'
    					' ωの計算
    					'
    			For i1 As Integer = 0 To n_rule-1
    	
    				omega(i1) = -1.0
    	
    				For i2 As Integer = 0 To n_val-1
    	
    					If rule(i1,i2) > 0
    	
    						Dim x1 As Double = 0.0
    						If x(i2) > left(i1,i2,0)-left(i1,i2,1) and x(i2) < left(i1,i2,0)+left(i1,i2,1)
    							x1 = Cross(x(i2), left(i1,i2,0), left(i1,i2,1), -1.0)
    						Else
    							x1 = 0.0
    						End If
    	
    						If omega(i1) < 0.0
    							omega(i1) = x1
    						Else
    							If method = 0
    								If x1 < omega(i1)
    									omega(i1) = x1
    								End If
    							Else
    								omega(i1) *= x1
    							End If
    						End If
    					End If
    				Next
    			Next
    					'
    					' 右辺の計算
    					'
    			Dim y As Double = Result(omega)
    	
    			Return y
    
    		End Function
    	
    		'********************************************'
    		' 右辺による推論                             '
    		'      om(i) : <0 : i番目の規則を使用しない '
    		'              >=0 : ωの値                  '
    		'      return : 推論値                       '
    		'********************************************'
    		Function Result(om() As Double)
    					'
    					' 積分範囲と積分幅の計算
    					'
    			Dim max As Double = 0.0
    			Dim min As Double = 0.0
    			Dim x1 As Double
    			Dim x2 As Double
    			Dim y As Double = 0.0
    			Dim y1 As Double
    			Dim y2 As Double
    			Dim z1 As Double
    			Dim z2 As Double
    			Dim sw As Integer = 0
    	
    			For i1 As Integer = 0 To n_rule-1
    				If om(i1) >= 0.0
    					x1 = right(i1,0) - right(i1,1)
    					x2 = right(i1,0) + right(i1,1)
    					If sw = 0
    						min = x1
    						max = x2
    						sw  = 1
    					Else
    						If x1 < min
    							min = x1
    						End If
    						If x2 > max
    							max = x2
    						End If
    					End If
    				End If
    			Next
    	
    			Dim h As Double = (max - min) / bun
    	
    			If h < 1.0e-15
    				Console.WriteLine("***error  invalid data (h = 0) ***")
    				Environment.Exit(1)
    			End If
    					'
    					' 積分(重心の計算,台形則)
    					'
    			z1 = Height(min, om)
    			z2 = Height(max, om)
    			y1 = 0.5 * (min * z1 + max * z2)
    			y2 = 0.5 * (z1 + z2)
    			x1 = min
    	
    			For i1 As Integer = 0 To bun-2
    				x1 += h
    				z1  = Height(x1, om)
    				y1 += x1 * z1
    				y2 += z1
    			Next
    	
    			y1 *= h
    			y2 *= h
    	
    			If Math.Abs(y2) > 1.0e-10
    				y = y1 / y2
    			Else
    				Console.WriteLine("***error  invalid data (y2 = 0) ***")
    				Environment.Exit(1)
    			End If
    	
    			Return y
    
    		End Function
    
    	End Class
    
    End Module
    
    /*
    ------------------------規則ファイル--------------
    推論方法 0 規則の数 3 変数の数 1 積分の分割数 100
    規則1
     変数1 1 中心と幅 1.0 1.0
     右辺(中心と幅) 1.0 15.0
    規則2
     変数1 1 中心と幅 2.0 1.0
     右辺(中心と幅) 11.0 15.0
    規則3
     変数1 1 中心と幅 3.0 1.0
     右辺(中心と幅) 21.0 15.0
    
    ------------------------推論ファイル--------------
    変数の数 1 データ数 21
    変数1 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0
    */
    			

情報学部 菅沼ホーム 目次 索引