解析系エンジニアのブログ

数値解析の備忘録がメインですが、オープンソースの配布なども行っています。

PHPでフーリエ級数展開

フーリエ級数展開PHPで実装してみました。

一般の周期関数に対するフーリエ級数展開です。

<?php
	
class FourierSeries{
	////////////////
	//  $n:分割数
	//  $L: 周期
	////////////////
	function __construct($n,$L){
		$this->n=$n;
		$this->L=$L/2;

		//フーリエ係数を計算
		for($i=0;$i<=$n;$i++){
			$this->a[$i]=$this->coefficientA($i);
			$this->b[$i]=$this->coefficientB($i);
		}
	}

	//$funcの$fromから$toまで積分.$nは分割数
	function integration($n,$from,$to,$func,$arg){
		$dx=($to-$from)/$n;
		$sum=0;
		for($i=0;$i<$n;$i++){
			$x=$from+$i*$dx;     
			$fx=$this->$func($x,$arg);
			$sum+=$fx*$dx;
		}
		return $sum;
	}
		
	function fA($x,$n){
		return $this->f($x)*cos($n*$x*M_PI/$this->L);
	}
	function fB($x,$n){
		return $this->f($x)*sin($n*$x*M_PI/$this->L);
	}

	//フーリエ係数a
	function coefficientA($n){
		return 1/$this->L*$this->integration(1000,-$this->L,$this->L,fA,$n);
	}
	//フーリエ係数b
	function coefficientB($n){
		return 1/$this->L*$this->integration(1000,-$this->L,$this->L,fB,$n);
	}

	//フーリエ級数
	public function series($x){
		$sum=0;
		for($n=1;$n<=$this->n;$n++){
			$sum+=$this->a[$n]*cos($n*$x*M_PI/$this->L)+$this->b[$n]*sin($n*$x*M_PI/$this->L);
		}
		return $this->a[0]/2+$sum;
	}
}
?>

使い方

<?php
class TestCls extends FourierSeries{
        //周期関数
        function f($x){        
		return sin($x/2); //周期4π
	}
}
$N=100;
$from=0;
$to=4*M_PI;
	
$obj=new TestCls(10,4*M_PI);
for($x=$from;$x<$to;$x+=($to-$from)/$N){
	echo $obj->series($x)."\n";		
}
?>