# ガウスの消去法 Gaussian Elimination # 引数 方程式 (\@Equations) # 戻り値 ガウスの消去法 (@GaussianElimination) sub GAUSSIANELIMINATION{ my ($Equations) = @_; my @SortEquations = @$Equations; my @TempEquations = (); my @GaussianElimination = (); my $Column = $#$Equations; my $Row = $#{$$Equations[0]}; my $RowNumber = 0; # 配列数の確認 for(my $i = 1; $i <= $Column; $i++){ if($Row != $#{$$Equations[$i]}){ return 0; } } if($Column != ($Row - 1)){ return 0; } # 上三角行列 前進消去 while($Column >= 0){ # 降順ソート @SortEquations = sort {$b->[$RowNumber] <=> $a->[$RowNumber]} @SortEquations; # 行列の一番上 $SortEquations[0]をコピー $TempEquations[$RowNumber] = $SortEquations[0]; last if($Column == 0); # $jの$RowNumber番目の要素を0にする for(my $j = 1; $j <= $Column; $j++){ last if($SortEquations[$j][$RowNumber] == 0); my $Price0 = $SortEquations[0][$RowNumber]; my $PriceJ = $SortEquations[$j][$RowNumber]; for(my $k = $RowNumber; $k <= $Row; $k++){ my $Diff = ($SortEquations[$j][$k] * $Price0) - ($SortEquations[0][$k] * $PriceJ); $SortEquations[$j][$k] = $Diff; } } # 行列の一番上 $SortEquations[0]を削除 my @temp = @SortEquations; @SortEquations = (); for(my $j = 1; $j < @temp; $j++){ $SortEquations[$j - 1] = $temp[$j]; } # 行列の縦方向の要素数 $Column = $#SortEquations; $RowNumber++; } # 後退代入 $Column = $#$Equations; $Row = $#{$$Equations[0]}; $GaussianElimination[$Row - 1] = $TempEquations[$Column][$Row] / $TempEquations[$Column][$Row - 1]; for(my $i = $Column - 1; $i >= 0; $i--){ my $tmp = $TempEquations[$i][$Row]; for(my $j = $Row - 1; $j > $i; $j--){ $tmp = $tmp - ($TempEquations[$i][$j] * $GaussianElimination[$j]); } # ガウスの消去法 Gaussian Elimination $GaussianElimination[$i] = $tmp / $TempEquations[$i][$i]; } return @GaussianElimination; }