こんにちは!今回は、PHPの標準関数であるsinh()について詳しく解説していきます。双曲線サイン(ハイパボリックサイン)を計算する数学関数です!
sinh関数とは?
sinh()関数は、指定された値の双曲線サイン(ハイパボリックサイン)を計算する関数です。
双曲線関数の一つで、sinh(x) = (e^x - e^-x) / 2という式で定義されます。物理学、工学、統計学など、様々な分野で使用されます!
基本的な構文
sinh(float $num): float
- $num: 双曲線サインを計算する値
- 戻り値: 双曲線サイン値
定義と数学的背景
// sinh(x)の定義
function sinh_manual($x) {
return (exp($x) - exp(-$x)) / 2;
}
// 組み込み関数と比較
$x = 2;
echo "sinh({$x}) = " . sinh($x) . "\n";
echo "手動計算 = " . sinh_manual($x) . "\n";
// 両方とも同じ結果
/*
sinh(x) = (e^x - e^-x) / 2
主な性質:
- sinh(0) = 0
- sinh(-x) = -sinh(x) (奇関数)
- sinh(x)は単調増加
- lim(x→∞) sinh(x) = ∞
- lim(x→-∞) sinh(x) = -∞
*/
基本的な使用例
シンプルな計算
// 基本的な値
echo sinh(0); // 0
echo sinh(1); // 1.1752011936438
echo sinh(-1); // -1.1752011936438
echo sinh(2); // 3.6268604078471
echo sinh(-2); // -3.6268604078471
// 大きな値
echo sinh(5); // 74.203210577788
echo sinh(10); // 11013.232874703
// 小さな値
echo sinh(0.1); // 0.10016675001984
echo sinh(0.01); // 0.010000166667417
主要な値の計算
echo "=== 双曲線サインの主要な値 ===\n";
$values = [-3, -2, -1, 0, 1, 2, 3];
foreach ($values as $x) {
echo sprintf("sinh(%+d) = %+.6f\n", $x, sinh($x));
}
/*
sinh(-3) = -10.017875
sinh(-2) = -3.626860
sinh(-1) = -1.175201
sinh(+0) = +0.000000
sinh(+1) = +1.175201
sinh(+2) = +3.626860
sinh(+3) = +10.017875
*/
双曲線恒等式の確認
// cosh²(x) - sinh²(x) = 1
$x = 2;
$cosh_squared = pow(cosh($x), 2);
$sinh_squared = pow(sinh($x), 2);
echo "cosh²({$x}) - sinh²({$x}) = " . ($cosh_squared - $sinh_squared) . "\n";
// 結果: 1(許容誤差内)
// sinh(2x) = 2·sinh(x)·cosh(x)
$sinh_2x = sinh(2 * $x);
$two_sinh_cosh = 2 * sinh($x) * cosh($x);
echo "sinh(2×{$x}) = " . $sinh_2x . "\n";
echo "2·sinh({$x})·cosh({$x}) = " . $two_sinh_cosh . "\n";
// 両方とも同じ値
実践的な使用例
例1: 双曲線関数計算機
class HyperbolicCalculator {
/**
* 双曲線サイン
*/
public static function sinh($x) {
return sinh($x);
}
/**
* 双曲線コサイン
*/
public static function cosh($x) {
return cosh($x);
}
/**
* 双曲線タンジェント
*/
public static function tanh($x) {
return tanh($x);
}
/**
* 逆双曲線サイン
*/
public static function asinh($x) {
return asinh($x);
}
/**
* 逆双曲線コサイン
*/
public static function acosh($x) {
if ($x < 1) {
return null;
}
return acosh($x);
}
/**
* 逆双曲線タンジェント
*/
public static function atanh($x) {
if (abs($x) >= 1) {
return null;
}
return atanh($x);
}
/**
* すべての双曲線関数値を取得
*/
public static function getAllHyperbolic($x) {
return [
'x' => $x,
'sinh' => sinh($x),
'cosh' => cosh($x),
'tanh' => tanh($x),
'csch' => 1 / sinh($x), // 双曲線余割
'sech' => 1 / cosh($x), // 双曲線正割
'coth' => cosh($x) / sinh($x) // 双曲線余接
];
}
/**
* 双曲線関数の表を生成
*/
public static function generateTable($start = -3, $end = 3, $step = 0.5) {
$table = [];
for ($x = $start; $x <= $end; $x += $step) {
if ($x == 0) {
// sinh(0) = 0なので除算を避ける
$table[] = [
'x' => $x,
'sinh' => sinh($x),
'cosh' => cosh($x),
'tanh' => tanh($x)
];
} else {
$table[] = self::getAllHyperbolic($x);
}
}
return $table;
}
/**
* グーデルマン関数(双曲線関数と三角関数の関係)
*/
public static function gudermannian($x) {
return 2 * atan(tanh($x / 2));
}
}
// 使用例
echo "=== 双曲線関数計算機 ===\n";
$x = 1.5;
echo "x = {$x}の双曲線関数:\n";
$hyp = HyperbolicCalculator::getAllHyperbolic($x);
foreach ($hyp as $name => $value) {
if ($name !== 'x') {
echo sprintf(" %s: %.6f\n", $name, $value);
}
}
// 逆関数
echo "\n=== 逆双曲線関数 ===\n";
$value = 2;
echo "asinh({$value}) = " . HyperbolicCalculator::asinh($value) . "\n";
echo "acosh({$value}) = " . HyperbolicCalculator::acosh($value) . "\n";
$value = 0.5;
echo "atanh({$value}) = " . HyperbolicCalculator::atanh($value) . "\n";
// 双曲線関数表
echo "\n=== 双曲線関数表 ===\n";
echo "x\tsinh(x)\t\tcosh(x)\t\ttanh(x)\n";
$table = HyperbolicCalculator::generateTable(-2, 2, 1);
foreach ($table as $row) {
echo sprintf(
"%.1f\t%.6f\t%.6f\t%.6f\n",
$row['x'],
$row['sinh'],
$row['cosh'],
$row['tanh']
);
}
例2: 懸垂線(カテナリー)の計算
class Catenary {
/**
* 懸垂線の形状を計算
* y = a * cosh(x/a)
*/
public static function calculate($x, $a = 1) {
return $a * cosh($x / $a);
}
/**
* 懸垂線の長さを計算
*/
public static function arcLength($x, $a = 1) {
return $a * sinh($x / $a);
}
/**
* 懸垂線の曲線を生成
*/
public static function generateCurve($start, $end, $steps, $a = 1) {
$curve = [];
$step = ($end - $start) / $steps;
for ($i = 0; $i <= $steps; $i++) {
$x = $start + $i * $step;
$y = self::calculate($x, $a);
$curve[] = [
'x' => $x,
'y' => $y
];
}
return $curve;
}
/**
* 電線や橋のケーブルの垂れ下がりを計算
*/
public static function cableSag($span, $tension, $weight) {
// a = 張力 / 単位重量
$a = $tension / $weight;
// 最低点からの高さ
$halfSpan = $span / 2;
$sag = $a * (cosh($halfSpan / $a) - 1);
return [
'sag' => $sag,
'parameter' => $a,
'span' => $span
];
}
/**
* 懸垂線の面積を計算
*/
public static function area($x1, $x2, $a = 1) {
// 懸垂線とx軸の間の面積
return $a * $a * (sinh($x2 / $a) - sinh($x1 / $a));
}
}
// 使用例
echo "=== 懸垂線(カテナリー) ===\n";
// 基本的な懸垂線
$a = 10;
echo "パラメータa={$a}の懸垂線:\n";
$curve = Catenary::generateCurve(-20, 20, 8, $a);
foreach ($curve as $point) {
echo sprintf("x=%+.1f: y=%.2f\n", $point['x'], $point['y']);
}
// ケーブルの垂れ下がり
echo "\n=== ケーブルの垂れ下がり ===\n";
$span = 100; // スパン(m)
$tension = 5000; // 張力(N)
$weight = 50; // 単位重量(N/m)
$sag = Catenary::cableSag($span, $tension, $weight);
echo "スパン: {$sag['span']}m\n";
echo "垂れ下がり: " . round($sag['sag'], 2) . "m\n";
// 弧長
echo "\n=== 懸垂線の長さ ===\n";
$x = 10;
$arcLength = Catenary::arcLength($x, $a);
echo "x=0から{$x}までの弧長: " . round($arcLength, 2) . "\n";
例3: 統計学での応用
class StatisticsHelper {
/**
* ロジスティック関数(シグモイド関数)
*/
public static function sigmoid($x) {
return 1 / (1 + exp(-$x));
}
/**
* ソフトマックス関数
*/
public static function softmax($values) {
$expValues = array_map('exp', $values);
$sum = array_sum($expValues);
return array_map(function($val) use ($sum) {
return $val / $sum;
}, $expValues);
}
/**
* 双曲線正接を使った正規化
*/
public static function tanhNormalization($x, $scale = 1) {
return tanh($x / $scale);
}
/**
* フィッシャー変換(相関係数の変換)
*/
public static function fisherTransform($r) {
if (abs($r) >= 1) {
return null;
}
return 0.5 * log((1 + $r) / (1 - $r));
// これはatanh(r)と同じ
}
/**
* 逆フィッシャー変換
*/
public static function inverseFisherTransform($z) {
return tanh($z);
}
/**
* グンベル分布の確率密度関数
*/
public static function gumbelPDF($x, $mu = 0, $beta = 1) {
$z = ($x - $mu) / $beta;
return (1 / $beta) * exp(-($z + exp(-$z)));
}
}
// 使用例
echo "=== 統計学での応用 ===\n";
// シグモイド関数
echo "シグモイド関数:\n";
$values = [-3, -2, -1, 0, 1, 2, 3];
foreach ($values as $x) {
echo sprintf("sigmoid(%+d) = %.4f\n", $x, StatisticsHelper::sigmoid($x));
}
// tanhによる正規化
echo "\n=== tanh正規化 ===\n";
$data = [10, 20, 30, 40, 50];
foreach ($data as $x) {
$normalized = StatisticsHelper::tanhNormalization($x, 50);
echo sprintf("%d → %.4f\n", $x, $normalized);
}
// フィッシャー変換
echo "\n=== フィッシャー変換 ===\n";
$correlations = [0.3, 0.5, 0.7, 0.9];
foreach ($correlations as $r) {
$z = StatisticsHelper::fisherTransform($r);
$r_back = StatisticsHelper::inverseFisherTransform($z);
echo sprintf("r=%.1f → z=%.4f → r=%.4f\n", $r, $z, $r_back);
}
// ソフトマックス
echo "\n=== ソフトマックス関数 ===\n";
$logits = [2.0, 1.0, 0.1];
$probabilities = StatisticsHelper::softmax($logits);
echo "入力: " . implode(', ', $logits) . "\n";
echo "確率: " . implode(', ', array_map(fn($p) => round($p, 4), $probabilities)) . "\n";
echo "合計: " . round(array_sum($probabilities), 4) . "\n";
例4: 物理学での応用
class PhysicsApplications {
/**
* 相対論的速度の加算
*/
public static function relativisticVelocityAddition($v1, $v2, $c = 299792458) {
// v = (v1 + v2) / (1 + v1*v2/c²)
return ($v1 + $v2) / (1 + ($v1 * $v2) / ($c * $c));
}
/**
* ラピディティ(相対論的速度パラメータ)
*/
public static function rapidity($velocity, $c = 299792458) {
$beta = $velocity / $c;
if (abs($beta) >= 1) {
return null;
}
return atanh($beta);
}
/**
* ローレンツ因子
*/
public static function lorentzFactor($velocity, $c = 299792458) {
$beta = $velocity / $c;
return 1 / sqrt(1 - $beta * $beta);
}
/**
* 懸垂線形状の重力ポテンシャル
*/
public static function catenaryPotential($x, $a, $g = 9.8, $rho = 1) {
// 単位長さあたりのポテンシャルエネルギー
$y = $a * cosh($x / $a);
return $rho * $g * $y;
}
/**
* 双曲線軌道(宇宙船の軌道)
*/
public static function hyperbolicOrbit($theta, $a, $e) {
// e > 1 の場合の双曲線軌道
if ($e <= 1) {
return null;
}
$r = $a * (1 - $e * $e) / (1 + $e * cos($theta));
return $r;
}
}
// 使用例
echo "=== 物理学での応用 ===\n";
// 相対論的速度
echo "相対論的速度の加算:\n";
$c = 299792458; // 光速 m/s
$v1 = 0.6 * $c;
$v2 = 0.6 * $c;
$v_classical = $v1 + $v2;
$v_relativistic = PhysicsApplications::relativisticVelocityAddition($v1, $v2, $c);
echo "古典的: " . ($v_classical / $c) . "c\n";
echo "相対論的: " . ($v_relativistic / $c) . "c\n";
// ラピディティ
echo "\n=== ラピディティ ===\n";
$velocities = [0.1, 0.3, 0.5, 0.7, 0.9];
foreach ($velocities as $beta) {
$v = $beta * $c;
$rapidity = PhysicsApplications::rapidity($v, $c);
$gamma = PhysicsApplications::lorentzFactor($v, $c);
echo sprintf(
"v=%.1fc: ラピディティ=%.4f, γ=%.4f\n",
$beta,
$rapidity,
$gamma
);
}
// 懸垂線のポテンシャル
echo "\n=== 懸垂線のポテンシャルエネルギー ===\n";
$a = 10;
$positions = [-10, -5, 0, 5, 10];
foreach ($positions as $x) {
$potential = PhysicsApplications::catenaryPotential($x, $a);
echo sprintf("x=%+d: U=%.2f J/m\n", $x, $potential);
}
例5: 工学での応用
class EngineeringApplications {
/**
* 送電線の垂れ下がり計算
*/
public static function powerLineSag($span, $weight, $tension) {
$a = $tension / $weight;
$halfSpan = $span / 2;
return [
'sag' => $a * (cosh($halfSpan / $a) - 1),
'cable_length' => 2 * $a * sinh($halfSpan / $a),
'max_tension' => $weight * $a * cosh($halfSpan / $a)
];
}
/**
* 熱交換器の温度分布
*/
public static function heatExchangerTemperature($x, $L, $T1, $T2) {
// 双曲線関数を使った温度分布モデル
return $T1 + ($T2 - $T1) * (sinh($x / $L) / sinh(1));
}
/**
* ビーム(梁)のたわみ
*/
public static function beamDeflection($x, $L, $load, $EI) {
// 双曲線関数を使った梁のたわみ計算
$lambda = sqrt($load / $EI);
return (1 / ($lambda * $lambda * $EI)) *
(cosh($lambda * $x) - 1 - $lambda * $x * sinh($lambda * $L) / sinh($lambda * $L));
}
/**
* 圧力容器の応力分布
*/
public static function pressureVesselStress($r, $r_inner, $r_outer, $pressure) {
// 双曲線関数を使った応力計算
$k = $r_outer / $r_inner;
$radial_stress = -$pressure * (($k * $k - ($r / $r_inner) ** 2) / ($k * $k - 1));
return $radial_stress;
}
}
// 使用例
echo "=== 工学での応用 ===\n";
// 送電線
echo "送電線の計算:\n";
$span = 200; // m
$weight = 15; // N/m
$tension = 30000; // N
$result = EngineeringApplications::powerLineSag($span, $weight, $tension);
echo "スパン: {$span}m\n";
echo "垂れ下がり: " . round($result['sag'], 2) . "m\n";
echo "ケーブル長: " . round($result['cable_length'], 2) . "m\n";
echo "最大張力: " . round($result['max_tension'], 2) . "N\n";
// 熱交換器
echo "\n=== 熱交換器の温度分布 ===\n";
$L = 1.0;
$T1 = 20; // 入口温度
$T2 = 80; // 出口温度
for ($x = 0; $x <= $L; $x += 0.2) {
$T = EngineeringApplications::heatExchangerTemperature($x, $L, $T1, $T2);
echo sprintf("x=%.1fm: T=%.1f°C\n", $x, $T);
}
例6: 数値計算とシミュレーション
class NumericalMethods {
/**
* 双曲線関数を使った微分方程式の解
*/
public static function hyperbolicODE($x, $A, $B, $lambda) {
return $A * cosh($lambda * $x) + $B * sinh($lambda * $x);
}
/**
* グッゲンハイム法(指数関数のフィッティング)
*/
public static function guggenheimFit($data) {
// 双曲線関数を使ったカーブフィッティング
$n = count($data);
$sum_x = 0;
$sum_y = 0;
foreach ($data as $point) {
$sum_x += $point['x'];
$sum_y += log(abs($point['y']));
}
$mean_x = $sum_x / $n;
$mean_y = $sum_y / $n;
return [
'a' => exp($mean_y),
'b' => $mean_x
];
}
/**
* 双曲線補間
*/
public static function hyperbolicInterpolation($x, $x0, $x1, $y0, $y1) {
$t = ($x - $x0) / ($x1 - $x0);
// 双曲線正接を使った補間
$s = (tanh(2 * $t - 1) + 1) / 2;
return $y0 + $s * ($y1 - $y0);
}
}
// 使用例
echo "=== 数値計算 ===\n";
// 微分方程式の解
echo "双曲線関数による微分方程式の解:\n";
$A = 1;
$B = 2;
$lambda = 0.5;
for ($x = -2; $x <= 2; $x += 1) {
$y = NumericalMethods::hyperbolicODE($x, $A, $B, $lambda);
echo sprintf("x=%+d: y=%.4f\n", $x, $y);
}
// 双曲線補間
echo "\n=== 双曲線補間 ===\n";
$x0 = 0;
$x1 = 10;
$y0 = 0;
$y1 = 100;
for ($x = 0; $x <= 10; $x += 2) {
$y = NumericalMethods::hyperbolicInterpolation($x, $x0, $x1, $y0, $y1);
echo sprintf("x=%d: y=%.2f\n", $x, $y);
}
関連する双曲線関数
$x = 1.5;
echo "=== 双曲線関数ファミリー ===\n";
// 双曲線サイン
echo "sinh({$x}) = " . sinh($x) . "\n";
// 双曲線コサイン
echo "cosh({$x}) = " . cosh($x) . "\n";
// 双曲線タンジェント
echo "tanh({$x}) = " . tanh($x) . "\n";
// 逆双曲線関数
echo "\n=== 逆双曲線関数 ===\n";
$y = 2;
echo "asinh({$y}) = " . asinh($y) . "\n";
echo "acosh({$y}) = " . acosh($y) . "\n";
$y = 0.5;
echo "atanh({$y}) = " . atanh($y) . "\n";
まとめ
sinh()関数の特徴をまとめると:
できること:
- 双曲線サインの計算
- 懸垂線の形状計算
- 相対論的計算
- 統計学での変換
定義:
sinh(x) = (e^x - e^-x) / 2
性質:
- 奇関数:
sinh(-x) = -sinh(x) sinh(0) = 0- 単調増加関数
- 値域: (-∞, +∞)
推奨される使用場面:
- 懸垂線(カテナリー)の計算
- 相対論的物理学
- 統計学(フィッシャー変換)
- 工学(送電線、梁のたわみ)
- 数値計算
重要な恒等式:
cosh²(x) - sinh²(x) = 1
sinh(2x) = 2·sinh(x)·cosh(x)
cosh(x) + sinh(x) = e^x
cosh(x) - sinh(x) = e^-x
関連関数:
cosh(): 双曲線コサインtanh(): 双曲線タンジェントasinh(): 逆双曲線サインacosh(): 逆双曲線コサインatanh(): 逆双曲線タンジェントexp(): 指数関数
よく使うパターン:
// 懸垂線
$y = $a * cosh($x / $a);
// 双曲線軌道
$r = $a * (e² - 1) / (1 + e * cos($theta));
// tanh正規化
$normalized = tanh($x / $scale);
sinh()は、物理学、工学、統計学など様々な分野で重要な役割を果たす関数です。特に懸垂線や相対論的計算では欠かせない関数です!
