Echo (3 + 5)
Echo (3 - 5)
Echo (3 * 5)
Echo ([Math]::Pow(3, 5))
Echo (5 / 3)
Echo ([Math]::Floor(5 / 3))
Echo (5 % 3)

Echo (5 % 3)

Write-Output (3 * 5)
Write-Host   (3 * 5)

Write-Host ([string]::format("{0,3:D}`n", 3 * 5)) -nonewline
Write-Host ([string]::format("{0,23:F20}", 5 / 3))
$i = 3 * 5

Write-Host   '3 * 5 = ' $i
Write-Host   '3 * 5 = ', $i
Write-Host   "3 * 5 = $i"

Write-Output "3 * 5 = $i"
Echo         "3 * 5 = $i"
foreach ($i in 1..9)
{
    Write-Host "$i, " -nonewline
}
foreach ($i in 1..9)
{
    if ($i % 3 -eq 0)
    {
        Write-Host "$i, " -nonewline
    }
}
$sum = 0
foreach ($i in 1..99)
{
    if ($i % 3 -eq 0)
    {
        $sum += $i
    }
}
Write-Host $sum

$sum = 0
foreach ($i in 1..99)
{
    $sum += if ($i % 3 -eq 0) {$i} else {0}
}
Write-Host $sum
1..9
1..9 | where { $_ % 3 -eq 0}
$sum = 0
1..99 | where {$_ % 3 -eq 0} | foreach {$sum += $_}
$sum
# 初項:a, 公差:a で, 上限:lim の数列の総和を返す関数
function sn($a, $lim)
{
    $n = [math]::floor($lim / $a) # 項数:n  =  上限:lim / 公差:a
    $l = $n * $a                  # 末項:l  =  項数:n   * 公差:a
    ($a + $l) * $n / 2            # 総和:sn = (初項:a   + 末項:l) * 項数:n / 2
}

# 3 の倍数の合計
Write-Host (sn 3 999)
# 10000 までの 自然数の和
# 項目数 n = 10000
$n = 10000
Write-Host($n * ($n + 1) / 2)
# 10000 までの 偶数の和
# 項目数 n = 5000
$n = 10000 / 2
Write-Host($n * ($n + 1))
# 10000 までの 奇数の和
# 項目数 n = 5000
$n = 10000 / 2
Write-Host([math]::pow($n, 2))
# 1000 までの 自然数の2乗の和
$n = 1000
Write-Host($n * ($n + 1) * (2 * $n + 1) / 6)
# 100 までの 自然数の3乗の和
$n = 100
Write-Host([math]::pow($n, 2) * [math]::pow(($n + 1), 2) / 4)
# 初項 2, 公比 3, 項数 10 の等比数列の和
$n = 10;
$a = 2;
$r = 3;
Write-Host(($a * ([math]::pow($r,  $n) - 1)) / ($r - 1))
$a = 5  # 初項 5
$d = 3  # 公差 3
$n = 10 # 項数 10
$p = 1  # 積

foreach ($i in 1..$n)
{
    $m = $a + ($d * ($i - 1))
    $p *= $m;
}
Write-Host $p
# 初項 5, 公差 3, 項数 10 の数列の積を表示する
Write-Host (product 5 3 10)

function product($m, $d, $n)
{
    if ($n -eq 0)
    {
        1
    }
    else
    {
        $m * (product ($m + $d) $d ($n - 1))
    }
}
# 階乗を求める関数
function Fact($n)
{
    if ($n -le 1)
    {
        1
    }
    else
    {
        $n * (Fact ($n - 1))
    }
}

# 10の階乗
Write-Host (Fact(10))
Write-Host (10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1)
# 下降階乗冪
function FallingFact($x, $n)
{
    if ($n -le 1)
    {
        $x
    }
    else
    {
        $x * (FallingFact ($x - 1) ($n - 1))
    }
}

# 10 から 6 までの 総乗
Write-Host (FallingFact 10 5)
Write-Host (10 * 9 * 8 * 7 * 6)
# 上昇階乗冪
function RisingFact($x, $n)
{
    if ($n -le 1)
    {
        $x
    }
    else
    {
        $x * (RisingFact ($x + 1) ($n - 1))
    }
}

# 10 から 14 までの 総乗
Write-Host (RisingFact 10 5)
Write-Host (10 * 11 * 12 * 13 * 14)
# 階乗
function Fact($n)
{
    if ($n -le 1)
    {
        1
    }
    else
    {
        $n * (Fact ($n - 1))
    }
}

# 下降階乗冪
function FallingFact($x, $n)
{
    if ($n -le 1)
    {
        $x
    }
    else
    {
        $x * (FallingFact ($x - 1) ($n - 1))
    }
}

# 順列 (異なる 10 個のものから 5 個取ってできる順列の総数)
$n = 10
$r = 5
Write-Host ((Fact $n) / (Fact ($n - $r)))
Write-Host (FallingFact $n $r)
# 重複順列 (異なる 10 個のものから重複を許して 5 個取ってできる順列の総数)
$n = 10
$r = 5
Write-Host ([math]::pow($n, $r))
# 組合せ
function Comb($n, $r)
{
    if (($r -eq 0) -or ($r -eq $n))
    {
        1
    }
    elseif ($r -eq 1)
    {
        $n
    }
    else
    {
        (Comb ($n - 1) ($r - 1)) + (Comb ($n - 1) $r)
    }
}

# 組合せ (異なる 10 個のものから 5 個取ってできる組合せの総数)
$n = 10
$r = 5
Write-Host (Comb $n $r)
# 組合せ
function Comb($n, $r)
{
    if (($r -eq 0) -or ($r -eq $n))
    {
        1
    }
    elseif ($r -eq 1)
    {
        $n
    }
    else
    {
        (Comb ($n - 1) ($r - 1)) + (Comb ($n - 1) $r)
    }
}

# 重複組合せ (異なる 10 個のものから重複を許して 5 個とる組合せの総数)
$n = 10
$r = 5
Write-Host (Comb ($n + $r - 1) $r)
# 自作の正弦関数
function mySin($x, $n, $nega, $numerator, $denominator, $y)
{
    $m           = 2 * $n
    $denominator = $denominator * ($m + 1) * $m
    $numerator   = $numerator * $x * $x
    $a           = $numerator / $denominator
    # 十分な精度になったら処理を抜ける
    if ($a -le 0.00000000001)
    {
        $y
    }
    else
    {
        if (-not $nega) { $a = -$a}
        $y + (mySin $x  ($n + 1) (-not $nega) $numerator $denominator $a)
    }
}

foreach ($i in 0..24)
{
    $degree = $i * 15
    if ($degree % 30 -eq 0 -or $degree % 45 -eq 0)
    {
        $radian = $degree * [Math]::PI / 180.0
        # 自作の正弦関数
        $d1     = mySin $radian 1 $false $radian 1.0 $radian
        # 標準の正弦関数
        $d2     = [Math]::Sin($radian)
        # 標準関数との差異
        Write-Host ([string]::format("{0,3:D} : {1,13:F10} - {2,13:F10} = {3,13:F10}", $degree, $d1, $d2, $d1 - $d2))
    }
}
# 自作の余弦関数
function myCos($x, $n, $nega, $numerator, $denominator, $y)
{
    $m           = 2 * $n
    $denominator = $denominator * $m * ($m - 1)
    $numerator   = $numerator * $x * $x
    $a           = $numerator / $denominator
    # 十分な精度になったら処理を抜ける
    if ($a -le 0.00000000001)
    {
        $y
    }
    else
    {
        if (-not $nega) { $a = -$a}
        $y + (myCos $x  ($n + 1) (-not $nega) $numerator $denominator $a)
    }
}

foreach ($i in 0..24)
{
    $degree = $i * 15
    if ($degree % 30 -eq 0 -or $degree % 45 -eq 0)
    {
        $radian = $degree * [Math]::PI / 180.0
        # 自作の余弦関数
        $d1     = myCos $radian 1 $false 1.0 1.0 1.0
        # 標準の余弦関数
        $d2     = [Math]::Cos($radian)
        # 標準関数との差異
        Write-Host ([string]::format("{0,3:D} : {1,13:F10} - {2,13:F10} = {3,13:F10}", $degree, $d1, $d2, $d1 - $d2))
    }
}
# 自作の正接関数
function myTan($x, $x2, $n, $t)
{
    $t = $x2 / ($n - $t)
    $n -= 2

    if ($n -le 1)
    {
        $x / (1 - $t)
    }
    else
    {
        myTan $x $x2 $n $t
    }
}
foreach ($i in 0..12)
{
    if (($i * 15) % 180 -ne 0)
    {
        $degree = $i * 15 - 90
        $radian = $degree * [Math]::PI / 180.0
        $x2     = $radian * $radian
        # 自作の正接関数
        $d1     = myTan $radian $x2 15 0.0 # 15:必要な精度が得られる十分大きな奇数
        # 標準の正接関数
        $d2     = [Math]::Tan($radian)
        # 標準関数との差異
        Write-Host ([string]::format("{0,3:D} : {1,13:F10} - {2,13:F10} = {3,13:F10}", $degree, $d1, $d2, $d1 - $d2))
    }
}
# 自作の指数関数
function myExp($x, $n, $numerator, $denominator, $y)
{
    $denominator = $denominator * $n
    $numerator   = $numerator   * $x
    $a           = $numerator / $denominator
    # 十分な精度になったら処理を抜ける
    if ([Math]::Abs($a) -le 0.00000000001)
    {
        $y
    }
    else
    {
        $y + (myExp $x ($n + 1) $numerator $denominator $a)
    }
}

foreach ($i in 0..20)
{
    $x = ($i - 10) / 4.0
    # 標準の指数関数
    $d1 = [Math]::Exp($x)
    # 自作の指数関数
    $d2 = myExp $x 1 1.0 1.0 1.0
    # 標準関数との差異
    Write-Host ([string]::format("{0,5:F2} : {1,13:F10} - {2,13:F10} = {3,13:F10}", $x, $d1, $d2, $d1 - $d2))
}
# 自作の指数関数
function myExp($x, $x2, $n, $t)
{
    $t = $x2 / ($n + $t)
    $n -= 4

    if ($n -lt 6)
    {
        1 + ((2 * $x) / (2 - $x + $t))
    }
    else
    {
        myExp $x $x2 $n $t
    }
}

foreach ($i in 0..20)
{
    $x = ($i - 10) / 4.0
    # 標準の指数関数
    $d1 = [Math]::Exp($x)
    # 自作の指数関数
    $x2 = $x * $x
    $d2 = myExp $x $x2 30 0.0 # 30:必要な精度が得られるよう, 6から始めて4ずつ増加させる
    # 標準関数との差異
    Write-Host ([string]::format("{0,5:F2} : {1,13:F10} - {2,13:F10} = {3,13:F10}", $x, $d1, $d2, $d1 - $d2))
}
# 自作の対数関数
function myLog($x2, $numerator, $denominator, $y)
{
    $denominator = $denominator + 2
    $numerator   = $numerator   * $x2 * $x2
    $a           = $numerator / $denominator
    # 十分な精度になったら処理を抜ける
    if ([Math]::Abs($a) -le 0.00000000001)
    {
        $y
    }
    else
    {
        $y + (myLog $x2 $numerator $denominator $a)
    }
}

foreach ($i in 1..20)
{
    $x = $i / 5.0
    # 標準の対数関数
    $d1 = [Math]::Log($x)
    # 自作の対数関数
    $x2 = ($x - 1) / ($x + 1)
    $d2 = 2 * (myLog $x2 $x2 1.0 $x2)
    # 標準関数との差異
    Write-Host ([string]::format("{0,5:F2} : {1,13:F10} - {2,13:F10} = {3,13:F10}", $x, $d1, $d2, $d1 - $d2))
}
# 自作の対数関数
function myLog($x, $n, $t)
{
    $n2 = $n
    $x2 = $x
    if ($n -gt 3)
    {
        if ($n % 2 -eq 0)
        {
            $n2 = 2
        }
        $x2 = $x * [Math]::Floor($n / 2)
    }
    $t = $x2 / ($n2 + $t)

    if ($n -le 2)
    {
        $x / (1 + $t)
    }
    else
    {
        myLog $x ($n - 1) $t
    }
}

foreach ($i in 1..20)
{
    $x = $i / 5.0
    # 標準の対数関数
    $d1 = [Math]::Log($x)
    # 自作の対数関数
    $d2 = myLog ($x - 1) 27 0.0 # 27:必要な精度が得られる十分大きな奇数
    # 標準関数との差異
    Write-Host ([string]::format("{0,5:F2} : {1,13:F10} - {2,13:F10} = {3,13:F10}", $x, $d1, $d2, $d1 - $d2))
}
# 自作の双曲線正弦関数
function mySinh($x, $n, $numerator, $denominator, $y)
{
    $m           = 2 * $n
    $denominator = $denominator * ($m + 1) * $m
    $numerator   = $numerator   * $x * $x
    $a           = $numerator / $denominator
    # 十分な精度になったら処理を抜ける
    if ([Math]::Abs($a) -le 0.00000000001)
    {
        $y
    }
    else
    {
        $y + (mySinh $x ($n + 1) $numerator $denominator $a)
    }
}

foreach ($i in 0..20)
{
    $x = $i - 10
    # 自作の双曲線正弦関数
    $d1 = mySinh $x 1 $x 1.0 $x
    # 標準の双曲線正弦関数
    $d2 = [Math]::Sinh($x)
    # 標準関数との差異
    Write-Host ([string]::format("{0,3:D} : {1,17:F10} - {2,17:F10} = {3,13:F10}", $x, $d1, $d2, $d1 - $d2))
}
# 自作の双曲線余弦関数
function myCosh($x, $n, $numerator, $denominator, $y)
{
    $m           = 2 * $n
    $denominator = $denominator * $m * ($m - 1)
    $numerator   = $numerator   * $x * $x
    $a           = $numerator / $denominator
    # 十分な精度になったら処理を抜ける
    if ([Math]::Abs($a) -le 0.00000000001)
    {
        $y
    }
    else
    {
        $y + (myCosh $x ($n + 1) $numerator $denominator $a)
    }
}

foreach ($i in 0..20)
{
    $x = $i - 10
    # 自作の双曲線余弦関数
    $d1 = myCosh $x 1 1.0 1.0 1.0
    # 標準の双曲線余弦関数
    $d2 = [Math]::Cosh($x)
    # 標準関数との差異
    Write-Host ([string]::format("{0,3:D} : {1,17:F10} - {2,17:F10} = {3,13:F10}", $x, $d1, $d2, $d1 - $d2))
}
function f($x)
{
    4 / (1 + $x * $x)
}

$a = 0
$b = 1

# 台形則で積分
$n = 2;
foreach ($j in 1..10)
{
    $h = ($b - $a) / $n
    $s = 0
    $x = $a
    foreach ($i in 1..($n - 1))
    {
        $x += $h
        $s += (f $x)
    }
    $s = $h * (((f $a) + (f $b)) / 2 + $s)
    $n *= 2

    # 結果を π と比較
    Write-Host ([string]::format("{0,2:D} : {1,13:F10}, {2,13:F10}", $j, $s, $s - [Math]::PI))
}
function f($x)
{
    4 / (1 + $x * $x)
}

$a = 0
$b = 1

# 中点則で積分
$n = 2;
foreach ($j in 1..10)
{
    $h = ($b - $a) / $n
    $s = 0
    $x = $a + ($h / 2)
    foreach ($i in 1..$n)
    {
        $s += (f $x)
        $x += $h
    }
    $s *= $h
    $n *= 2

    # 結果を π と比較
    Write-Host ([string]::format("{0,2:D} : {1,13:F10}, {2,13:F10}", $j, $s, $s - [Math]::PI))
}
function f($x)
{
    4 / (1 + $x * $x)
}

$a = 0
$b = 1

# Simpson則で積分
$n = 2;
foreach ($j in 1..5)
{
    $h  = ($b - $a) / $n
    $s2 = 0
    $s4 = 0
    $x  = $a + $h
    foreach ($i in 1..($n / 2))
    {
        $s4 += (f $x)
        $x  += $h
        $s2 += (f $x)
        $x  += $h
    }
    $s2 = ($s2 - (f $b)) * 2 + (f $a) + (f $b)
    $s4 *= 4
    $s  = ($s2 + $s4) * $h / 3
    $n  *= 2

    # 結果を π と比較
    Write-Host ([string]::format("{0,2:D} : {1,13:F10}, {2,13:F10}", $j, $s, $s - [Math]::PI))
}
function f($x)
{
    4 / (1 + $x * $x)
}

$a = 0
$b = 1

$t = New-Object "double[,]" 7,7

# 台形則で積分
$n = 2;
foreach ($i in 1..6)
{
    $h = ($b - $a) / $n
    $s = 0
    $x = $a
    foreach ($j in 1..($n - 1))
    {
        $x += $h
        $s += (f $x)
    }
    # 結果を保存
    $t[$i,1] = $h * (((f $a) + (f $b)) / 2 + $s)
    $n *= 2
}

# Richardsonの補外法
$n = 4
foreach ($j in 2..6)
{
    foreach ($i in $j..6)
    {
        $t1 = $t[ $i     ,($j - 1)]
        $t2 = $t[($i - 1),($j - 1)]
        $t[$i,$j] = $t1 + ($t1 - $t2) / ($n - 1)
        if ($i -eq $j)
        {
            # 結果を π と比較
            $s = $t[$i,$j]
            Write-Host ([string]::format("{0,2:D} : {1,13:F10}, {2,13:F10}", $j, $s, ($s - [Math]::PI)))
        }
    }
    $n *= 4;
}
# データ点の数
set-variable -option constant -name N -value 7

# 元の関数
function f($x)
{
    $x - [math]::pow($x, 3) / (3 * 2) + [math]::pow($x, 5) / (5 * 4 * 3 * 2)
}

# Lagrange (ラグランジュ) 補間
function lagrange($d, $x, $y)
{
    $sum = 0
    foreach ($i in 0..($N - 1))
    {
        $prod = $y[$i]
        foreach ($j in 0..($N - 1))
        {
            if ($j -ne $i)
            {
                $prod *= ($d - $x[$j]) / ($x[$i] - $x[$j])
            }
        }
        $sum += $prod
    }
    $sum
}

$x = New-Object double[] $N
$y = New-Object double[] $N

# 1.5刻みで -4.5〜4.5 まで, 7点だけ値をセット
foreach ($i in 0..($N - 1))
{
    $d = $i * 1.5 - 4.5
    $x[$i] = $d
    $y[$i] = f($d)
}

# 0.5刻みで 与えられていない値を補間
foreach ($i in 0..18)
{
    $d  = $i * 0.5 - 4.5
    $d1 = f($d)
    $d2 = (lagrange $d $x $y)

    # 元の関数と比較
    Write-Host ([string]::format("{0,5:F2}`t{1,8:F5}`t{2,8:F5}`t{3,8:F5}", $d, $d1, $d2, ($d1 - $d2)))
}
# データ点の数
set-variable -option constant -name N -value 7

# 元の関数
function f($x)
{
    $x - [math]::pow($x, 3) / (3 * 2) + [math]::pow($x, 5) / (5 * 4 * 3 * 2)
}

# Neville (ネヴィル) 補間
function neville($d, $x, $y)
{
    $w = New-Object "double[,]" $N,$N
    foreach ($i in 0..($N - 1))
    {
        $w[0,$i] = $y[$i]
    }
    foreach ($j in 1..($N - 1))
    {
        foreach ($i in 0..($N - $j - 1))
        {
            $w[$j, $i] = $w[($j-1),($i+1)] + ($w[($j-1),($i+1)] - $w[($j-1),$i]) * ($d - $x[($i+$j)]) / ($x[($i+$j)] - $x[$i])
        }
    }
    $w[($N-1),0]
}

$x = New-Object double[] $N
$y = New-Object double[] $N

# 1.5刻みで -4.5〜4.5 まで, 7点だけ値をセット
foreach ($i in 0..($N - 1))
{
    $d = $i * 1.5 - 4.5
    $x[$i] = $d
    $y[$i] = f($d)
}

# 0.5刻みで 与えられていない値を補間
foreach ($i in 0..18)
{
    $d  = $i * 0.5 - 4.5
    $d1 = f($d)
    $d2 = (neville $d $x $y)

    # 元の関数と比較
    Write-Host ([string]::format("{0,5:F2}`t{1,8:F5}`t{2,8:F5}`t{3,8:F5}", $d, $d1, $d2, ($d1 - $d2)))
}
# データ点の数
set-variable -option constant -name N -value 7

# 元の関数
function f($x)
{
    $x - [math]::pow($x, 3) / (3 * 2) + [math]::pow($x, 5) / (5 * 4 * 3 * 2)
}

# Newton (ニュートン) 補間
function newton($d, $x, $a)
{
    $sum = $a[0]
    foreach ($i in 1..($N - 1))
    {
        $prod = $a[$i]
        foreach ($j in 0..($i - 1))
        {
            $prod *= ($d - $x[$j])
        }
        $sum += $prod
    }
    $sum
}

$x = New-Object double[] $N
$y = New-Object double[] $N

# 1.5刻みで -4.5〜4.5 まで, 7点だけ値をセット
foreach ($i in 0..($N - 1))
{
    $d1 = $i * 1.5 - 4.5
    $x[$i] = $d1
    $y[$i] = f($d1)
}

# 差分商の表を作る
$d = New-Object "double[,]" $N,$N
foreach ($j in 0..($N - 1))
{
    $d[0,$j] = $y[$j]
}
foreach ($i in 1..($N - 1))
{
    foreach ($j in 0..($N - $i - 1))
    {
        $d[$i,$j] = ($d[($i-1),($j+1)] - $d[($i-1),$j]) / ($x[($j+$i)] - $x[$j])
    }
}
# n階差分商
$a = New-Object double[] $N
foreach ($j in 0..($N - 1))
{
    $a[$j] = $d[$j,0]
}

# 0.5刻みで 与えられていない値を補間
foreach ($i in 0..18)
{
    $d1 = $i * 0.5 - 4.5
    $d2 = f($d1)
    $d3 = (newton $d1 $x $a)

    # 元の関数と比較
    Write-Host ([string]::format("{0,5:F2}`t{1,8:F5}`t{2,8:F5}`t{3,8:F5}", $d1, $d2, $d3, ($d2 - $d3)))
}
# データ点の数
set-variable -option constant -name N   -value  7
set-variable -option constant -name Nx2 -value 14

# 元の関数
function f($x)
{
    $x - [math]::pow($x, 3) / (3 * 2) + [math]::pow($x, 5) / (5 * 4 * 3 * 2)
}
# 導関数
function fd($x)
{
    1 - [math]::pow($x, 2) / 2 + [math]::pow($x, 4) / (4 * 3 * 2)
}

# Hermite (エルミート) 補間
function hermite($d, $z, $a)
{
    $sum = $a[0]
    foreach ($i in 1..($Nx2 - 1))
    {
        $prod = $a[$i]
        foreach ($j in 0..($i - 1))
        {
            $prod *= ($d - $z[$j])
        }
        $sum += $prod
    }
    $sum
}

$x  = New-Object double[] $N
$y  = New-Object double[] $N
$yd = New-Object double[] $N

# 1.5刻みで -4.5〜4.5 まで, 7点だけ値をセット
foreach ($i in 0..($N - 1))
{
    $d1      = $i * 1.5 - 4.5
    $x[$i]   = $d1
    $y[$i]   = f($d1)
    $yd[$i]  = fd($d1)
}

# 差分商の表を作る
$z = New-Object  double[]   $Nx2
$d = New-Object "double[,]" $Nx2,$Nx2
foreach ($i in 0..($Nx2 - 1))
{
    $j       = [math]::floor($i / 2)
    $z[$i]   = $x[$j]
    $d[0,$i] = $y[$j]
}
foreach ($i in 1..($Nx2 - 1))
{
    foreach ($j in 0..($Nx2 - $i - 1))
    {
        if ($i -eq 1 -and $j % 2 -eq 0)
        {
            $d[$i,$j] = $yd[[math]::floor($j / 2)]
        }
        else
        {
            $d[$i,$j] = ($d[($i-1),($j+1)] - $d[($i-1),$j]) / ($z[($j+$i)] - $z[$j])
        }
    }
}
# n階差分商
$a = New-Object double[] $Nx2
foreach ($j in 0..($Nx2 - 1))
{
    $a[$j] = $d[$j,0]
}

# 0.5刻みで 与えられていない値を補間
foreach ($i in 0..18)
{
    $d1 = $i * 0.5 - 4.5
    $d2 = f($d1)
    $d3 = (hermite $d1 $z $a)

    # 元の関数と比較
    Write-Host ([string]::format("{0,5:F2}`t{1,8:F5}`t{2,8:F5}`t{3,8:F5}", $d1, $d2, $d3, ($d2 - $d3)))
}
# データ点の数
set-variable -option constant -name N -value 7

# 元の関数
function f($x)
{
    $x - [math]::pow($x, 3) / (3 * 2) + [math]::pow($x, 5) / (5 * 4 * 3 * 2)
}

# Spline (スプライン) 補間
function spline($d, $x, $y, $z)
{
    # 補間関数値がどの区間にあるか
    $k = -1
    foreach ($i in 1..($N - 1))
    {
        if ($d -le $x[$i])
        {
            $k = $i - 1
            break
        }
    }
    if ($k -lt 0)
    {
        $k = $N - 1
    }

    $d1 = $x[($k+1)] - $d
    $d2 = $d         - $x[$k]
    $d3 = $x[($k+1)] - $x[$k]
    ($z[$k] * [math]::pow($d1,3) + $z[($k+1)] * [math]::pow($d2,3)) / (6.0 * $d3) +
    ($y[$k]     / $d3 - $z[$k]     * $d3 / 6.0) * $d1 +
    ($y[($k+1)] / $d3 - $z[($k+1)] * $d3 / 6.0) * $d2
}

$x = New-Object double[] $N
$y = New-Object double[] $N

# 1.5刻みで -4.5〜4.5 まで, 7点だけ値をセット
foreach ($i in 0..($N - 1))
{
    $d1 = $i * 1.5 - 4.5
    $x[$i] = $d1
    $y[$i] = f($d1)
}

# 3項方程式の係数の表を作る
$a = New-Object double[] $N
$b = New-Object double[] $N
$c = New-Object double[] $N
$d = New-Object double[] $N
foreach ($i in 1..($N - 2))
{
    $a[$i] =         $x[$i]     - $x[($i-1)]
    $b[$i] = 2.0 *  ($x[($i+1)] - $x[($i-1)])
    $c[$i] =         $x[($i+1)] - $x[$i]
    $d[$i] = 6.0 * (($y[($i+1)] - $y[$i]) / ($x[($i+1)] - $x[$i]) - ($y[$i] - $y[($i-1)]) / ($x[$i] - $x[($i-1)]))
}
# 3項方程式を解く (ト−マス法)
$g = New-Object double[] $N
$s = New-Object double[] $N
$g[1] = $b[1]
$s[1] = $d[1]
foreach ($i in 2..($N - 2))
{
    $g[$i] = $b[$i] - $a[$i] * $c[($i-1)] / $g[($i-1)]
    $s[$i] = $d[$i] - $a[$i] * $s[($i-1)] / $g[($i-1)]
}
$z = New-Object double[] $N
$z[0] = 0
$z[($N-1)] = 0
$z[($N-2)] = $s[($N-2)] / $g[($N-2)]
for ($i = $N - 3; $i -ge 1; $i--)
{
    $z[$i] = ($s[$i] - $c[$i] * $z[($i+1)]) / $g[$i]
}

# 0.5刻みで 与えられていない値を補間
foreach ($i in 0..18)
{
    $d1 = $i * 0.5 - 4.5
    $d2 = f($d1)
    $d3 = (spline $d1 $x $y $z)

    # 元の関数と比較
    Write-Host ([string]::format("{0,5:F2}`t{1,8:F5}`t{2,8:F5}`t{3,8:F5}", $d1, $d2, $d3, ($d2 - $d3)))
}
# 重力加速度
$g = -9.8
# 空気抵抗係数
$k = -0.01
# 時間間隔(秒)
$h = 0.01

# 角度
$degree = 45
$radian = $degree * [Math]::PI / 180.0
# 初速 250 km/h -> 秒速に変換
$v = [math]::floor(250 * 1000 / 3600)
# 水平方向の速度
$vx  = New-Object double[] 2
$vx[0] = $v * [Math]::Cos($radian)
# 鉛直方向の速度
$vy  = New-Object double[] 2
$vy[0] = $v * [Math]::Sin($radian)
# 経過秒数
$t = 0.0
# 位置
$x = 0.0
$y = 0.0

# 空気抵抗による水平方向の減速分
function fx($vx, $vy)
{
    return $global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vx
}
# 重力と空気抵抗による鉛直方向の減速分
function fy($vx, $vy)
{
    return $global:g + ($global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vy)
}

# Euler法
for ($i = 1; $y -ge 0.0; $i++)
{
    # 経過秒数
    $t = $i * $h

    # 位置
    $x += $h * $vx[0]
    $y += $h * $vy[0]

    Write-Host ([string]::format("{0,4:F2}`t{1,8:F5}`t{2,9:F5}`t{3,9:F5}`t{4,8:F5}", $t, $vx[0], $vy[0], $x, $y))

    # 速度
    $vx[1] = $vx[0] + $h * (fx $vx[0] $vy[0])
    $vy[1] = $vy[0] + $h * (fy $vx[0] $vy[0])
    $vx[0] = $vx[1]
    $vy[0] = $vy[1]
}
# 重力加速度
$g = -9.8
# 空気抵抗係数
$k = -0.01
# 時間間隔(秒)
$h = 0.01

# 角度
$degree = 45
$radian = $degree * [Math]::PI / 180.0
# 初速 250 km/h -> 秒速に変換
$v = [math]::floor(250 * 1000 / 3600)
# 水平方向の速度
$vx  = New-Object double[] 3
$vx[0] = $v * [Math]::Cos($radian)
# 鉛直方向の速度
$vy  = New-Object double[] 3
$vy[0] = $v * [Math]::Sin($radian)
# 経過秒数
$t = 0.0
# 位置
$x  = New-Object double[] 3
$y  = New-Object double[] 3
$x[0] = 0.0
$y[0] = 0.0

# 空気抵抗による水平方向の減速分
function fx($vx, $vy)
{
    return $global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vx
}
# 重力と空気抵抗による鉛直方向の減速分
function fy($vx, $vy)
{
    return $global:g + ($global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vy)
}

# Heun法
for ($i = 1; $y[0] -ge 0.0; $i++)
{
    # 経過秒数
    $t = $i * $h

    # 位置・速度
    $x[1]  =  $x[0] + $h *     $vx[0]
    $y[1]  =  $y[0] + $h *     $vy[0]
    $vx[1] = $vx[0] + $h * (fx $vx[0] $vy[0])
    $vy[1] = $vy[0] + $h * (fy $vx[0] $vy[0])

    $x[2]  =  $x[0] + $h * (    $vx[0]         +     $vx[1]        ) / 2
    $y[2]  =  $y[0] + $h * (    $vy[0]         +     $vy[1]        ) / 2
    $vx[2] = $vx[0] + $h * ((fx $vx[0] $vy[0]) + (fx $vx[1] $vy[1])) / 2
    $vy[2] = $vy[0] + $h * ((fy $vx[0] $vy[0]) + (fy $vx[1] $vy[1])) / 2

    $x[0]  =  $x[2]
    $y[0]  =  $y[2]
    $vx[0] = $vx[2]
    $vy[0] = $vy[2]

    Write-Host ([string]::format("{0,4:F2}`t{1,8:F5}`t{2,9:F5}`t{3,9:F5}`t{4,8:F5}", $t, $vx[0], $vy[0], $x[0], $y[0]))
}
# 重力加速度
$g = -9.8
# 空気抵抗係数
$k = -0.01
# 時間間隔(秒)
$h = 0.01

# 角度
$degree = 45
$radian = $degree * [Math]::PI / 180.0
# 初速 250 km/h -> 秒速に変換
$v = [math]::floor(250 * 1000 / 3600)
# 水平方向の速度
$vx  = New-Object double[] 2
$vx[0] = $v * [Math]::Cos($radian)
# 鉛直方向の速度
$vy  = New-Object double[] 2
$vy[0] = $v * [Math]::Sin($radian)
# 経過秒数
$t = 0.0
# 位置
$x  = New-Object double[] 2
$y  = New-Object double[] 2
$x[0] = 0.0
$y[0] = 0.0

# 空気抵抗による水平方向の減速分
function fx($vx, $vy)
{
    return $global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vx
}
# 重力と空気抵抗による鉛直方向の減速分
function fy($vx, $vy)
{
    return $global:g + ($global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vy)
}

# 中点法
for ($i = 1; $y[0] -ge 0.0; $i++)
{
    # 経過秒数
    $t = $i * $h

    # 位置・速度
    $vx[1] = $h * (fx $vx[0] $vy[0])
    $vy[1] = $h * (fy $vx[0] $vy[0])

    $wx    = $vx[0] + $vx[1] / 2
    $wy    = $vy[0] + $vy[1] / 2
    $vx[0] = $vx[0] + $h * (fx $wx $wy)
    $vy[0] = $vy[0] + $h * (fy $wx $wy)
    $x[0]  =  $x[0] + $h *     $wx
    $y[0]  =  $y[0] + $h *     $wy

    Write-Host ([string]::format("{0,4:F2}`t{1,8:F5}`t{2,9:F5}`t{3,9:F5}`t{4,8:F5}", $t, $vx[0], $vy[0], $x[0], $y[0]))
}
# 重力加速度
$g = -9.8
# 空気抵抗係数
$k = -0.01
# 時間間隔(秒)
$h = 0.01

# 角度
$degree = 45
$radian = $degree * [Math]::PI / 180.0
# 初速 250 km/h -> 秒速に変換
$v = [math]::floor(250 * 1000 / 3600)
# 水平方向の速度
$vx  = New-Object double[] 5
$vx[0] = $v * [Math]::Cos($radian)
# 鉛直方向の速度
$vy  = New-Object double[] 5
$vy[0] = $v * [Math]::Sin($radian)
# 経過秒数
$t = 0.0
# 位置
$x  = New-Object double[] 5
$y  = New-Object double[] 5
$x[0] = 0.0
$y[0] = 0.0

# 空気抵抗による水平方向の減速分
function fx($vx, $vy)
{
    return $global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vx
}
# 重力と空気抵抗による鉛直方向の減速分
function fy($vx, $vy)
{
    return $global:g + ($global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vy)
}

# Runge-Kutta法
for ($i = 1; $y[0] -ge 0.0; $i++)
{
    # 経過秒数
    $t = $i * $h

    # 位置・速度
    $x[1]  = $h *     $vx[0]
    $y[1]  = $h *     $vy[0]
    $vx[1] = $h * (fx $vx[0] $vy[0])
    $vy[1] = $h * (fy $vx[0] $vy[0])

    $wx = $vx[0] + $vx[1] / 2
    $wy = $vy[0] + $vy[1] / 2
    $x[2]  = $h *     $wx
    $y[2]  = $h *     $wy
    $vx[2] = $h * (fx $wx $wy)
    $vy[2] = $h * (fy $wx $wy)

    $wx    = $vx[0] + $vx[2] / 2
    $wy    = $vy[0] + $vy[2] / 2
    $x[3]  = $h *     $wx
    $y[3]  = $h *     $wy
    $vx[3] = $h * (fx $wx $wy)
    $vy[3] = $h * (fy $wx $wy)

    $wx    = $vx[0] + $vx[3]
    $wy    = $vy[0] + $vy[3]
    $x[4]  = $h *     $wx
    $y[4]  = $h *     $wy
    $vx[4] = $h * (fx $wx $wy)
    $vy[4] = $h * (fy $wx $wy)

    $x[0]  += ( $x[1] +  $x[2] * 2 +  $x[3] * 2 +  $x[4]) / 6
    $y[0]  += ( $y[1] +  $y[2] * 2 +  $y[3] * 2 +  $y[4]) / 6
    $vx[0] += ($vx[1] + $vx[2] * 2 + $vx[3] * 2 + $vx[4]) / 6
    $vy[0] += ($vy[1] + $vy[2] * 2 + $vy[3] * 2 + $vy[4]) / 6

    Write-Host ([string]::format("{0,4:F2}`t{1,8:F5}`t{2,9:F5}`t{3,9:F5}`t{4,8:F5}", $t, $vx[0], $vy[0], $x[0], $y[0]))
}
# 重力加速度
$g = -9.8
# 空気抵抗係数
$k = -0.01
# 時間間隔(秒)
$h = 0.01

# 角度
$degree = 45
$radian = $degree * [Math]::PI / 180.0
# 初速 250 km/h -> 秒速に変換
$v = [math]::floor(250 * 1000 / 3600)
# 水平方向の速度
$vx  = New-Object double[] 5
$vx[0] = $v * [Math]::Cos($radian)
# 鉛直方向の速度
$vy  = New-Object double[] 5
$vy[0] = $v * [Math]::Sin($radian)
# 経過秒数
$t = 0.0
# 位置
$x  = New-Object double[] 5
$y  = New-Object double[] 5
$x[0] = 0.0
$y[0] = 0.0

# 空気抵抗による水平方向の減速分
function fx($vx, $vy)
{
    return $global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vx
}
# 重力と空気抵抗による鉛直方向の減速分
function fy($vx, $vy)
{
    return $global:g + ($global:k * [Math]::Sqrt($vx * $vx + $vy * $vy) * $vy)
}

# Runge-Kutta-Gill法
for ($i = 1; $y[0] -ge 0.0; $i++)
{
    # 経過秒数
    $t = $i * $h

    # 位置・速度
    $x[1]  = $h *     $vx[0]
    $y[1]  = $h *     $vy[0]
    $vx[1] = $h * (fx $vx[0] $vy[0])
    $vy[1] = $h * (fy $vx[0] $vy[0])

    $wx = $vx[0] + $vx[1] / 2
    $wy = $vy[0] + $vy[1] / 2
    $x[2]  = $h *     $wx
    $y[2]  = $h *     $wy
    $vx[2] = $h * (fx $wx $wy)
    $vy[2] = $h * (fy $wx $wy)

    $wx    = $vx[0] + $vx[1] * (([Math]::Sqrt(2.0) - 1) / 2) + $vx[2] * (1 - 1 / [Math]::Sqrt(2.0))
    $wy    = $vy[0] + $vy[1] * (([Math]::Sqrt(2.0) - 1) / 2) + $vy[2] * (1 - 1 / [Math]::Sqrt(2.0))
    $x[3]  = $h *     $wx
    $y[3]  = $h *     $wy
    $vx[3] = $h * (fx $wx $wy)
    $vy[3] = $h * (fy $wx $wy)

    $wx    = $vx[0] - $vx[2] / [Math]::Sqrt(2.0) + $vx[3] * (1 + 1 / [Math]::Sqrt(2.0))
    $wy    = $vy[0] - $vy[2] / [Math]::Sqrt(2.0) + $vy[3] * (1 + 1 / [Math]::Sqrt(2.0))
    $x[4]  = $h *    $wx
    $y[4]  = $h *    $wy
    $vx[4] = $h * (fx $wx $wy)
    $vy[4] = $h * (fy $wx $wy)

    $x[0]  += ( $x[1] +  $x[2] * (2 - [Math]::Sqrt(2.0)) +  $x[3] * (2 + [Math]::Sqrt(2.0)) +  $x[4]) / 6
    $y[0]  += ( $y[1] +  $y[2] * (2 - [Math]::Sqrt(2.0)) +  $y[3] * (2 + [Math]::Sqrt(2.0)) +  $y[4]) / 6
    $vx[0] += ($vx[1] + $vx[2] * (2 - [Math]::Sqrt(2.0)) + $vx[3] * (2 + [Math]::Sqrt(2.0)) + $vx[4]) / 6
    $vy[0] += ($vy[1] + $vy[2] * (2 - [Math]::Sqrt(2.0)) + $vy[3] * (2 + [Math]::Sqrt(2.0)) + $vy[4]) / 6

    Write-Host ([string]::format("{0,4:F2}`t{1,8:F5}`t{2,9:F5}`t{3,9:F5}`t{4,8:F5}", $t, $vx[0], $vy[0], $x[0], $y[0]))
}
function bisection($a, $b)
{
    while ($true)
    {
        # 区間 (a, b) の中点 c = (a + b) / 2
        $c = ($a + $b) / 2
        Write-Host ([string]::format("{0,12:F10}`t{1,13:F10}", $c, $c - [Math]::Sqrt(2)))

        $fc = f($c)
        if ([Math]::Abs($fc) -lt 0.0000000001)
        {
            break
        }

        if ($fc -lt 0)
        {
            # f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            $a = $c
        }
        else
        {
            # f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            $b = $c
        }
    }
    return $c
}

function f($x)
{
    return $x * $x - 2
}

$a = 1
$b = 2
Write-Host ([string]::format("{0,12:F10}", (bisection $a $b)))
function falseposition($a, $b)
{
    while ($true)
    {
        # 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        $c = ($a * (f $b) - $b * (f $a)) / ((f $b) - (f $a))
        Write-Host ([string]::format("{0,12:F10}`t{1,13:F10}", $c, $c - [Math]::Sqrt(2)))

        $fc = f($c)
        if ([Math]::Abs($fc) -lt 0.0000000001)
        {
            break
        }

        if ($fc -lt 0)
        {
            # f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            $a = $c
        }
        else
        {
            # f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            $b = $c
        }
    }
    return $c
}

function f($x)
{
    return $x * $x - 2
}

$a = 1
$b = 2
Write-Host ([string]::format("{0,12:F10}", (falseposition $a $b)))
function iterative($x0)
{
    while ($true)
    {
        $x1 = g($x0)
        Write-Host ([string]::format("{0,12:F10}`t{1,13:F10}", $x1, $x1 - [Math]::Sqrt(2)))

        if ([Math]::Abs($x1 - $x0) -lt 0.0000000001)
        {
            break
        }
        $x0 = $x1
    }
    return $x1
}

function g($x)
{
    return ($x / 2) + (1 / $x)
}

$x = 1
Write-Host ([string]::format("{0,12:F10}", (iterative $x)))
function newton($x0)
{
    while ($true)
    {
        $x1 = $x0 - ((f0 $x0) / (f1 $x0))
        Write-Host ([string]::format("{0,12:F10}`t{1,13:F10}", $x1, $x1 - [Math]::Sqrt(2)))

        if ([Math]::Abs($x1 - $x0) -lt 0.0000000001)
        {
            break
        }
        $x0 = $x1
    }
    return $x1
}

function f0($x)
{
    return $x * $x - 2
}

function f1($x)
{
    return 2 * $x
}

$x = 2
Write-Host ([string]::format("{0,12:F10}", (newton $x)))
function bailey($x0)
{
    while ($true)
    {
        $x1 = $x0 - ((f0 $x0) / ((f1 $x0) - ((f0 $x0) * (f2 $x0) / (2 * (f1 $x0)))))
        Write-Host ([string]::format("{0,12:F10}`t{1,13:F10}", $x1, $x1 - [Math]::Sqrt(2)))

        if ([Math]::Abs($x1 - $x0) -lt 0.0000000001)
        {
            break
        }
        $x0 = $x1
    }
    return $x1
}

function f0($x)
{
    return $x * $x - 2
}

function f1($x)
{
    return 2 * $x
}

function f2($x)
{
    return 2
}

$x = 2
Write-Host ([string]::format("{0,12:F10}", (bailey $x)))
function secant($x0, $x1)
{
    while ($true)
    {
        $x2 = $x1 - (f $x1) * ($x1 - $x0) / ((f $x1) - (f $x0))
        Write-Host ([string]::format("{0,12:F10}`t{1,13:F10}", $x2, $x2 - [Math]::Sqrt(2)))

        if ([Math]::Abs($x2 - $x1) -lt 0.0000000001)
        {
            break
        }
        $x0 = $x1
        $x1 = $x2
    }
    return $x2
}

function f($x)
{
    return $x * $x - 2
}

$x0 = 1
$x1 = 2
Write-Host ([string]::format("{0,12:F10}", (secant $x0 $x1)))
inserted by FC2 system