PHP asinh()函数

双曲函数: asinh() 函数用于计算反双曲正弦值,返回参数的反双曲正弦值。

asinh() 函数返回一个数的反双曲正弦值(inverse hyperbolic sine)。参数可以是任意实数,返回值也是实数。

函数语法

asinh(float $num): float

参数说明

参数 类型 描述 必需
$num float 要计算反双曲正弦值的数字,可以是任意实数

返回值

返回参数 $num 的反双曲正弦值,以浮点数形式返回。返回值满足:sinh(asinh(x)) = x。

使用示例

示例1:基本用法 - 计算反双曲正弦值

计算不同数字的反双曲正弦值:

<?php
// 计算反双曲正弦值
echo "asinh(0) = " . asinh(0) . "\n";           // 0
echo "asinh(0.5) = " . asinh(0.5) . "\n";       // 约 0.4812118250596
echo "asinh(1) = " . asinh(1) . "\n";           // 约 0.88137358701954
echo "asinh(2) = " . asinh(2) . "\n";           // 约 1.4436354751788
echo "asinh(5) = " . asinh(5) . "\n";           // 约 2.3124383412728
echo "asinh(-1) = " . asinh(-1) . "\n";         // 约 -0.88137358701954
echo "asinh(-2) = " . asinh(-2) . "\n";         // 约 -1.4436354751788

// 验证 sinh(asinh(x)) = x
$x = 3.5;
$asinh_x = asinh($x);
$sinh_asinh_x = sinh($asinh_x);
echo "x = $x\n";
echo "asinh(x) = $asinh_x\n";
echo "sinh(asinh(x)) = $sinh_asinh_x\n";
echo "验证: " . (abs($sinh_asinh_x - $x) < 0.000001 ? "通过" : "失败") . "\n";

// 处理大数和小数
echo "asinh(100) = " . asinh(100) . "\n";       // 约 5.2983423656106
echo "asinh(0.001) = " . asinh(0.001) . "\n";   // 约 0.00099999983333334
echo "asinh(-100) = " . asinh(-100) . "\n";     // 约 -5.2983423656106
?>

示例2:双曲函数关系验证

验证双曲函数和反双曲函数的关系:

<?php
// 双曲函数关系验证
class HyperbolicFunctions {

    // 计算反双曲正弦的自然对数表示
    public static function asinhByFormula($x) {
        return log($x + sqrt($x * $x + 1));
    }

    // 验证 asinh(x) = ln(x + √(x² + 1))
    public static function verifyAsinhFormula($x) {
        $asinh_value = asinh($x);
        $formula_value = self::asinhByFormula($x);
        $difference = abs($asinh_value - $formula_value);

        return [
            'asinh' => $asinh_value,
            'formula' => $formula_value,
            'difference' => $difference,
            'verified' => $difference < 1e-10
        ];
    }

    // 验证双曲函数性质
    public static function verifyProperties($x) {
        $y = asinh($x);

        // 性质1: sinh(asinh(x)) = x
        $property1 = sinh($y);

        // 性质2: asinh(sinh(y)) = y
        $property2 = asinh(sinh($y));

        // 性质3: 奇函数性质 asinh(-x) = -asinh(x)
        $property3 = asinh(-$x);

        // 性质4: 导数公式验证
        $derivative = 1 / sqrt($x * $x + 1);

        return [
            'x' => $x,
            'y' => $y,
            'sinh(y)' => sinh($y),
            'property1_error' => abs($property1 - $x),
            'asinh(sinh(y))' => $property2,
            'property2_error' => abs($property2 - $y),
            'asinh(-x)' => $property3,
            'property3_error' => abs($property3 + $y),
            'derivative' => $derivative
        ];
    }
}

// 测试
echo "公式验证:\n";
$testValues = [0, 0.5, 1, 2, 5, -1, -2];
foreach ($testValues as $x) {
    $result = HyperbolicFunctions::verifyAsinhFormula($x);
    echo "x = $x: asinh = " . round($result['asinh'], 6) .
         ", 公式 = " . round($result['formula'], 6) .
         ", 差异 = " . $result['difference'] .
         ", 验证" . ($result['verified'] ? "通过" : "失败") . "\n";
}

echo "\n双曲函数性质验证:\n";
foreach ([0, 1, 2, -1] as $x) {
    $props = HyperbolicFunctions::verifyProperties($x);
    echo "x = $x, y = asinh(x) = " . round($props['y'], 4) . "\n";
    echo "  验证 sinh(y) = x: sinh(" . round($props['y'], 4) . ") = " .
         round($props['sinh(y)'], 4) . " (误差: " . round($props['property1_error'], 10) . ")\n";
    echo "  验证 asinh(sinh(y)) = y: " . round($props['asinh(sinh(y))'], 4) .
         " (误差: " . round($props['property2_error'], 10) . ")\n";
    echo "  验证奇函数性质 asinh(-x) = -asinh(x): " . round($props['asinh(-x)'], 4) .
         " = -" . round($props['y'], 4) . " (误差: " . round($props['property3_error'], 10) . ")\n";
    echo "  导数: d(asinh(x))/dx = 1/√(x²+1) = " . round($props['derivative'], 4) . "\n\n";
}
?>

示例3:物理和工程应用

在物理和工程问题中应用asinh()函数:

<?php
// 悬链线计算 (Catenary curve) - 另一种形式
class CatenaryCalculator {

    // 计算悬链线的弧长参数
    public static function catenaryArcLength($a, $x) {
        // 弧长 s = a * sinh(x/a)
        return $a * sinh($x / $a);
    }

    // 从弧长反求x坐标
    public static function catenaryXFromArcLength($a, $s) {
        // 反函数: x = a * asinh(s/a)
        return $a * asinh($s / $a);
    }

    // 计算悬链线张力
    public static function catenaryTension($a, $weightPerUnit, $x) {
        // 张力 T = a * weightPerUnit * cosh(x/a)
        return $a * $weightPerUnit * cosh($x / $a);
    }
}

// 使用示例
echo "悬链线计算:\n";
$a = 10; // 参数a
$weightPerUnit = 0.5; // 单位长度重量

echo "参数 a = $a, 单位长度重量 = $weightPerUnit\n\n";

// 计算不同x位置的弧长和张力
$xValues = [0, 5, 10, 15, 20];
echo "悬链线参数:\n";
foreach ($xValues as $x) {
    $arcLength = CatenaryCalculator::catenaryArcLength($a, $x);
    $tension = CatenaryCalculator::catenaryTension($a, $weightPerUnit, $x);
    echo "x = $x: 弧长 = " . round($arcLength, 4) . ", 张力 = " . round($tension, 4) . "\n";
}

echo "\n从弧长反求x坐标:\n";
$s = 15; // 弧长
$xFromArcLength = CatenaryCalculator::catenaryXFromArcLength($a, $s);
echo "弧长 s = $s => x坐标 = " . round($xFromArcLength, 4) . "\n";
echo "验证: 从x坐标计算弧长 = " .
     round(CatenaryCalculator::catenaryArcLength($a, $xFromArcLength), 4) . "\n";

// 相对论中的速度叠加公式(另一种形式)
echo "\n相对论速度叠加(使用双曲函数):\n";
function relativisticVelocityAdditionHyp($v1, $v2, $c = 1) {
    // 使用双曲函数: v = c * tanh(atanh(v1/c) + atanh(v2/c))
    // 或者使用双曲正弦和余弦
    $rapidity1 = asinh($v1 / sqrt($c*$c - $v1*$v1));
    $rapidity2 = asinh($v2 / sqrt($c*$c - $v2*$v2));
    $combinedRapidity = $rapidity1 + $rapidity2;
    return $c * tanh($combinedRapidity);
}

$v1 = 0.6;  // 0.6c
$v2 = 0.8;  // 0.8c
$result = relativisticVelocityAdditionHyp($v1, $v2);
echo "速度1: {$v1}c, 速度2: {$v2}c\n";
echo "相对论叠加: " . round($result, 4) . "c\n";
echo "经典力学叠加: " . round($v1 + $v2, 4) . "c (不正确)\n";
echo "相对论极限: 1c (光速)\n";
?>

示例4:错误处理和数值稳定性

处理asinh()函数的数值稳定性和边界情况:

<?php
// 安全的asinh函数,包含数值稳定性处理
class SafeHyperbolicInverse {

    // 安全的asinh计算,处理数值稳定性
    public static function safeAsinh($x) {
        // 检查输入类型
        if (!is_numeric($x)) {
            throw new InvalidArgumentException("参数必须是数字");
        }

        // 处理特殊情况
        if ($x == 0) return 0.0;
        if (is_infinite($x)) {
            return $x > 0 ? INF : -INF;
        }
        if (is_nan($x)) return NAN;

        // 对于非常大的|x|,使用近似公式避免数值问题
        $absX = abs($x);
        if ($absX > 1e100) {
            // 对于非常大的x,asinh(x) ≈ sign(x) * (ln(2|x|))
            return ($x > 0 ? 1 : -1) * log(2 * $absX);
        }

        // 对于非常小的|x|,使用泰勒展开提高精度
        if ($absX < 1e-8) {
            // 泰勒展开: asinh(x) = x - x³/6 + 3x⁵/40 - ...
            return $x - pow($x, 3)/6 + 3*pow($x, 5)/40;
        }

        // 通用情况:使用标准公式,但要避免数值问题
        // asinh(x) = ln(x + √(x² + 1))
        // 对于负x,利用奇函数性质:asinh(-x) = -asinh(x)
        if ($x < 0) {
            return -self::safeAsinhPositive(-$x);
        }

        return self::safeAsinhPositive($x);
    }

    // 处理正数的asinh,避免数值问题
    private static function safeAsinhPositive($x) {
        // 当x很大时,x + √(x²+1)可能溢出
        // 使用公式:asinh(x) = ln(x + √(x²+1)) = ln(√(x²+1) + x)
        $sqrt = sqrt($x * $x + 1);

        // 检查是否可能溢出
        if (is_infinite($sqrt + $x)) {
            // 使用替代公式:asinh(x) ≈ ln(2x) + 1/(4x²) - ...
            return log(2 * $x) + 1/(4 * $x * $x);
        }

        return log($sqrt + $x);
    }

    // 批量计算并验证
    public static function batchAsinh(array $values) {
        $results = [];
        foreach ($values as $index => $value) {
            try {
                $result = self::safeAsinh($value);
                $verification = sinh($result);

                $results[$index] = [
                    'input' => $value,
                    'result' => $result,
                    'sinh(result)' => $verification,
                    'error' => abs($verification - $value),
                    'status' => 'success'
                ];
            } catch (Exception $e) {
                $results[$index] = [
                    'input' => $value,
                    'result' => null,
                    'status' => 'error',
                    'message' => $e->getMessage()
                ];
            }
        }
        return $results;
    }
}

// 测试数值稳定性
echo "测试数值稳定性:\n";
$testCases = [
    0,                  // 零
    1e-10,              // 非常小的正数
    -1e-10,             // 非常小的负数
    1,                  // 1
    1000,               // 大数
    1e50,               // 非常大的数
    1e100,              // 极限大数
    1e200,              // 超过双精度范围
    -1000,              // 大负数
    "0.5",              // 字符串数字
    "abc",              // 无效字符串
    NAN,                // NAN
    INF,                // 正无穷
    -INF,               // 负无穷
    M_E,                // 自然常数e
    M_PI                // π
];

foreach ($testCases as $testValue) {
    echo "输入: ";
    if (is_nan($testValue)) {
        echo "NAN";
    } elseif (is_infinite($testValue)) {
        echo $testValue > 0 ? "INF" : "-INF";
    } else {
        echo is_float($testValue) ? sprintf("%.2e", $testValue) : $testValue;
    }

    echo " => ";

    try {
        $result = SafeHyperbolicInverse::safeAsinh($testValue);

        if (is_nan($result)) {
            echo "NAN";
        } elseif (is_infinite($result)) {
            echo $result > 0 ? "INF" : "-INF";
        } else {
            echo is_float($result) && abs($result) > 1e10 ?
                 sprintf("%.2e", $result) : round($result, 6);

            // 验证
            if (is_numeric($testValue) && !is_nan($testValue) && !is_infinite($testValue)) {
                $verification = sinh($result);
                echo " (验证误差: " . sprintf("%.2e", abs($verification - $testValue)) . ")";
            }
        }
    } catch (Exception $e) {
        echo "错误: " . $e->getMessage();
    }

    echo "\n";
}

// 比较内置函数和自定义函数的精度
echo "\n精度比较:\n";
$precisionTestValues = [1e-20, 1e-10, 0.5, 1, 10, 1e10, 1e20];
foreach ($precisionTestValues as $value) {
    $builtin = asinh($value);
    $custom = SafeHyperbolicInverse::safeAsinh($value);
    $diff = abs($builtin - $custom);
    echo "x = " . sprintf("%.2e", $value) . ": 内置 = " . sprintf("%.10e", $builtin) .
         ", 自定义 = " . sprintf("%.10e", $custom) . ", 差异 = " . sprintf("%.2e", $diff) . "\n";
}
?>

示例5:科学计算和数据分析

在科学计算和数据分析中使用asinh()函数:

<?php
// 统计学中的双曲变换
class StatisticalTransforms {

    // 反双曲正弦变换(用于处理有正负的数据)
    public static function asinhTransform($x, $scale = 1) {
        // asinh(x/scale) 变换
        return asinh($x / $scale);
    }

    // 反变换
    public static function inverseAsinhTransform($y, $scale = 1) {
        return $scale * sinh($y);
    }

    // 使用asinh变换处理有正负值的数据
    public static function transformData($data, $scale = null) {
        if (empty($data)) {
            return [];
        }

        // 如果没有提供scale,使用数据的标准差
        if ($scale === null) {
            $std = self::standardDeviation($data);
            $scale = $std != 0 ? $std : 1;
        }

        $transformed = [];
        foreach ($data as $value) {
            $transformed[] = self::asinhTransform($value, $scale);
        }

        return [
            'original' => $data,
            'transformed' => $transformed,
            'scale' => $scale,
            'mean_original' => self::mean($data),
            'mean_transformed' => self::mean($transformed),
            'std_original' => self::standardDeviation($data),
            'std_transformed' => self::standardDeviation($transformed)
        ];
    }

    // 计算平均值
    private static function mean($data) {
        return array_sum($data) / count($data);
    }

    // 计算标准差
    private static function standardDeviation($data) {
        $mean = self::mean($data);
        $sum = 0;
        foreach ($data as $value) {
            $sum += pow($value - $mean, 2);
        }
        return sqrt($sum / count($data));
    }
}

// 使用示例:处理有正负值的数据
echo "反双曲正弦变换在统计学中的应用:\n";
$data = [-1000, -100, -10, -1, 0, 1, 10, 100, 1000];
$result = StatisticalTransforms::transformData($data, 100);

echo "原始数据: " . implode(', ', $data) . "\n";
echo "变换数据 (scale=100): " . implode(', ', array_map(function($x) {
    return round($x, 4);
}, $result['transformed'])) . "\n";

echo "\n统计量对比:\n";
echo "原始数据平均值: " . round($result['mean_original'], 4) . "\n";
echo "变换数据平均值: " . round($result['mean_transformed'], 4) . "\n";
echo "原始数据标准差: " . round($result['std_original'], 4) . "\n";
echo "变换数据标准差: " . round($result['std_transformed'], 4) . "\n";

// 反变换验证
echo "\n反变换验证:\n";
$sampleValue = 500;
$transformed = StatisticalTransforms::asinhTransform($sampleValue, 100);
$inverse = StatisticalTransforms::inverseAsinhTransform($transformed, 100);
echo "原始值: $sampleValue\n";
echo "变换值: " . round($transformed, 4) . "\n";
echo "反变换值: " . round($inverse, 4) . "\n";
echo "误差: " . abs($inverse - $sampleValue) . "\n";

// 在数值积分中的应用
echo "\n数值积分中的双曲替换:\n";
function integrateWithHyperbolicSubstitution($a, $b, $n = 1000) {
    // 计算 ∫1/√(x²+1) dx 从 a 到 b
    // 解析解: asinh(x)
    $sum = 0;
    $dx = ($b - $a) / $n;

    for ($i = 0; $i < $n; $i++) {
        $x = $a + ($i + 0.5) * $dx;
        $sum += 1 / sqrt($x * $x + 1);
    }

    return $sum * $dx;
}

// 解析解: ∫1/√(x²+1) dx = asinh(x)
function exactIntegral($x) {
    return asinh($x);
}

$a = 0;
$b = 3;
$numerical = integrateWithHyperbolicSubstitution($a, $b);
$exact = exactIntegral($b) - exactIntegral($a);

echo "数值积分 ∫1/√(x²+1) dx 从 $a 到 $b:\n";
echo "数值结果: " . round($numerical, 6) . "\n";
echo "精确结果: " . round($exact, 6) . " (asinh($b) - asinh($a))\n";
echo "误差: " . abs($numerical - $exact) . "\n";

// 在机器学习中作为激活函数
echo "\n双曲正弦激活函数:\n";
class HyperbolicActivation {

    // 双曲正弦激活函数
    public static function sinhActivation($x) {
        return sinh($x);
    }

    // 反双曲正弦激活函数
    public static function asinhActivation($x) {
        return asinh($x);
    }

    // 双曲正弦激活函数的导数
    public static function sinhActivationDerivative($x) {
        return cosh($x);
    }

    // 反双曲正弦激活函数的导数
    public static function asinhActivationDerivative($x) {
        return 1 / sqrt($x * $x + 1);
    }

    // 计算激活函数输出
    public static function calculateActivation($inputs, $weights, $useAsinh = false) {
        $weightedSum = 0;
        for ($i = 0; $i < count($inputs); $i++) {
            $weightedSum += $inputs[$i] * $weights[$i];
        }

        if ($useAsinh) {
            return self::asinhActivation($weightedSum);
        } else {
            return self::sinhActivation($weightedSum);
        }
    }
}

// 测试激活函数
$inputs = [0.5, -0.2, 0.8];
$weights = [0.3, 0.7, -0.1];

$sinhOutput = HyperbolicActivation::calculateActivation($inputs, $weights, false);
$asinhOutput = HyperbolicActivation::calculateActivation($inputs, $weights, true);

echo "输入: " . implode(', ', $inputs) . "\n";
echo "权重: " . implode(', ', $weights) . "\n";
echo "sinh激活输出: " . round($sinhOutput, 4) . "\n";
echo "asinh激活输出: " . round($asinhOutput, 4) . "\n";
echo "sinh激活导数: " . round(HyperbolicActivation::sinhActivationDerivative(array_sum($inputs)), 4) . "\n";
echo "asinh激活导数: " . round(HyperbolicActivation::asinhActivationDerivative(array_sum($inputs)), 4) . "\n";
?>

数学原理

反双曲正弦定义

对于任意实数 x,反双曲正弦函数 y = asinh(x) 定义为:

y ∈ (-∞, ∞) 使得 sinh(y) = x

其中双曲正弦函数定义为:sinh(y) = (eʸ - e⁻ʸ)/2

定义域: (-∞, ∞)

值域: (-∞, ∞)

重要性质和公式
  • 对数表示:asinh(x) = ln(x + √(x² + 1))
  • 奇函数:asinh(-x) = -asinh(x)
  • 导数:d/dx asinh(x) = 1/√(x² + 1)
  • 积分:∫asinh(x)dx = x·asinh(x) - √(x² + 1) + C
  • 关系式:asinh(x) ≈ x 当 x→0
  • 渐近线:asinh(x) ≈ sign(x)·ln(2|x|) 当 |x|→∞

应用场景

场景 描述 公式/代码
悬链线计算 从弧长反求悬链线参数 asinh($s/$a) * $a
相对论物理 速度叠加和快速性计算 asinh($v/√($c²-$v²))
统计学变换 处理有正负值的数据 asinh($x/$scale)
信号处理 双曲滤波器和变换 asinh($frequency_ratio)
机器学习 作为激活函数使用 asinh($weighted_sum)

注意事项

重要提醒
  • 数值稳定性:对于非常大的参数,直接计算可能产生数值溢出
  • 奇函数性质:asinh(-x) = -asinh(x),可以利用这一性质简化计算
  • 精度问题:当参数非常接近0时,使用泰勒展开可以提高精度
  • 特殊值:asinh(NAN) 返回 NANasinh(INF) 返回 INF
  • 性能:对于大量计算,使用数值稳定的实现可以提高性能

相关函数

sinh()

计算双曲正弦值

acosh()

计算反双曲余弦值

atanh()

计算反双曲正切值

asinh()

计算反双曲正弦值(当前函数)

log()

计算自然对数

sqrt()

计算平方根

常见问题

  • asin()是反正弦函数(inverse sine),处理普通三角函数
  • asinh()是反双曲正弦函数(inverse hyperbolic sine),处理双曲函数
  • asin()定义域:[-1, 1],值域:[-π/2, π/2]
  • asinh()定义域:(-∞, ∞),值域:(-∞, ∞)
  • asin()与圆函数相关,asinh()与双曲线函数相关
  • asinh()是奇函数,asin()也是奇函数

因为双曲正弦函数sinh(x) = (eˣ - e⁻ˣ)/2的值域是(-∞, ∞)。对于任何实数y,sinh(y)可以取任何实数值。因此,反函数asinh(x)的定义域自然就是所有实数。这意味着对于任何实数x,都存在唯一的实数y满足sinh(y) = x。

  1. 接近0的值:使用泰勒展开 asinh(x) ≈ x - x³/6 + 3x⁵/40
  2. 非常大的值:使用近似 asinh(x) ≈ sign(x)·ln(2|x|)
  3. 通用情况:使用公式 asinh(x) = ln(x + √(x²+1)),但要避免大数相减
  4. 利用奇函数性质:只计算正数的asinh,负数通过奇函数性质得到
  5. 精度控制:根据参数大小选择不同的计算方法