首页 函数目录

    伽玛累积分布函数

    p=gamcdf(x,a)返回具有a中的形状参数的标准gamma分布的累积分布函数(cdf),在x中的值处进行评估。.

    p=gamcdf(x,a,b)返回伽玛分布的cdf,其中a中的形状参数和b中的比例参数在x中的值处进行评估.

    x是评估cdf的值,非负标量,非负标量数组

    a是形状参数,正标量值,正标量值数组

    b是比例参数,默认值是1,正标量值,正标量的数组.

    如果输入参数x,a和b中的一个或多个是数组,则数组大小必须相同.在这种情况下,gamcdf将每个标量输入扩展为与数组输入大小相同的常量数组.p中的每个元素都是由a和b中的对应元素指定的分布的cdf值, 在x中的相应元素处进行评估.

    示例1:等待时间分析

    假设某服务台平均每分钟服务2个客户(k=2, θ=0.5分钟)

    计算等待时间不超过1分钟的概率
    result1 = gamcdf(1, 2, 0.5)
    print(f"等待时间≤1分钟的概率: {float(result1):.4f} ({result1})")
    #等待时间≤1分钟的概率: 0.5940 (0.593994150290162)

    计算不同等待时间的概率
    times = [0.5, 1.0, 1.5, 2.0]
    for t in times:
        prob = gamcdf(t, 2, 0.5)
        print(f"等待时间≤{t}分钟的概率: {float(prob):.4f}")
    #等待时间≤0.5分钟的概率: 0.2642
    #等待时间≤1.0分钟的概率: 0.5940
    #等待时间≤1.5分钟的概率: 0.8009
    #等待时间≤2.0分钟的概率: 0.9084
    #应用意义: 服务质量评估和资源规划

    示例2:保险理赔分析

    假设理赔金额服从伽马分布(k=3, θ=1000)

    计算理赔金额不超过5000元的概率
    result2 = gamcdf(5000, 3, 1000)
    print(f"理赔金额≤5000元的概率: {float(result2):.4f}")
    #理赔金额≤5000元的概率: 0.8753

    计算不同金额的概率
    amounts = [1000, 3000, 5000, 10000]
    for amount in amounts:
        prob = gamcdf(amount, 3, 1000)
        print(f"理赔金额≤{amount}元的概率: {float(prob):.4f}")
    #理赔金额≤1000元的概率: 0.0803
    #理赔金额≤3000元的概率: 0.5768
    #理赔金额≤5000元的概率: 0.8753
    #理赔金额≤10000元的概率: 0.9972
    #保险意义: 风险评估和保费定价

    示例3:设备寿命预测

    假设设备寿命服从伽马分布(k=2.5, θ=1000小时)

    计算设备在2000小时内故障的概率
    result3 = gamcdf(2000, 2.5, 1000)
    print(f"设备在2000小时内故障的概率: {float(result3):.4f}")
    #设备在2000小时内故障的概率: 0.4506

    计算不同时间的可靠性
    lifetimes = [500, 1000, 2000, 3000]
    for time in lifetimes:
        prob = gamcdf(time, 2.5, 1000)
        reliability = 1 - float(prob)
        print(f"设备运行{time}小时的可靠性: {reliability:.4f}")
    #设备运行500小时的可靠性: 0.9626
    #设备运行1000小时的可靠性: 0.8491
    #设备运行2000小时的可靠性: 0.5494
    #设备运行3000小时的可靠性: 0.3062
    #工程意义: 预防性维护计划制定

    示例4:软件缺陷发现模型

    使用伽马分布模拟软件测试过程中缺陷的发现模式

    k=3表示缺陷发现速率的变化,θ=50表示平均发现时间
    testing_hours = [100, 200, 300, 400]
    for hours in testing_hours:
        prob = gamcdf(hours, 3, 50)
        print(f"在{hours}小时测试内发现缺陷的概率: {float(prob):.4f}")
    #在100小时测试内发现缺陷的概率: 0.3233
    #在200小时测试内发现缺陷的概率: 0.7619
    #在300小时测试内发现缺陷的概率: 0.9380
    #在400小时测试内发现缺陷的概率: 0.9862
    #软件工程意义: 测试进度评估和发布决策

    示例5:极端损失概率计算

    使用伽马分布模拟极端损失事件(k=2, θ=100000)

    loss_thresholds = [100000, 200000, 500000, 1000000]
    for loss in loss_thresholds:
        prob = gamcdf(loss, 2, 100000)
        print(f"损失≤{loss:,}元的概率: {float(prob):.6f}")
    #损失≤100,000元的概率: 0.264241
    #损失≤200,000元的概率: 0.593994
    #损失≤500,000元的概率: 0.959572
    #损失≤1,000,000元的概率: 0.999501
    #金融意义: 风险资本计算和压力测试

    示例6:信用风险建模

    贷款违约时间可以用伽马分布建模

    months = [6, 12, 24, 36]
    for month in months:
        # k=1.8, θ=18个月的平均违约时间
        prob = gamcdf(month, 1.8, 18)
        print(f"贷款在{month}个月内违约的概率: {float(prob):.4f}")
    #贷款在6个月内违约的概率: 0.0669
    #贷款在12个月内违约的概率: 0.1899
    #贷款在24个月内违约的概率: 0.4494
    #贷款在36个月内违约的概率: 0.6527
    #银行意义: 贷款损失准备金计算

    示例7:疾病潜伏期分析

    疾病潜伏期常用伽马分布描述

    days = [3, 7, 14, 21]
    for day in days:
        # k=5, θ=2表示平均潜伏期10天
        prob = gamcdf(day, 5, 2)
        print(f"潜伏期≤{day}天的概率: {float(prob):.4f}")
    #潜伏期≤3天的概率: 0.0186
    #潜伏期≤7天的概率: 0.2746
    #潜伏期≤14天的概率: 0.8270
    #潜伏期≤21天的概率: 0.9789
    #流行病学意义: 隔离政策制定

    示例8:药物治疗响应时间

    药物生效时间分布
    hours = [1, 2, 4, 8]
    for hour in hours:
        prob = gamcdf(hour, 2, 1.5)
        print(f"药物在{hour}小时内生效的概率: {float(prob):.4f}")
    #药物在1小时内生效的概率: 0.1443
    #药物在2小时内生效的概率: 0.3849
    #药物在4小时内生效的概率: 0.7452
    #药物在8小时内生效的概率: 0.9694
    #临床意义: 治疗方案优化

    示例9:带符号参数的伽马CDF

    symbolic_result = gamcdf(t, k, theta)

    通用伽马CDF公式:
    print(symbolic_result)
    #Piecewise((lowergamma(k, t/theta)/gamma(k), t > 0), (0, True))
    #数学意义: 理论分析和公式推导

    示例10:特定参数下的符号结果

    for k in [1, 2, 3, 4]:
        result = gamcdf(t, k, 1)
        print(f"k={k}, θ=1时的CDF: {result}")
    #k=1, θ=1时的CDF: Piecewise((1.0 - exp(-t), t > 0), (0, True))
    #k=2, θ=1时的CDF: Piecewise(((-t + 1.0*exp(t) - 1.0)*exp(-t), t > 0), (0, True))
    #k=3, θ=1时的CDF: Piecewise(((-0.5*t**2 - t + 1.0*exp(t) - 1.0)*exp(-t), t > 0), (0, True))
    #k=4, θ=1时的CDF: Piecewise(((-0.166666666666667*t**3 - 0.5*t**2 - t + 1.0*exp(t) - 1.0)*exp(-t), t > 0), (0, True))
    #解析意义: 显示不同形状参数下的分布特性

    示例11:批量概率计算

    使用矩阵输入同时计算多个概率
    times_matrix = [[1, 2, 3], [4, 5, 6]]
    k_value = 2
    theta_value = 1

    时间矩阵:
    for i, row in enumerate(times_matrix):
        for j, time in enumerate(row):
            prob = gamcdf(time, k_value, theta_value)
            print(f"位置({i},{j}): 时间={time}, 概率={float(prob):.4f}")
    #位置(0,0): 时间=1, 概率=0.2642
    #位置(0,1): 时间=2, 概率=0.5940
    #位置(0,2): 时间=3, 概率=0.8009
    #位置(1,0): 时间=4, 概率=0.9084
    #位置(1,1): 时间=5, 概率=0.9596
    #位置(1,2): 时间=6, 概率=0.9826
    #批量计算意义: 高效处理多个相似计算

    示例12:贝叶斯分析中的共轭先验

    伽马分布是指数族分布的共轭先验

    先验分布: Gamma(k0, θ0)
    k0, theta0 = 2, 1
    print(f"先验分布: Gamma(k={k0}, θ={theta0})")
    #先验分布: Gamma(k=2, θ=1)

    后验分布计算示例
    data = [1.2, 2.3, 0.8, 1.5, 2.1]  # 观测数据
    n = len(data)
    sum_data = sum(data)

    后验参数
    k_posterior = k0 + n
    theta_posterior = theta0 / (1 + theta0 * sum_data)

    print(f"后验分布: Gamma(k={k_posterior}, θ={theta_posterior:.4f})")
    #后验分布: Gamma(k=7, θ=0.1124)
    #贝叶斯意义: 参数估计的不确定性量化

    示例13:假设检验

    检验假设: 平均等待时间是否小于2分钟
    critical_value = 2.0
    k_test, theta_test = 2, 0.8  # 假设的参数

    p_value = float(gamcdf(critical_value, k_test, theta_test))
    print(f"零假设下观测到等待时间≤{critical_value}分钟的概率: {p_value:.4f}")
    #零假设下观测到等待时间≤2.0分钟的概率: 0.7127

    alpha = 0.05  # 显著性水平
    if p_value < alpha:
        print("拒绝零假设: 平均等待时间显著小于2分钟")
    else:
        print("无法拒绝零假设: 没有足够证据表明平均等待时间小于2分钟")
    #无法拒绝零假设: 没有足够证据表明平均等待时间小于2分钟
    #统计意义: 基于分布的假设检验方法
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    from scipy.stats import gamma as scipy_gamma
    from sympy.stats import Gamma, cdf


    def gamma_cumulative_distribution(input_str):
        """
        伽马分布累积分布函数(CDF),支持符号变量和数值计算

        特性:
        1. 自动检测输入类型(符号/数值)
        2. 符号计算使用sympy,数值计算使用scipy加速
        3. 支持矩阵广播和元素级运算

        输入格式:
        "(x, k, theta)" 或 "(x, k)"(theta默认为1)
        参数可以是标量、矩阵或包含符号的表达式

        示例:
        "(t, 2, 1)"          -> 符号结果: 1 - (t + 1)*exp(-t)
        "([[1,2],[3,4]], 2)" -> 数值矩阵结果
        """
        try:
            # 符号检测函数
            expr = sp.sympify(input_str)
            result = None

            if isinstance(expr, tuple):
                if len(expr) == 3:
                    z = expr[0]
                    k = expr[1]  # k
                    theta = expr[2]  # theta
                elif len(expr) == 2:
                    z = expr[0]
                    k = expr[1]  # k
                    theta = 1  # theta
                else:
                    return f"输入错误:{input_str}"

                if any(e.free_symbols for e in expr):
                    X = Gamma("gamma", k, theta)
                    result = cdf(X)(z)
                else:
                    if k <= 0 or theta <= 0:
                        raise ValueError("k和theta必须>0")
                    result = scipy_gamma.cdf(float(z), a=float(k), scale=float(theta))

            return result

        except Exception as e:
            return f"错误: {str(e)}"


    # 测试案例
    if __name__ == "__main__":
        # 符号计算测试
        print("符号测试:")
        symbolic_input = "(t, 2, 1)"
        symbolic_result = gamma_cumulative_distribution(symbolic_input)
        print(f"输入: {symbolic_input}\n符号结果:", symbolic_result.simplify())
        # 符号结果: Piecewise(((-t + exp(t) - 1)*exp(-t), t > 0), (0, True))

        # 数值矩阵测试
        print("\n数值矩阵测试:")
        matrix_input = "(1, 2)"
        matrix_result = gamma_cumulative_distribution(matrix_input)
        print(f"输入: {matrix_input}\n数值结果:\n{np.array(matrix_result, dtype=float)}")
        # 0.2642411176571153

        # 混合输入测试
        print("\n混合输入测试:")
        mixed_input = "(x, 2, 1)"
        mixed_result = gamma_cumulative_distribution(mixed_input)
        print(f"输入: {mixed_input}\n混合结果:", mixed_result)
        # 混合结果: Piecewise((-(x + 1)*exp(-x) + 1, x > 0), (0, True))
    
    
    伽玛参数估计

    [phat,pci]=gamfit(data)返回MLE和95%置信区间。pci的第一行是置信区间的下限;最后一行是上限.

    示例1:设备故障时间数据分析

    模拟设备故障时间数据(单位:小时)
    np.random.seed(42)  # 保证结果可重现
    true_k, true_theta = 2.5, 800  # 真实参数:形状参数2.5,尺度参数800小时
    failure_times = st.gamma.rvs(a=true_k, scale=true_theta, size=50)

    print(f"故障时间数据样本(前10个): {failure_times[:10].round(1)}")
    #故障时间数据样本(前10个): [2386.5 1575.6 1472.  1472.  4337.3 2803.2 1237.2 2453.9 2034.2  315.5]

    estimates, ci = gamfit(failure_times)

    print(f"真实参数: 形状k={true_k}, 尺度θ={true_theta}小时")
    print(f"估计参数: 形状k={estimates[0]:.3f}, 尺度θ={estimates[1]:.3f}小时")
    print(f"平均故障时间(MTTF): {estimates[0] * estimates[1]:.1f}小时")
    print(f"形状参数95%置信区间: [{ci[0][0]:.3f}, {ci[0][1]:.3f}]")
    print(f"尺度参数95%置信区间: [{ci[1][0]:.3f}, {ci[1][1]:.3f}]")
    #真实参数: 形状k=2.5, 尺度θ=800小时
    #估计参数: 形状k=4.044, 尺度θ=476.840小时
    #平均故障时间(MTTF): 1928.1小时
    #形状参数95%置信区间: [2.995, 6.127]
    #尺度参数95%置信区间: [298.978, 660.475]
    #工程意义: 设备可靠性评估和预防性维护计划

    示例2:保险理赔金额分析

    模拟保险理赔金额数据(单位:万元)
    true_k_insurance, true_theta_insurance = 3.2, 15  # 真实参数
    claim_amounts = st.gamma.rvs(a=true_k_insurance, scale=true_theta_insurance, size=200)
    claim_amounts = np.maximum(claim_amounts, 0.1)  # 确保最小理赔金额

    estimates_insurance, ci_insurance = gamfit(claim_amounts)

    print(f"理赔金额数据统计: 均值={claim_amounts.mean():.2f}万, 标准差={claim_amounts.std():.2f}万")
    print(f"估计参数: 形状k={estimates_insurance[0]:.3f}, 尺度θ={estimates_insurance[1]:.3f}万")
    print(f"平均理赔金额: {estimates_insurance[0] * estimates_insurance[1]:.2f}万")
    print(f"形状参数95%置信区间: [{ci_insurance[0][0]:.3f}, {ci_insurance[0][1]:.3f}]")
    print(f"尺度参数95%置信区间: [{ci_insurance[1][0]:.3f}, {ci_insurance[1][1]:.3f}]")
    #理赔金额数据统计: 均值=47.13万, 标准差=27.04万
    #估计参数: 形状k=2.945, 尺度θ=16.004万
    #平均理赔金额: 47.13万
    #形状参数95%置信区间: [2.499, 3.575]
    #尺度参数95%置信区间: [13.070, 19.034]
    #保险意义: 保费定价和准备金计算

    示例3:电子元件寿命测试

    模拟高温加速测试下的元件寿命数据(单位:小时)
    np.random.seed(123)
    true_k_component, true_theta_component = 1.8, 500
    component_lifetimes = st.gamma.rvs(a=true_k_component, scale=true_theta_component, size=30)

    estimates_component, ci_component = gamfit(component_lifetimes)

    print(f"元件寿命数据: 最短={component_lifetimes.min():.1f}h, 最长={component_lifetimes.max():.1f}h")
    print(f"估计参数: 形状k={estimates_component[0]:.3f}, 尺度θ={estimates_component[1]:.3f}小时")
    #元件寿命数据: 最短=8.9h, 最长=3345.3h
    #估计参数: 形状k=1.162, 尺度θ=872.768小时

    计算可靠性指标
    mttf = estimates_component[0] * estimates_component[1]  # 平均故障时间
    reliability_1000h = 1 - st.gamma.cdf(1000, estimates_component[0], scale=estimates_component[1])

    print(f"平均寿命(MTTF): {mttf:.1f}小时")
    print(f"1000小时可靠性: {reliability_1000h:.4f}")
    print(f"形状参数95%置信区间: [{ci_component[0][0]:.3f}, {ci_component[0][1]:.3f}]")
    #平均寿命(MTTF): 1014.4小时
    #1000小时可靠性: 0.3829
    #形状参数95%置信区间: [0.752, 2.381]
    #质量工程意义: 产品寿命预测和质量改进

    示例4:软件系统故障间隔时间

    模拟软件系统故障间隔时间(单位:天)
    true_k_software, true_theta_software = 2.0, 30
    failure_intervals = st.gamma.rvs(a=true_k_software, scale=true_theta_software, size=25)

    estimates_software, ci_software = gamfit(failure_intervals)

    print(f"故障间隔数据: 平均间隔={failure_intervals.mean():.1f}天")
    print(f"估计参数: 形状k={estimates_software[0]:.3f}, 尺度θ={estimates_software[1]:.3f}天")
    print(f"平均故障间隔时间(MTBF): {estimates_software[0] * estimates_software[1]:.1f}天")
    print(f"30天内无故障概率: {1 - st.gamma.cdf(30, estimates_software[0], scale=estimates_software[1]):.4f}")
    #故障间隔数据: 平均间隔=50.1天
    #估计参数: 形状k=2.463, 尺度θ=20.353天
    #平均故障间隔时间(MTBF): 50.1天
    #30天内无故障概率: 0.6986
    #软件工程意义: 系统稳定性评估和发布决策

    示例5:极端损失事件金额建模

    模拟极端损失事件数据(单位:百万元)
    np.random.seed(456)
    true_k_loss, true_theta_loss = 2.5, 50  # 真实参数
    extreme_losses = st.gamma.rvs(a=true_k_loss, scale=true_theta_loss, size=80)

    estimates_loss, ci_loss = gamfit(extreme_losses)

    print(f"极端损失数据: 次数={len(extreme_losses)}, 最大损失={extreme_losses.max():.1f}百万")
    print(f"估计参数: 形状k={estimates_loss[0]:.3f}, 尺度θ={estimates_loss[1]:.3f}百万")
    #极端损失数据: 次数=80, 最大损失=384.9百万
    #估计参数: 形状k=3.034, 尺度θ=41.349百万

    计算风险指标
    var_95 = st.gamma.ppf(0.95, estimates_loss[0], scale=estimates_loss[1])  # 95% VaR
    expected_shortfall = extreme_losses[extreme_losses > var_95].mean() if len(
        extreme_losses[extreme_losses > var_95]) > 0 else var_95

    print(f"95%风险价值(VaR): {var_95:.1f}百万")
    print(f"期望短缺(Expected Shortfall): {expected_shortfall:.1f}百万")
    print(f"形状参数95%置信区间: [{ci_loss[0][0]:.3f}, {ci_loss[0][1]:.3f}]")
    #95%风险价值(VaR): 262.4百万
    #期望短缺(Expected Shortfall): 325.8百万
    #形状参数95%置信区间: [2.472, 4.018]
    #风险管理意义: 资本充足率计算和压力测试

    示例6:贷款违约损失分布

    模拟贷款违约损失率数据(百分比)
    true_k_loan, true_theta_loan = 4.0, 2.5
    loss_rates = st.gamma.rvs(a=true_k_loan, scale=true_theta_loan, size=150) / 100  # 转换为小数

    estimates_loan, ci_loan = gamfit(loss_rates * 100)  # 保持百分比单位

    print(f"违约损失率数据: 均值={loss_rates.mean() * 100:.2f}%, 标准差={loss_rates.std() * 100:.2f}%")
    print(f"估计参数: 形状k={estimates_loan[0]:.3f}, 尺度θ={estimates_loan[1]:.3f}%")
    print(f"平均损失率: {estimates_loan[0] * estimates_loan[1] / 100:.4f} ({estimates_loan[0] * estimates_loan[1]:.2f}%)")
    #违约损失率数据: 均值=10.21%, 标准差=5.32%
    #估计参数: 形状k=3.956, 尺度θ=2.582%
    #平均损失率: 0.1021 (10.21%)
    #信贷风险意义: 贷款损失准备金计算

    示例7:疾病潜伏期分布估计

    模拟疾病潜伏期数据(单位:天)
    np.random.seed(789)
    true_k_incubation, true_theta_incubation = 5.5, 1.8
    incubation_periods = st.gamma.rvs(a=true_k_incubation, scale=true_theta_incubation, size=100)

    estimates_incubation, ci_incubation = gamfit(incubation_periods)

    print(f"潜伏期数据: 最短={incubation_periods.min():.1f}天, 最长={incubation_periods.max():.1f}天")
    print(f"估计参数: 形状k={estimates_incubation[0]:.3f}, 尺度θ={estimates_incubation[1]:.3f}天")
    #潜伏期数据: 最短=1.7天, 最长=21.6天
    #估计参数: 形状k=5.401, 尺度θ=1.833天

    计算重要百分位数
    median_incubation = st.gamma.ppf(0.5, estimates_incubation[0], scale=estimates_incubation[1])
    p95_incubation = st.gamma.ppf(0.95, estimates_incubation[0], scale=estimates_incubation[1])

    print(f"潜伏期中位数: {median_incubation:.1f}天")
    print(f"95%分位数: {p95_incubation:.1f}天")
    print(f"形状参数95%置信区间: [{ci_incubation[0][0]:.3f}, {ci_incubation[0][1]:.3f}]")
    #潜伏期中位数: 9.3天
    #95%分位数: 17.8天
    #形状参数95%置信区间: [4.286, 7.292]
    #流行病学意义: 隔离政策制定和传播动力学建模

    示例8:环境污染物浓度分析

    模拟河流污染物浓度数据(单位:mg/L)
    true_k_pollutant, true_theta_pollutant = 3.0, 0.8
    pollutant_concentrations = st.gamma.rvs(a=true_k_pollutant, scale=true_theta_pollutant, size=60)

    estimates_pollutant, ci_pollutant = gamfit(pollutant_concentrations)

    regulatory_limit = 2.0  # 法规限值 2mg/L
    exceedance_prob = 1 - st.gamma.cdf(regulatory_limit, estimates_pollutant[0], scale=estimates_pollutant[1])

    print(f"污染物浓度数据: 均值={pollutant_concentrations.mean():.3f}mg/L")
    print(f"估计参数: 形状k={estimates_pollutant[0]:.3f}, 尺度θ={estimates_pollutant[1]:.3f}mg/L")
    print(f"超过法规限值({regulatory_limit}mg/L)的概率: {exceedance_prob:.4f}")
    #污染物浓度数据: 均值=2.343mg/L
    #估计参数: 形状k=2.381, 尺度θ=0.984mg/L
    #超过法规限值(2.0mg/L)的概率: 0.5070
    #环境科学意义: 环境风险评估和监管合规分析
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import scipy.stats as st


    def gamma_parameter_estimates(data):
        """
        估计Gamma分布的参数及置信区间,对标MATLAB的gamfit函数

        参数:
        data: list/array 输入数据样本

        返回:
        tuple: (参数估计值, 置信区间)
            参数估计值格式: [形状参数, 尺度参数]
            置信区间格式: [[形状参数CI], [尺度参数CI]]
            如果出错返回错误信息字符串
        """
        try:
            # 将输入转换为numpy数组
            data = np.array(data, dtype=float)

            # 拟合Gamma分布参数(固定位置参数loc=0)
            shape_est, _, scale_est = st.gamma.fit(data, floc=0)

            # 自举法参数设置
            n_bootstraps = 1000  # 通常建议1000次以上
            shape_estimates = []
            scale_estimates = []

            # 执行自举采样
            for _ in range(n_bootstraps):
                sample = np.random.choice(data, size=len(data), replace=True)
                shape, _, scale = st.gamma.fit(sample, floc=0)
                shape_estimates.append(shape)
                scale_estimates.append(scale)

            # 计算95%置信区间
            shape_ci = np.percentile(shape_estimates, [2.5, 97.5])
            scale_ci = np.percentile(scale_estimates, [2.5, 97.5])

            return [shape_est, scale_est], [shape_ci, scale_ci]

        except Exception as e:
            return f"错误: {e}"


    # 示例代码
    if __name__ == "__main__":
        # 生成模拟数据(形状参数k=2,尺度参数θ=1)
        true_k, true_theta = 2, 1
        data = st.gamma.rvs(a=true_k, scale=true_theta, size=10)
        # 进行参数估计
        estimates, confidence_intervals = gamma_parameter_estimates(data)

        # 结果展示
        print(f"真实参数: 形状={true_k}, 尺度={true_theta}")
        print(f"估计参数: 形状={estimates[0]:.3f}, 尺度={estimates[1]:.3f}")
        print(f"形状参数95%置信区间: [{confidence_intervals[0][0]:.3f}, {confidence_intervals[0][1]:.3f}]")
        print(f"尺度参数95%置信区间: [{confidence_intervals[1][0]:.3f}, {confidence_intervals[1][1]:.3f}]")
        # 形状参数95%置信区间: [2.178, 8.166]
        # 尺度参数95%置信区间: [0.219, 1.020]
    
    
    伽玛分布的逆累积分布函数(gamma ppf = gamma cdf inverse)

    x=gaminv(p,a)返回具有形状参数a的标准伽玛分布的逆累积分布函数(icdf),该形状参数在p中的值处进行评估。.

    x=gaminv(p,a,b)返回具有形状参数a和尺度参数b的伽玛分布的icdf,以p中的值进行评估。.

    p是计算icdf的概率值,取值范围[0,1]

    a是形状参数. 正标量值,正标量值数组

    b是标度参数. 1是默认值,正标量值,正标量的数组.

    示例1:金融风险价值(VaR)计算

    假设损失分布服从Gamma(k=3, θ=10000)
    confidence_levels = [0.90, 0.95, 0.99]  # 置信水平
    k_risk, theta_risk = 3.0, 10000

    print(f"损失分布参数: 形状k={k_risk}, 尺度θ={theta_risk}")
    #损失分布参数: 形状k=3.0, 尺度θ=10000

    不同置信水平下的风险价值(VaR):
    for cl in confidence_levels:
        var = gaminv(cl, k_risk, theta_risk)
        print(f"{cl * 100}% VaR: {var:,.0f} 元")
    #90.0% VaR: 53,223 元
    #95.0% VaR: 62,958 元
    #99.0% VaR: 84,059 元

    计算期望短缺(Expected Shortfall)
    es_95 = st.gamma.expect(lambda x: x, args=(k_risk,), scale=theta_risk,
                            lb=gaminv(0.95, k_risk, theta_risk))
    conditional_var = es_95 / (1 - 0.95)  # 条件风险价值

    print(f"95% 期望短缺: {conditional_var:,.0f} 元")
    #95% 期望短缺: 76,017 元
    #金融意义: 金融机构资本充足率计算和风险管理

    示例2:保险理赔准备金计算

    假设理赔分布为Gamma(k=4, θ=5000)
    k_claim, theta_claim = 4.0, 5000
    reserve_percentiles = [0.75, 0.90, 0.95, 0.99]

    不同分位数下的理赔准备金估计:
    for p in reserve_percentiles:
        reserve = gaminv(p, k_claim, theta_claim)
        print(f"{p * 100}% 分位数准备金: {reserve:,.0f} 元")
    #75.0% 分位数准备金: 25,547 元
    #90.0% 分位数准备金: 33,404 元
    #95.0% 分位数准备金: 38,768 元
    #99.0% 分位数准备金: 50,226 元

    计算超额赔款再保险起赔点
    attachment_point = gamma_inverse_ppf(f"0.95, {k_claim}, {theta_claim}")
    print(f"超额赔款再保险起赔点: {attachment_point:,.0f} 元")
    #超额赔款再保险起赔点: 38,768 元
    #保险意义: 再保险定价和资本管理

    示例3:生产过程容差限计算

    假设产品尺寸变异服从Gamma(k=8, θ=0.1mm)
    k_quality, theta_quality = 8.0, 0.1
    tolerance_levels = [0.001, 0.01, 0.05, 0.10]  # 允许的不合格品率

    基于不同质量要求的过程容差限:
    for alpha in tolerance_levels:
        upper_limit = gaminv(1 - alpha, k_quality, theta_quality)
        print(f"{alpha * 100}% 不合格率对应的上限: {upper_limit:.3f} mm")
    #0.1% 不合格率对应的上限: 1.963 mm
    #1.0% 不合格率对应的上限: 1.600 mm
    #5.0% 不合格率对应的上限: 1.315 mm
    #10.0% 不合格率对应的上限: 1.177 mm

    六西格玛质量水平计算
    six_sigma_limit = gaminv(0.9999966, k_quality, theta_quality)
    print(f"六西格玛质量水平上限: {six_sigma_limit:.3f} mm")
    #六西格玛质量水平上限: 2.756 mm
    #质量工程意义: 统计过程控制和规格限设定

    示例4:环境监测预警阈值

    污染物浓度分布Gamma(k=2.5, θ=0.3mg/L)
    k_pollutant, theta_pollutant = 2.5, 0.3
    regulatory_limit = 2.0  # 法规限值

    计算不同预警级别的阈值
    warning_levels = [0.90, 0.95, 0.99]

    不同预警级别的污染物浓度阈值:
    for level in warning_levels:
        threshold = gaminv(level, k_pollutant, theta_pollutant)
        status = "超标" if threshold > regulatory_limit else "达标"
        print(f"{level * 100}% 预警阈值: {threshold:.3f} mg/L ({status})")
    #90.0% 预警阈值: 1.385 mg/L (达标)
    #95.0% 预警阈值: 1.661 mg/L (达标)
    #99.0% 预警阈值: 2.263 mg/L (超标)
    #环境监测意义: 预警系统设计和合规管理

    示例5:设备寿命保证期确定

    设备寿命分布Gamma(k=2.5, θ=1000小时)
    k_life, theta_life = 2.5, 1000
    warranty_failure_rates = [0.01, 0.05, 0.10]  # 允许的保修期内故障率

    基于不同故障率要求的保修期:
    for fr in warranty_failure_rates:
        warranty_period = gaminv(fr, k_life, theta_life)
        print(f"{fr * 100}% 故障率对应的保修期: {warranty_period:.0f} 小时")
    #1.0% 故障率对应的保修期: 277 小时
    #5.0% 故障率对应的保修期: 573 小时
    #10.0% 故障率对应的保修期: 805 小时

    计算可靠性寿命指标
    b10_life = gaminv(0.10, k_life, theta_life)  # B10寿命
    median_life = gaminv(0.50, k_life, theta_life)  # 中位寿命

    print(f"B10寿命 (10%故障): {b10_life:.0f} 小时")
    print(f"中位寿命: {median_life:.0f} 小时")
    #B10寿命 (10%故障): 805 小时
    #中位寿命: 2176 小时
    #可靠性工程意义: 保修策略和产品寿命规划

    示例6:预防性维护间隔优化

    故障时间分布Gamma(k=3, θ=500小时)
    k_maintenance, theta_maintenance = 3.0, 500
    maintenance_strategies = {
        "保守策略": 0.10,  # 10%故障风险
        "均衡策略": 0.20,  # 20%故障风险
        "经济策略": 0.30  # 30%故障风险
    }

    不同维护策略下的维护间隔:
    for strategy, risk in maintenance_strategies.items():
        interval = gaminv(risk, k_maintenance, theta_maintenance)
        print(f"{strategy}: {interval:.0f} 小时 (故障风险: {risk * 100}%)")
    #保守策略: 551 小时 (故障风险: 10.0%)
    #均衡策略: 768 小时 (故障风险: 20.0%)
    #经济策略: 957 小时 (故障风险: 30.0%)

    计算成本最优维护间隔
    preventive_cost = 1000  # 预防性维护成本
    corrective_cost = 5000  # 故障修复成本
    best_risk = preventive_cost / corrective_cost  # 成本最优风险水平
    optimal_interval = gaminv(best_risk, k_maintenance, theta_maintenance)

    print(f"成本最优维护间隔: {optimal_interval:.0f} 小时 (风险: {best_risk * 100:.1f}%)")
    #成本最优维护间隔: 768 小时 (风险: 20.0%)
    #维护工程意义: 基于风险的维护优化

    示例7:库存安全水平计算

    需求分布Gamma(k=6, θ=100单位/周)
    k_demand, theta_demand = 6.0, 100
    service_levels = [0.90, 0.95, 0.98, 0.99]  # 服务水平

    lead_time = 2  # 提前期2周
    average_demand = k_demand * theta_demand

    print(f"平均周需求: {average_demand:.0f} 单位")
    #平均周需求: 600 单位

    不同服务水平下的安全库存:

    for sl in service_levels:
        demand_during_lead_time = gaminv(sl, k_demand * lead_time, theta_demand)
        safety_stock = demand_during_lead_time - average_demand * lead_time
        print(f"{sl * 100}% 服务水平: 安全库存 = {safety_stock:.0f} 单位")
    #90.0% 服务水平: 安全库存 = 460 单位
    #95.0% 服务水平: 安全库存 = 621 单位
    #98.0% 服务水平: 安全库存 = 814 单位
    #99.0% 服务水平: 安全库存 = 949 单位
    #供应链意义: 库存优化和服务水平管理

    示例8:供应商交货时间可靠性

    交货时间分布Gamma(k=4, θ=2天)
    k_delivery, theta_delivery = 4.0, 2
    promised_delivery = 10  # 承诺交货时间10天

    计算按时交货概率
    on_time_prob = st.gamma.cdf(promised_delivery, k_delivery, scale=theta_delivery)

    计算可靠交货时间
    reliable_levels = [0.90, 0.95, 0.99]
    print(f"承诺交货时间: {promised_delivery} 天")
    print(f"按时交货概率: {on_time_prob:.1%}")
    #承诺交货时间: 10 天
    #按时交货概率: 73.5%

    可靠交货时间估计:

    for level in reliable_levels:
        reliable_time = gaminv(level, k_delivery, theta_delivery)
        print(f"{level * 100}% 可靠度: {reliable_time:.1f} 天")
    #90.0% 可靠度: 13.4 天
    #95.0% 可靠度: 15.5 天
    #99.0% 可靠度: 20.1 天
    #采购管理意义: 供应商绩效评估和采购决策

    示例9:医疗资源需求规划

    病人住院时间分布Gamma(k=3, θ=4天)
    k_hospital, theta_hospital = 3.0, 4
    occupancy_levels = [0.80, 0.90, 0.95]  # 床位占用率目标

    average_stay = k_hospital * theta_hospital
    print(f"平均住院时间: {average_stay:.1f} 天")
    #平均住院时间: 12.0 天

    计算满足不同占用率目标的床位需求
    daily_admissions = 20  # 每日入院人数

    基于不同占用率目标的床位需求:

    for occupancy in occupancy_levels:
        # 计算住院时间分位数
        stay_percentile = gaminv(occupancy, k_hospital, theta_hospital)
        # 估算床位需求
        bed_requirement = daily_admissions * stay_percentile
        print(f"{occupancy * 100}% 占用率: {bed_requirement:.0f} 张床位")
    #80.0% 占用率: 342 张床位
    #90.0% 占用率: 426 张床位
    #95.0% 占用率: 504 张床位
    #医疗管理意义: 资源规划和效率优化

    示例10:疾病治疗时间分析

    治疗时间分布Gamma(k=5, θ=7天)
    k_treatment, theta_treatment = 5.0, 7
    recovery_probabilities = [0.50, 0.75, 0.90, 0.95]

    患者康复时间预测:
    for prob in recovery_probabilities:
        recovery_time = gaminv(prob, k_treatment, theta_treatment)
        print(f"{prob * 100}% 患者将在 {recovery_time:.0f} 天内康复")
    #50.0% 患者将在 33 天内康复
    #75.0% 患者将在 44 天内康复
    #90.0% 患者将在 56 天内康复
    #95.0% 患者将在 64 天内康复

    计算治疗计划时间
    treatment_plan = gamma_inverse_ppf(f"0.95, {k_treatment}, {theta_treatment}")
    print(f"治疗计划时间(95%把握): {treatment_plan:.0f} 天")
    #治疗计划时间(95%把握): 64 天
    #临床意义: 治疗计划制定和患者沟通

    示例11:置信区间计算

    从样本数据估计参数后计算置信区间
    np.random.seed(42)
    true_k, true_theta = 2.5, 1.2
    sample_data = st.gamma.rvs(a=true_k, scale=true_theta, size=100)

    参数估计(使用矩估计法简化)
    sample_mean = np.mean(sample_data)
    sample_var = np.var(sample_data)
    k_est = sample_mean ** 2 / sample_var
    theta_est = sample_var / sample_mean

    计算置信区间
    alpha = 0.05
    lower_ci = gaminv(alpha / 2, k_est, theta_est)
    upper_ci = gaminv(1 - alpha / 2, k_est, theta_est)

    print(f"样本均值: {sample_mean:.3f}, 样本方差: {sample_var:.3f}")
    print(f"估计参数: k={k_est:.3f}, θ={theta_est:.3f}")
    print(f"95% 置信区间: [{lower_ci:.3f}, {upper_ci:.3f}]")
    print(f"真实均值: {true_k * true_theta:.3f} (包含在置信区间内: {lower_ci <= true_k * true_theta <= upper_ci})")
    #样本均值: 2.905, 样本方差: 2.662
    #估计参数: k=3.171, θ=0.916
    #95% 置信区间: [0.635, 6.867]
    #真实均值: 3.000 (包含在置信区间内: True)
    #统计推断意义: 参数估计的不确定性量化

    示例12:假设检验临界值

    单侧检验的临界值计算
    significance_level = 0.05
    k_null, theta_null = 2.0, 1.0  # 零假设参数

    critical_value = gaminv(1 - significance_level, k_null, theta_null)
    print(f"显著性水平 {significance_level} 的单侧检验临界值: {critical_value:.3f}")
    #显著性水平 0.05 的单侧检验临界值: 4.744
    #假设检验意义: 检验决策规则的制定
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import scipy.stats as st
    import sympy as sp


    def gamma_inverse_ppf(input_str):
        """
        Gamma分布逆累积分布函数(分位数函数),对标MATLAB的gaminv函数

        参数:
        p : float/array_like
            累积概率值,范围需在[0,1]之间
        a : float/array_like
            形状参数(shape parameter),必须为正数
        scale : float/array_like, 可选
            尺度参数(scale parameter),默认为1,必须为正数

        返回:
        ndarray : 对应的分位数值,形状与输入广播后的形状一致
        如果出错返回包含错误信息的字符串

        示例:
        >>> # 计算单个分位数
        >>> gamma_inverse_ppf(0.5, 2, 1)
        1.678346990016661

        >>> # 计算多个分位数(向量化计算)
        >>> gamma_inverse_ppf([0.1, 0.5, 0.9], 2, 1)
        array([0.53181161, 1.67834699, 3.88972044])

        >>> # 处理不同形状的输入
        >>> gamma_inverse_ppf([[0.1], [0.9]], [[2, 3]], 1)
        array([[0.53181161, 0.74008317],
               [3.88972044, 5.41908035]])
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            if isinstance(expr, tuple):
                if len(expr) == 3:
                    p = expr[0]
                    a = expr[1]
                    scale = expr[2]
                elif len(expr) == 2:
                    p = expr[0]
                    a = expr[1]
                    scale = 1
                else:
                    error = True

                if isinstance(p, list):
                    p = sp.Matrix(p)

                if isinstance(a, list):
                    a = sp.Matrix(a)

                if isinstance(scale, list):
                    scale = sp.Matrix(scale)

                # 将输入转换为numpy数组并进行广播
                p_arr, a_arr, scale_arr = np.broadcast_arrays(
                    np.asarray(p, dtype=float),
                    np.asarray(a, dtype=float),
                    np.asarray(scale, dtype=float)
                )

                # 参数有效性检查
                if np.any((p_arr < 0) | (p_arr > 1)):
                    raise ValueError("概率值p必须在[0, 1]范围内")
                if np.any(a_arr <= 0):
                    raise ValueError("形状参数a必须为正数")
                if np.any(scale_arr <= 0):
                    raise ValueError("尺度参数scale必须为正数")

                # 初始化结果数组
                result = np.empty_like(p_arr, dtype=float)

                # 向量化计算分位数
                for index in np.ndindex(p_arr.shape):
                    result[index] = st.gamma.ppf(
                        q=p_arr[index],
                        a=a_arr[index],
                        scale=scale_arr[index]
                    )
                if result.size == 1:
                    result = float(result)
                else:
                    result = sp.Matrix(result.tolist())
            else:
                error = True

            return result if not error else f"输入错误: {input_str}"

        except Exception as e:
            return f"错误:{e}"


    # 示例测试
    if __name__ == "__main__":
        # 测试用例1:标量输入
        print("标量输入测试:")
        print(gamma_inverse_ppf("0.5, 3, 5"))
        # 13.370301568617794

        # 测试用例2:向量输入
        print("\n向量输入测试:")
        print(gamma_inverse_ppf("[0.1, 0.5, 0.9], 2"))
        # Matrix([[0.531811608389612],
        #         [1.67834699001666],
        #         [3.88972016986743]])

        # 测试用例3:广播测试
        print("\n广播测试:")
        print(gamma_inverse_ppf("[[0.1], [0.9]], [[2, 3]]"))
        # Matrix([[0.531811608389612, 1.10206532824932],
        #         [3.88972016986743, 5.32232033783421]])
    
    
    伽玛分布的负对数似然函数

    nlogL=gamlike(params,data)返回给定数据的参数params的gamma对数似然的负值. params(1)=A,形状参数,params(2)=B,比例参数。params中的参数必须全部为正.

    示例1:保险索赔金额建模

    模拟保险索赔数据(单位:万元)
    np.random.seed(42)
    claims_data = np.random.gamma(shape=2.5, scale=1.2, size=100)

    假设我们已经通过某种方法得到了参数估计
    estimated_params = [2.3, 1.1]  # [形状参数, 尺度参数]

    计算负对数似然值(衡量模型拟合优度)
    nll = gamlike(estimated_params, claims_data)
    print(f"索赔数据负对数似然值: {nll}")
    #索赔数据负对数似然值: 183.46245646722977

    比较不同参数模型的拟合效果
    alt_params1 = [2.0, 1.0]
    alt_params2 = [3.0, 1.5]

    nll1 = gamlike(alt_params1, claims_data)
    nll2 = gamlike(alt_params2, claims_data)

    print(f"参数{alt_params1}的负对数似然: {nll1}")
    print(f"参数{alt_params2}的负对数似然: {nll2}")
    #参数[2.0, 1.0]的负对数似然: 199.76099175588814
    #参数[3.0, 1.5]的负对数似然: 203.11551575829495
    #负对数似然值越小,说明模型拟合越好

    示例2:设备寿命分析

    模拟设备故障时间数据(单位:小时)
    failure_times = [125, 89, 156, 203, 78, 145, 167, 198, 112, 134]

    不同维护策略下的参数估计
    strategy_a = [2.8, 45]  # 策略A:定期维护
    strategy_b = [3.2, 38]  # 策略B:预测性维护

    nll_a = gamlike(strategy_a, failure_times)
    nll_b = gamlike(strategy_b, failure_times)

    print(f"策略A(定期维护)负对数似然: {nll_a}")
    print(f"策略B(预测性维护)负对数似然: {nll_b}")
    #策略A(定期维护)负对数似然: 54.75534678188527
    #策略B(预测性维护)负对数似然: 54.40380198332201

    if nll_a < nll_b:
        print("策略A的模型拟合更好")
    else:
        print("策略B的模型拟合更好")
    #策略B的模型拟合更好

    示例3:降雨量建模

    某地区月降雨量数据(单位:mm)
    monthly_rainfall = [45.2, 78.9, 123.4, 156.7, 89.1, 67.8,
                        34.5, 56.7, 98.9, 112.3, 145.6, 87.9]

    不同季节的参数(春、夏、秋、冬)
    seasonal_params = [
        [2.5, 35],  # 春季
        [3.2, 45],  # 夏季
        [2.8, 40],  # 秋季
        [2.0, 25]  # 冬季
    ]

    计算每个季节模型对全年数据的拟合程度
    for i, params in enumerate(seasonal_params):
        season_name = ["春季", "夏季", "秋季", "冬季"][i]
        nll = gamlike(params, monthly_rainfall)
        print(f"{season_name}模型负对数似然: {nll:.2f}")
    #春季模型负对数似然: 61.76
    #夏季模型负对数似然: 64.34
    #秋季模型负对数似然: 61.98
    #冬季模型负对数似然: 68.03

    示例4:住院时间分析

    不同科室病人住院天数
    surgery_days = [5, 7, 3, 8, 6, 4, 9, 5, 7, 6]
    internal_days = [10, 8, 12, 9, 11, 7, 13, 10, 9, 11]

    两个科室的参数估计
    surgery_params = [6.0, 1.2]  # 外科
    internal_params = [10.0, 1.1]  # 内科

    计算各自模型的拟合优度
    nll_surgery = gamlike(surgery_params, surgery_days)
    nll_internal = gamlike(internal_params, internal_days)

    print(f"外科模型负对数似然: {nll_surgery:.2f}")
    print(f"内科模型负对数似然: {nll_internal:.2f}")
    #外科模型负对数似然: 21.54
    #内科模型负对数似然: 22.62

    交叉验证:用外科模型拟合内科数据
    cross_nll = gamlike(surgery_params, internal_days)
    print(f"外科模型拟合内科数据的负对数似然: {cross_nll:.2f}")
    #外科模型拟合内科数据的负对数似然: 27.79
    #交叉验证值明显更大,说明模型不适用于不同分布的数据

    示例5:参数优化过程

    模拟数据
    data = np.random.gamma(shape=3.0, scale=2.0, size=50).tolist()

    测试不同的形状参数
    shape_values = [1.5, 2.0, 2.5, 3.0, 3.5, 4.0]
    scale_fixed = 2.0

    固定尺度参数=2.0,测试不同形状参数的拟合效果:
    for shape in shape_values:
        params = [shape, scale_fixed]
        nll = gamlike(params, data)
        print(f"形状参数={shape}, 负对数似然={nll:.2f}")
    #形状参数=1.5, 负对数似然=148.73
    #形状参数=2.0, 负对数似然=132.18
    #形状参数=2.5, 负对数似然=123.83
    #形状参数=3.0, 负对数似然=121.67
    #形状参数=3.5, 负对数似然=124.48
    #形状参数=4.0, 负对数似然=131.44

    找到最佳参数(最小负对数似然)
    best_shape = min(shape_values, key=lambda s: gamlike([s, 2.0], data))
    print(f"\n最佳形状参数: {best_shape}")
    #最佳形状参数: 3.0

    示例6:异常检测

    正常数据(设备正常运行时的能耗)
    normal_energy = [25.1, 26.3, 24.8, 25.7, 26.1, 25.4, 25.9, 24.7, 26.2, 25.5]

    拟合正常数据的Gamma分布参数
    normal_params = [25.0, 1.0]  # 假设已通过MLE估计得到

    测试数据点(包含正常和异常)
    test_points = [25.3, 26.1, 35.8, 24.9, 40.2, 25.6]

    测试点的负对数似然(值越大越可能是异常):
    for point in test_points:
        nll = gamlike(normal_params, [point]")
        print(f"能耗{point}kW: 负对数似然={nll:.2f}")
    #能耗25.3kW: 负对数似然=2.55
    #能耗26.1kW: 负对数似然=2.60
    #能耗35.8kW: 负对数似然=4.71
    #能耗24.9kW: 负对数似然=2.53
    #能耗40.2kW: 负对数似然=6.33
    #能耗25.6kW: 负对数似然=2.56

    设置阈值
    threshold = 5.0
    anomalies = [pt for pt in test_points if gamlike(normal_params, [pt]) > threshold]
    print(f"\n检测到的异常值: {anomalies}")
    #检测到的异常值: [40.2]
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import scipy.stats as st


    def gamma_neg_log_like(params, data):
        """
        计算Gamma分布的负对数似然,对标MATLAB的gamlike函数

        参数:
        params : tuple/list/array_like
            包含形状参数(shape)和尺度参数(scale)的数组,格式为[shape, scale]
        data : list/array_like
            观测数据样本,所有值必须为正数

        返回:
        float: 负对数似然值
        如果出错返回包含错误信息的字符串

        示例:
        >>> # MATLAB等效调用:gamlike([2, 1], [1.2, 0.8, 2.3])
        >>> params = [2, 1]
        >>> data = [1.2, 0.8, 2.3]
        >>> gamma_neg_log_like(params, data)
        3.876492512616387
        """
        try:
            # 参数类型转换和验证
            params = np.asarray(params, dtype=float)
            data = np.asarray(data, dtype=float)

            # 检查参数维度
            if params.size != 2:
                raise ValueError("参数必须包含两个元素:[形状参数, 尺度参数]")

            # 解包参数
            shape, scale = params[0], params[1]

            # 参数有效性检查
            if shape <= 0 or scale <= 0:
                raise ValueError("形状参数和尺度参数必须大于0")
            if np.any(data <= 0):
                raise ValueError("所有数据值必须为正数")

            # 计算对数似然
            log_pdf = st.gamma.logpdf(data, a=shape, scale=scale)
            return -np.sum(log_pdf)

        except Exception as e:
            return f"错误: {e}"


    # 示例测试
    if __name__ == "__main__":
        # 测试用例1:正常情况
        data = [1.2, 0.8, 2.3, 1.5]
        params = [2.0, 1.0]
        print(f"测试1结果: {gamma_neg_log_like(params, data)}")
        # 4.602447763476986

        # 测试用例2:多参数维度测试
        matrix_params = [[2.0, 1.0], [3.0, 0.5]]  # 两组不同参数
        print(f"\n测试4结果: {[gamma_neg_log_like(p, data) for p in matrix_params]}")
        # [4.602447763476986, 3.6597180824744107]
    
    
    Y = gamma(X) 返回在X的元素处计算的gamma函数值.

    X是标量,向量,矩阵,多维数组

    示例1:概率论与组合数学

    1.1 计算阶乘(Gamma(n+1) = n!)

    for n in [5, 10, 15]:
        factorial_gamma = gamma(n + 1)
        print(f"Gamma({n + 1}) = {factorial_gamma}  (等价于 {n}! = {np.math.factorial(n)})")
    #Gamma(6) = (119.99999999999987+0j)  (等价于 5! = 120)
    #Gamma(11) = (3628800.0000000084+0j)  (等价于 10! = 3628800)
    #Gamma(16) = (1307674368000.003+0j)  (等价于 15! = 1307674368000)

    1.2 计算二项式系数 C(n, k) = n!/(k!(n-k)!) = Gamma(n+1)/(Gamma(k+1)*Gamma(n-k+1))

    n, k = 10, 3
    binomial_coeff = (gamma(n + 1) /
                      (gamma(k + 1) * gamma(n - k + 1)))
    print(f"C({n}, {k}) = {binomial_coeff}")
    #C(10, 3) = 120.00000000000061

    1.3 计算半整数的Gamma值(在概率分布中常见)

    half_integers = [0.5, 1.5, 2.5, 3.5]
    for x in half_integers:
        result = gamma(x)
        print(f"Gamma({x}) = {result}")
    #Gamma(0.5) = 1.7724538509055134
    #Gamma(1.5) = 0.8862269254527566
    #Gamma(2.5) = 1.3293403881791352
    #Gamma(3.5) = 3.323350970447838

    示例2:统计学中的分布函数

    2.1 Gamma分布的归一化常数

    def gamma_pdf(x, alpha, beta):
        """Gamma分布的概率密度函数"""
        return (beta ** alpha / gamma(alpha)) * x ** (alpha - 1) * np.exp(-beta * x)

    alpha, beta = 3, 2
    x_values = np.linspace(0.1, 5, 100)
    pdf_values = [gamma_pdf(x, alpha, beta) for x in x_values]

    print(f"Gamma分布PDF在alpha={alpha}, beta={beta}时的归一化常数: 1/Gamma({alpha}) = {1 / gamma(str(alpha))}")
    #Gamma分布PDF在alpha=3, beta=2时的归一化常数: 1/Gamma(3) = 0.5000000000000009

    2.2 学生t分布的归一化常数

    def student_t_constant(nu):
        """学生t分布的归一化常数"""
        return gamma((nu+1)/2) / (np.sqrt(nu * np.pi) * gamma(nu / 2))

    degrees_freedom = [1, 5, 10, 30]

    学生t分布的归一化常数:
    for nu in degrees_freedom:
        const = student_t_constant(nu)
        print(f"自由度 ν={nu}: 归一化常数 = {const}")
    #自由度 ν=1: 归一化常数 = 0.3183098861837912
    #自由度 ν=5: 归一化常数 = 0.37960668982249435
    #自由度 ν=10: 归一化常数 = 0.3891083839660311
    #自由度 ν=30: 归一化常数 = 0.39563218489409696

    示例3:工程与物理学应用

    3.1 计算球体的超体积(n维球体体积公式包含Gamma函数)

    def n_sphere_volume(n, R):
        """计算n维球体的体积"""
        return (np.pi ** (n / 2) * R ** n) / gamma(n / 2 + 1)

    n维球体体积计算:
    dimensions = [2, 3, 4, 5]  # 2维圆,3维球,4维超球等
    radius = 1.0
    for n in dimensions:
        volume = n_sphere_volume(n, radius)
        print(f"{n}维球体体积 (R=1): {volume:.4f}")
    #2维球体体积 (R=1): 3.1416
    #3维球体体积 (R=1): 4.1888
    #4维球体体积 (R=1): 4.9348
    #5维球体体积 (R=1): 5.2638

    3.2 量子力学中的波函数归一化

    def hydrogen_wavefunction_constant(n, l):
        """氢原子波函数的归一化常数"""
        # 简化公式,实际公式更复杂
        return np.sqrt(gamma(n - l) / gamma(n + l + 1))

    氢原子波函数归一化常数:
    quantum_numbers = [(1, 0), (2, 0), (2, 1), (3, 1)]
    for n, l in quantum_numbers:
        const = hydrogen_wavefunction_constant(n, l)
        print(f"主量子数n={n}, 角量子数l={l}: 归一化常数 ≈ {const:.4f}")
    #主量子数n=1, 角量子数l=0: 归一化常数 ≈ 1.0000
    #主量子数n=2, 角量子数l=0: 归一化常数 ≈ 0.7071
    #主量子数n=2, 角量子数l=1: 归一化常数 ≈ 0.4082
    #主量子数n=3, 角量子数l=1: 归一化常数 ≈ 0.2041

    示例4:金融数学应用

    4.1 Black-Scholes模型中的Gamma(二阶导数)

    def black_scholes_gamma(S, K, T, r, sigma):
        """计算期权定价的Gamma值"""
        from scipy.stats import norm
        d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
        return norm.pdf(d1) / (S * sigma * np.sqrt(T))

    虽然这里用的是正态分布,但Gamma函数在更复杂的衍生品定价中出现

    4.2 风险度量中的极端值理论

    def extreme_value_constant(shape_param):
        """极值分布中的常数项(包含Gamma函数)"""
        if shape_param != 0:
            return gamma(1 - shape_param)
        else:
            return 1.0  # Gumbel分布情况

    shape_params = [-0.5, 0, 0.3]

    极值分布中的Gamma函数应用:
    for xi in shape_params:
        const = extreme_value_constant(xi)
        print(f"形状参数 ξ={xi}: 相关常数 = {const}")
    #形状参数 ξ=-0.5: 相关常数 = 0.8862269254527566+
    #形状参数 ξ=0: 相关常数 = 1.0
    #形状参数 ξ=0.3: 相关常数 = 1.2980553326475577

    示例5:数值分析与特殊函数

    5.1 计算Beta函数 B(x,y) = Gamma(x)Gamma(y)/Gamma(x+y)

    def beta_function(x, y):
        """Beta函数计算"""
        return (gamma(x) * gamma(y)) / gamma(x + y)

    Beta函数计算:
    pairs = [(2, 3), (0.5, 0.5), (3, 4)]
    for x, y in pairs:
        beta_val = beta_function(x, y)
        print(f"B({x}, {y}) = {beta_val:.4f}")
    #B(2, 3) = 0.0833
    #B(0.5, 0.5) = 3.1416
    #B(3, 4) = 0.0167

    5.2 不完全Gamma函数的相关计算

    def incomplete_gamma_ratio(a, x):
        """计算Gamma(a,x)/Gamma(a)的近似(用于不完全Gamma函数)"""
        # 简化版本,实际需要更复杂的数值方法
        return 1 - np.exp(-x) * x ** a / (gamma(a) * a)

    不完全Gamma函数相关计算:

    parameters = [(2, 1), (3, 2), (0.5, 0.1)]
    for a, x in parameters:
        ratio = incomplete_gamma_ratio(a, x)
        print(f"P({a}, {x}) ≈ {ratio:.4f}  (正则化不完全Gamma函数)")
    #P(2, 1) ≈ 0.8161+0.0000j  (正则化不完全Gamma函数)
    #P(3, 2) ≈ 0.8196+0.0000j  (正则化不完全Gamma函数)
    #P(0.5, 0.1) ≈ 0.6771+0.0000j  (正则化不完全Gamma函数)

    示例6:符号计算与数学恒等式

    6.1 反射公式: Gamma(z)Gamma(1-z) = π/sin(πz)

    z_values = [0.25, 0.33, 0.5, 0.75]

    Gamma函数反射公式验证:
    for z in z_values:
        left_side = gamma(z) * gamma(1 - z)
        right_side = np.pi / np.sin(np.pi * z)
        print(f"z={z}: Gamma({z})*Gamma({1 - z}) = {left_side:.6f}")
        print(f"        π/sin(π{z}) = {right_side:.6f}")
        print(f"        差值: {abs(left_side - right_side):.2e}")
    #z=0.25: Gamma(0.25)*Gamma(0.75) = 4.442883+0.000000j
        π/sin(π0.25) = 4.442883
        差值: 8.88e-16
    #z=0.33: Gamma(0.33)*Gamma(0.6699999999999999) = 3.649866+0.000000j
        π/sin(π0.33) = 3.649866
        差值: 4.44e-15
    #z=0.5: Gamma(0.5)*Gamma(0.5) = 3.141593+0.000000j
        π/sin(π0.5) = 3.141593
        差值: 8.88e-15
    #z=0.75: Gamma(0.75)*Gamma(0.25) = 4.442883+0.000000j
        π/sin(π0.75) = 4.442883
        差值: 8.88e-16

    6.2 递推关系: Gamma(z+1) = z * Gamma(z)

    recurrence = gamma(z + 1) - symbolic_z * gamma(z)
    print(f"Gamma(z+1) - z*Gamma(z) = {recurrence} (应该为0)")
    #Gamma(z+1) - z*Gamma(z) = 0 (应该为0)

    示例7:实际数据分析应用

    7.1 拟合Gamma分布参数的最大似然估计

    def gamma_mle_equations(data):
        """Gamma分布参数估计的方程(包含Gamma函数)"""
        n = len(data)
        mean_log = np.mean(np.log(data))
        mean_data = np.mean(data)

        # 最大似然方程涉及Gamma函数的导数(Digamma函数)
        # 这里简化显示Gamma函数的作用
        print("Gamma分布在参数估计中的作用:")
        print(f"样本大小: {n}")
        print(f"数据均值: {mean_data:.4f}")
        print(f"对数均值: {mean_log:.4f}")
        print("MLE方程涉及Gamma函数的对数导数")


    # 模拟等待时间数据(通常服从Gamma分布)
    waiting_times = np.random.gamma(shape=2.5, scale=1.0, size=100)
    gamma_mle_equations(waiting_times)
    #样本大小: 100
    #数据均值: 2.4858
    #对数均值: 0.7186
    #MLE方程涉及Gamma函数的对数导数
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    from scipy.special import gamma


    def gamma_compute(input_str):
        """
        对标 MATLAB 的 gamma 函数,支持标量、矩阵和符号计算。

        参数:
        input_str: 输入的数学表达式字符串。

        返回:
        计算结果或错误信息字符串。

        示例:
        >>> gamma_compute("5")
        24.0
        >>> gamma_compute("Matrix([[1, 2], [3, 4]])")
        Matrix([[1, 1], [2, 6]])
        >>> gamma_compute("x + 1")
        x*gamma(x)
        >>> gamma_compute("invalid")
        '错误: ...'
        """
        try:
            expr = sp.sympify(input_str)
            # 数值处理分支
            if expr.is_number:
                z = complex(expr)
                return gamma(z)

            # 符号表达式处理分支
            elif expr.free_symbols:
                return sp.expand_func(sp.gamma(expr))

            # 未知类型处理
            else:
                return f"无法处理的输入类型: {input_str}"

        except Exception as e:
            return f"错误: {e}"


    # 示例测试
    if __name__ == "__main__":
        # 标量测试
        print(gamma_compute("2.5"))
        # (1.3293403881791352+0j)

        # 符号测试
        print(gamma_compute("x + 1"))
        # x*gamma(x)
    
    
    正则化不完全gamma函数

    Y = gammainc(X,A) 返回在 X 和 A 的元素处计算的正则化下不完全 gamma 函数。X 和 A 必须都为实数,A 必须为非负值.

    Y = gammainc(X,A,type) 返回正则化下/上不完全 gamma 函数。type 的选项是 'lower'(默认值)和 'upper'.

    X是标量,向量,矩阵,多维数组

    A是标量,向量,矩阵. 多维数组, A的元素必须为非负实数.X和A必须大小相同,或者其中之一必须为标量.

    type是正则化不完全gamma函数的类型,upper或lower(默认)

    示例1. 通信系统中的误码率计算

    Q函数与上不完全伽马函数的关系:Q(x) = 0.5 * Γ(0.5, x²/2)

    def q_function(x):
        """计算Q函数(标准正态分布的右尾概率)"""
        return 0.5 * gammainc(0.5, x**2/2, upper)

    测试Q函数
    print("Q(1) =", q_function(1))
    print("Q(2) =", q_function(2))
    #Q(1) = 0.282094791773878*uppergamma(0.5, x**2/2)
    #Q(2) = 0.282094791773878*uppergamma(0.5, x**2/2)

    BPSK调制的误码率
    def bpsk_ber(snr_db):
        """计算BPSK调制的误码率"""
        snr_linear = 10 ** (snr_db / 10)
        return q_function(sp.sqrt(2 * snr_linear))

    print("BPSK BER at SNR=10dB:", bpsk_ber(10))
    #BPSK BER at SNR=10dB: 0.282094791773878*uppergamma(0.5, x**2/2)

    示例2. 统计学中的卡方分布

    卡方分布的累积分布函数
    def chi_squared_cdf(x, k):
        """自由度为k的卡方分布CDF"""
        # P(X ≤ x) = γ(k/2, x/2) / Γ(k/2)
        return gammainc(k/2, x/2, lower)


    计算卡方分布的p值
    def chi_squared_p_value(x, k):
        """卡方检验的p值"""
        return 1 - chi_squared_cdf(x, k)

    假设检验示例
    chi2_statistic = 15.0  # 卡方统计量
    degrees_freedom = 10  # 自由度

    p_value = chi_squared_p_value(chi2_statistic, degrees_freedom)
    print(f"卡方统计量={chi2_statistic}, 自由度={degrees_freedom}")
    print(f"p值 = {p_value}")
    #卡方统计量=15.0, 自由度=10
    #p值 = 0.1320618562877206

    临界值计算(近似)
    critical_value_95 = 18.3  # 95%置信水平的临界值
    if chi2_statistic > critical_value_95:
        print("拒绝原假设")
    else:
        print("不能拒绝原假设")
    #不能拒绝原假设

    示例3. 矩阵输入的批量计算

    创建测试矩阵
    a_matrix = [[1, 2], [3, 4]]
    x_matrix = [[0.5, 1.5], [2.5, 3.5]]

    矩阵形式的下不完全伽马函数
    result_lower = gammainc(a_matrix, x_matrix, lower)

    下不完全伽马函数(矩阵):
    print(result_lower)
    #[[0.39346934 0.4421746 ]
      [0.45618688 0.46336733]]

    矩阵形式的上不完全伽马函数
    result_upper = gammainc(a_matrix, x_matrix, upper)

    上不完全伽马函数(矩阵):
    print(result_upper)
    #[[0.60653066 0.5578254 ]
      [0.54381312 0.53663267]]

    示例4. 符号计算应用

    符号计算示例

    基本符号表达式
    symbolic_result = gammainc(a, x, lower)
    print(f"Γ(a, x)/Γ(a) = {symbolic_result}")
    #Γ(a, x)/Γ(a) = lowergamma(a, x)/gamma(a)

    特定参数情况
    specific_case = gammainc(n+1, x, lower)
    print(f"Γ(n+1, x)/Γ(n+1) = {specific_case}")
    #Γ(n+1, x)/Γ(n+1) = lowergamma(n + 1, x)/gamma(n + 1)

    半整数参数(常见于物理问题)
    half_integer = gammainc(3/2, x, upper)
    print(f"Γ(3/2, x)/Γ(3/2) = {half_integer}")
    #Γ(3/2, x)/Γ(3/2) = 1.12837916709551*uppergamma(3/2, x)

    示例5. 金融风险管理中的应用

    伽马分布在金融风险建模中的应用
    def gamma_var(alpha, beta, confidence_level=0.95):
        """基于伽马分布的风险价值计算"""
        # VaR = F⁻¹(confidence_level),其中F是伽马分布的CDF
        # 使用不完全伽马函数求逆(这里简化处理)
        return gammainc(alpha, beta*x, lower)

    信用风险模型中的违约概率
    def default_probability(pd, lgd, exposure):
        """简化版的信用风险计算"""
        # 使用伽马分布建模违约损失
        return gammainc(2, pd*exposure, upper) * lgd

    pd = 0.02  # 违约概率
    lgd = 0.6  # 违约损失率
    exposure = 1000000  # 风险暴露
    prob = default_probability(pd, lgd, exposure)
    print(f"预期信用损失: {prob}")
    #预期信用损失: 0.0

    示例6. 物理学中的应用

    黑体辐射的普朗克定律相关计算
    def planck_integral(nu, T):
        """计算黑体辐射的谱辐射出射度(简化版)"""
        # 使用不完全伽马函数计算特定频率范围的辐射
        h = 6.626e-34  # 普朗克常数
        k = 1.381e-23  # 玻尔兹曼常数
        x = h * nu / (k * T)
        return gammainc(f4, x, upper) * (8 * np.pi * k ** 4 * T ** 4) / (h ** 3 * 3.0e8 ** 3)

    计算太阳表面温度下的辐射
    T_sun = 5778  # 开尔文
    nu_visible = 5e14  # 可见光频率
    radiation = planck_integral(nu_visible, T_sun)
    print(f"太阳在可见光频段的辐射出射度: {radiation:.2e} W/m²/Hz")
    #太阳在可见光频段的辐射出射度: 5.25e-02 W/m²/Hz
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import scipy.special as sc


    def gamma_incomplete_function(input_str):
        """
        对标 MATLAB 的 gammainc 函数,计算正则化的下/上不完全伽马函数。

        参数:
        input_str: 输入的数学表达式字符串,格式为元组 (x, a, 'type'),其中 type 可选 'lower' 或 'upper'。

        返回:
        计算结果或错误信息字符串。

        示例:
        >>> gamma_incomplete_function("(2, 5, lower)")
        0.052653017343711
        >>> gamma_incomplete_function("(Matrix([[1,2]]), Matrix([[3,4]]), upper)")
        Matrix([[0.849145, 0.238536]])
        >>> gamma_incomplete_function("(x, a, lower)")
        lowergamma(a, x)/gamma(a)
        """
        try:
            expr = sp.sympify(input_str, evaluate=False)
            error = False
            result = None

            if isinstance(expr, tuple):
                # 解析参数
                if len(expr) == 3:
                    x, a, gammainc_type = expr
                    gammainc_type = str(gammainc_type)
                elif len(expr) == 2:
                    x, a = expr
                    gammainc_type = 'lower'
                else:
                    error = True
                    return f"输入错误: 参数数量错误,期望2或3个参数,实际{len(expr)}个"

                # 检查类型参数有效性
                if gammainc_type not in ['lower', 'upper']:
                    error = True
                    return f"输入错误: 类型参数必须为 'lower' 或 'upper',实际为 {gammainc_type}"

                if gammainc_type == "lower":
                    if any(e.free_symbols for e in [x, a]):
                        result = sp.lowergamma(a, x) / sp.gamma(a)
                    elif all(e.is_number for e in [x, a]):
                        result = sc.gammainc(float(a), float(x))
                else:
                    if any(e.free_symbols for e in [x, a]):
                        result = sp.uppergamma(a, x) / sp.gamma(a)
                    elif all(e.is_number for e in [x, a]):
                        result = sc.gammaincc(float(a), float(x))

                return result
            else:
                return f"输入错误: 输入必须是元组"

        except Exception as e:
            return f"错误: {e}"


    # 示例测试
    if __name__ == "__main__":
        # 标量测试
        print(gamma_incomplete_function("2, 5, lower"))
        # 0.052653017343711125

        print(gamma_incomplete_function("(5, 2, upper)"))
        # 0.04042768199451279

        # 符号测试
        print(gamma_incomplete_function("(x, a, lower)"))
        # lowergamma(a, x)/gamma(a)
    
    
    正则化不完全gamma函数的逆函数

    X = gammaincinv(Y,A)返回在Y和A元素处计算的正则化下不完全gamma函数的逆函数,满足Y = gammainc(X,A). Y和A都必须为实数. Y的元素必须在闭区间[0,1]内,A必须为非负值.

    X = gammaincinv(Y,A,type) 返回正则化下或上不完全gamma函数的逆函数.type的选项是'lower'(默认值)和'upper'.

    Y是标量,向量,矩阵,多维数组

    A是标量,向量,矩阵,多维数组. A的元素必须为非负实数.Y和A必须大小相同,或者其中之一必须为标量.

    type是逆不完全gamma函数的类型,upper或lower(默认)

    示例1. 统计学中的置信区间计算

    卡方分布的临界值计算
    def chi_squared_critical_value(confidence_level, degrees_freedom):
        """
        计算卡方分布的临界值(用于假设检验)
        """
        # P(X ≤ x) = confidence_level => x = gammaincinv(confidence_level, df/2) * 2
        return 2 * gammaincinv(confidence_level, degrees_freedom/2)


    计算95%置信水平的卡方临界值
    df = 10
    critical_value = chi_squared_critical_value(0.95, df)
    print(f"自由度为{df}的卡方分布在95%置信水平的临界值: {critical_value:.4f}")
    #自由度为10的卡方分布在95%置信水平的临界值: 18.3070

    不同自由度下的临界值比较
    degrees = [5, 10, 15, 20]
    conf_levels = [0.90, 0.95, 0.99]

    不同自由度和置信水平的卡方临界值:
    for df in degrees:
        row = []
        for cl in conf_levels:
            cv = chi_squared_critical_value(cl, df)
            row.append(f"{cv:.3f}")
        print(f"自由度{df:2d}: {', '.join(row)}")
    #自由度 5: 9.236, 11.070, 15.086
    #自由度10: 15.987, 18.307, 23.209
    #自由度15: 22.307, 24.996, 30.578
    #自由度20: 28.412, 31.410, 37.566
    #设备寿命的中位数: 267.41 小时

    示例2. 可靠性工程中的寿命预测

    伽马分布的分位数计算
    def gamma_quantile(probability, shape_param, scale_param=1):
        """
        计算伽马分布的分位数(逆CDF)
        F(x) = P(X ≤ x) = γ(α, x/β)/Γ(α)
        => x = β * gammaincinv(P, α)
        """
        return scale_param * gammaincinv(probability, shape_param)

    设备寿命的中位数估计
    shape = 3.0  # 形状参数
    scale = 100  # 尺度参数(平均寿命)

    median_life = gamma_quantile(0.5, shape, scale)
    print(f"设备寿命的中位数: {median_life:.2f} 小时")
    #设备寿命的中位数: 267.41 小时

    计算不同分位点的寿命
    quantiles = [0.1, 0.25, 0.5, 0.75, 0.9, 0.95]

    伽马分布(α=3, β=100)的分位数:
    for q in quantiles:
        life = gamma_quantile(q, shape, scale)
        print(f"P(X ≤ {life:6.2f}) = {q}")
    #P(X ≤ 110.21) = 0.1
    #P(X ≤ 172.73) = 0.25
    #P(X ≤ 267.41) = 0.5
    #P(X ≤ 392.04) = 0.75
    #P(X ≤ 532.23) = 0.9
    #P(X ≤ 629.58) = 0.95

    保修期设计:确定90%设备能存活的时间
    warranty_period = gamma_quantile(0.9, shape, scale)
    print(f"\n建议保修期: {warranty_period:.1f} 小时 (90%设备在此时间内不会故障)")
    #建议保修期: 532.2 小时 (90%设备在此时间内不会故障)

    示例3. 金融风险管理中的VaR计算

    基于伽马分布的风险价值计算
    def gamma_var(shape_param, scale_param, confidence_level=0.95):
        """
        计算伽马分布的风险价值(Value at Risk)
        """
        return gamma_quantile(confidence_level, shape_param, scale_param)

    def gamma_expected_shortfall(shape_param, scale_param, confidence_level=0.95):
        """
        计算伽马分布的预期短缺(Expected Shortfall)
        """
        var_level = gamma_var(shape_param, scale_param, confidence_level)
        # 简化计算:使用条件期望公式
        conditional_shape = shape_param + 1
        conditional_expectation = scale_param * conditional_shape

        # 更精确的计算需要积分,这里使用近似
        return conditional_expectation * (1 - confidence_level) / (1 - confidence_level)

    投资损失分布分析
    shape_loss = 2.5  # 损失分布的形状参数
    scale_loss = 10000  # 损失分布的尺度参数

    var_95 = gamma_var(shape_loss, scale_loss, 0.95)
    var_99 = gamma_var(shape_loss, scale_loss, 0.99)

    投资损失风险分析:
    print(f"95% VaR: ${var_95:,.2f}")
    print(f"99% VaR: ${var_99:,.2f}")
    #95% VaR: $55,352.49
    #99% VaR: $75,431.36

    风险资本分配
    capital_required = var_99 * 1.1  # 附加10%缓冲
    print(f"建议风险资本: ${capital_required:,.2f}")
    #建议风险资本: $82,974.50

    示例4. 医学统计中的生存分析

    生存函数的分位数计算
    def survival_quantile(survival_probability, shape_param, scale_param):
        """
        计算生存时间的分位数(生存分析)
        S(t) = 1 - F(t) = P(T > t)
        => t = gammaincinv(1 - survival_probability, α) * β
        """
        return scale_param * gammaincinv(1 - survival_probability, shape_param)

    癌症患者生存时间分析
    shape_medical = 1.8  # 形状参数
    scale_medical = 24  # 尺度参数(月)

    计算中位生存时间
    median_survival = survival_quantile(0.5, shape_medical, scale_medical)
    print(f"中位生存时间: {median_survival:.1f} 个月")
    #中位生存时间: 35.5 个月

    不同生存概率对应的时间
    survival_probs = [0.9, 0.75, 0.5, 0.25, 0.1]

    患者生存时间分析:
    for prob in survival_probs:
        time = survival_quantile(prob, shape_medical, scale_medical)
        print(f"{prob * 100:2.0f}%患者生存时间超过 {time:5.1f} 个月")
    #90%患者生存时间超过  10.3 个月
    #75%患者生存时间超过  19.6 个月
    #50%患者生存时间超过  35.5 个月
    #25%患者生存时间超过  58.6 个月
    #10%患者生存时间超过  86.1 个月

    临床试验设计:确定观察期
    trial_duration = survival_quantile(0.8, shape_medical, scale_medical)
    print(f"\n建议临床试验观察期: {trial_duration:.1f} 个月 (80%患者在此时间内生存)")
    #建议临床试验观察期: 16.6 个月 (80%患者在此时间内生存)

    示例5. 矩阵输入的批量计算

    批量处理多个概率和参数组合

    多个概率值
    probabilities = [[0.1, 0.5], [0.9, 0.95]]
    shape_params = [[2, 3], [4, 5]]

    result = gammaincinv(probabilities, shape_params)

    逆不完全伽马函数结果矩阵:
    print(result)
    #[[0.53181161 2.67406031]
      [6.68078307 9.15351903]]

    保险精算应用:不同风险等级的分位数
    risk_levels = [0.5, 0.75, 0.9, 0.95, 0.99]
    shape_parameters = [1.5, 2.0, 2.5, 3.0]

    不同风险等级和形状参数的分位数:
    for shape in shape_parameters:
        row = []
        for level in risk_levels:
            quantile = gamma_quantile(level, shape, 1000)
            row.append(f"{quantile:.0f}")
        print(f"α={shape}: {', '.join(row)}")
    #α=1.5: 1183, 2054, 3126, 3907, 5672
    #α=2.0: 1678, 2693, 3890, 4744, 6638
    #α=2.5: 2176, 3313, 4618, 5535, 7543
    #α=3.0: 2674, 3920, 5322, 6296, 8406
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import scipy.special as sc


    def gamma_incomplete_inverse_function(input_str):
        """
        计算逆不完全伽马函数,类似MATLAB的gammaincinv函数。

        参数:
        input_str: 输入的字符串表达式,格式为元组(y, a, 'lower'/'upper')或(y, a)。

        返回:
        标量数值、SymPy矩阵或错误信息字符串。

        示例:
        >>> gamma_incomplete_inverse_function("(0.5, 1)")
        0.6931471806
        >>> gamma_incomplete_inverse_function("([[0.5], [0.6]], [[1], [2]])")
        Matrix([[1.386294361], [1.42711696]])
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            if isinstance(expr, tuple) and len(expr) == 2:

                if all(e.is_number for e in expr):
                    params = tuple(float(e.evalf()) for e in expr)
                    result = sc.gammaincinv(*params[::-1])
                else:
                    error = True
            else:
                error = True

            return result if not error else f"输入错误: {input_str}"


        except Exception as e:
            return f"错误: {e}"


    # 示例测试
    if __name__ == "__main__":
        # 标量测试
        print(gamma_incomplete_inverse_function("0.5, 0.6"))
        # 0.31570201701610756
    
    
    Y = gammaln(A)返回gamma函数的对数gammaln(A)=log(gamma(A)).

    A 必须是非负数和实数. gammaln命令可避免直接使用log(gamma(A))计算时可能会出现的下溢和上溢.

    示例1. 统计学中的最大似然估计

    伽玛分布的对数似然函数
    def gamma_log_likelihood(data, alpha, beta):
        """
        计算伽玛分布的对数似然函数
        """
        n = len(data)
        sum_log_x = sum(log(data))
        sum_x = sum(data)

        # 使用gammaln避免数值溢出
        log_likelihood = (alpha - 1) * sum_log_x - sum_x / beta - n * alpha * log(beta) - n * gammaln(alpha)
        return log_likelihood


    示例数据(模拟伽玛分布数据)
    np.random.seed(42)
    true_alpha, true_beta = 3.0, 2.0
    sample_data = np.random.gamma(true_alpha, true_beta, 100)

    计算不同参数的对数似然
    alpha_values = np.linspace(2.0, 4.0, 50)
    beta_values = np.linspace(1.5, 2.5, 50)
    log_likelihoods = []

    for alpha in alpha_values:
        for beta in beta_values:
            ll = gamma_log_likelihood(sample_data, alpha, beta)
            log_likelihoods.append((alpha, beta, ll))

    找到最大似然估计
    best_fit = max(log_likelihoods, key=lambda x: x[2])
    print(f"真实参数: α={true_alpha}, β={true_beta}")
    print(f"最大似然估计: α={best_fit[0]:.3f}, β={best_fit[1]:.3f}")
    print(f"最大对数似然值: {best_fit[2]:.3f}")
    #真实参数: α=3.0, β=2.0
    #最大似然估计: α=3.918, β=1.500
    #最大对数似然值: -240.090

    示例2. 贝叶斯统计中的模型比较

    计算贝叶斯因子(用于模型比较)
    def bayes_factor_gamma_models(data, alpha1, beta1, alpha2, beta2):
        """
        计算两个伽玛分布模型的贝叶斯因子
        """
        # 模型1的对数边际似然
        log_marginal1 = gamma_log_likelihood(data, alpha1, beta1) + log(1.0)  # 简化先验

        # 模型2的对数边际似然
        log_marginal2 = gamma_log_likelihood(data, alpha2, beta2) + log(1.0)  # 简化先验

        bayes_factor = exp(log_marginal1 - log_marginal2)
        return bayes_factor

    模型比较示例
    model1_params = (2.5, 2.0)  # (α, β)
    model2_params = (3.0, 1.8)  # (α, β)

    bf = bayes_factor_gamma_models(sample_data, *model1_params, *model2_params)
    print(f"贝叶斯因子(模型1/模型2): {bf:.3f}")
    #贝叶斯因子(模型1/模型2): 0.004

    if bf > 1:
        print("证据支持模型1")
    else:
        print("证据支持模型2")
    #证据支持模型2

    示例3. 组合数学和大数计算

    计算大数的组合数对数(避免阶乘溢出)
    def log_combination(n, k):
        """
        计算组合数C(n,k)的自然对数,避免大数阶乘溢出
        """
        if k < 0 or k > n:
            return -inf

        # 使用Gamma函数性质: n! = Gamma(n+1)
        # log(C(n,k)) = log(n!) - log(k!) - log((n-k)!)
        return (gammaln(n + 1) -
                gammaln(k + 1) -
                gammaln(n - k + 1))

    大数组合计算示例
    n_large = 1000
    k_large = 200

    直接计算会溢出,但对数计算可行
    log_comb = log_combination(n_large, k_large)
    print(f"log(C({n_large}, {k_large})) = {log_comb}")
    print(f"C({n_large}, {k_large}) ≈ {np.exp(log_comb):.2e}")
    #log(C(1000, 200)) = 496.9454605977171
    #C(1000, 200) ≈ 6.62e+215

    二项分布的概率质量函数(对数形式)
    def log_binomial_pmf(k, n, p):
        """
        二项分布概率质量函数的对数
        """
        if k < 0 or k > n or p < 0 or p > 1:
            return -inf

        log_comb = log_combination(n, k)
        log_prob = log_comb + k * log(p) + (n - k) * log(1 - p)
        return log_prob

    计算罕见事件的概率
    n_rare = 10000
    p_rare = 0.001
    k_rare = 15

    log_p_rare = log_binomial_pmf(k_rare, n_rare, p_rare)
    print(f"罕见事件概率: P(X={k_rare}) = {exp(log_p_rare):.2e}")
    #罕见事件概率: P(X=15) = 3.47e-02

    示例4. 物理化学中的统计力学应用

    理想气体的熵计算(使用伽玛函数)
    def ideal_gas_entropy(N, V, T, mass):
        """
        计算单原子理想气体的萨库尔-特罗德方程(Sackur-Tetrode)熵
        """
        import scipy.constants as const

        # 热波长
        lambda_thermal = const.h / sqrt(2 * pi * mass * const.k * T)

        # 使用斯特林近似和伽玛函数
        # S = N*k*[ln(V/Nλ³) + 5/2]
        # 更精确的版本涉及伽玛函数

        # 使用gammaln计算精确的构型数对数
        log_omega = (N * log(V) - gammaln(N + 1) +
                     3 * N / 2 * log(2 * pi * mass * const.k * T / const.h ** 2) -
                     3 * N / 2)

        entropy = const.k * log_omega
        return entropy


    # 计算氦气在标准条件下的熵
    N_avogadro = 6.022e23  # 阿伏伽德罗常数
    V_molar = 0.0224  # 标准状况下气体摩尔体积 (m³)
    T_std = 273.15  # 标准温度 (K)
    mass_he = 6.646e-27  # 氦原子质量 (kg)

    S_molar = ideal_gas_entropy(N_avogadro, V_molar, T_std, mass_he)
    print(f"氦气在标准状况下的摩尔熵: {S_molar:.2f} J/(mol·K)")
    #氦气在标准状况下的摩尔熵: 99.27 J/(mol·K)

    示例5. 金融工程中的极值理论

    广义极值分布(GEV)的对数似然
    def gev_log_likelihood(data, mu, sigma, xi):
        """
        广义极值分布的对数似然函数
        """
        n = len(data)
        z = (data - mu) / sigma

        if abs(xi) < 1e-10:  # Gumbel case (xi = 0)
            log_likelihood = -n * log(sigma) - sum(z) - sum(exp(-z))
        else:  # Fréchet or Weibull case (xi ≠ 0)
            # 需要确保1 + xi*z > 0
            valid = 1 + xi * z > 0
            if not all(valid):
                return -inf

            log_likelihood = (-n * log(sigma) -
                              (1 + 1 / xi) * sum(log(1 + xi * z)) -
                              sum((1 + xi * z) ** (-1 / xi)))

        return log_likelihood

    极值风险分析示例(模拟极端损失数据)
    np.random.seed(123)
    extreme_losses = np.random.gumbel(loc=1000, scale=200, size=50)  # 极端损失

    使用gammaln辅助模型选择
    def model_complexity_penalty(k, n):
        """
        计算模型复杂度的惩罚项(使用伽玛函数)
        """
        # BIC近似: 0.5 * k * log(n)
        # 更精确的版本涉及伽玛函数
        return 0.5 * (k * log(n) - 2 * gammaln(k / 2 + 1))

    比较不同复杂度模型
    models = [
        {"name": "简单模型", "params": 2, "log_likelihood": -1500},
        {"name": "复杂模型", "params": 5, "log_likelihood": -1490}
    ]

    n_data = len(extreme_losses)
    for model in models:
        penalty = model_complexity_penalty(model["params"], n_data)
        bic = -2 * model["log_likelihood"] + penalty
        print(f"{model['name']}: BIC = {bic:.1f}")
    #简单模型: BIC = 3003.9
    #复杂模型: BIC = 2988.6

    示例6. 生物信息学中的序列分析

    DNA序列的熵计算(使用伽玛函数进行狄利克雷先验的贝叶斯估计)
    def dna_sequence_entropy(sequence, pseudocount=1):
        """
        计算DNA序列的熵,使用狄利克雷先验进行贝叶斯平滑
        """
        from collections import Counter

        # 计数各碱基出现次数
        counts = Counter(sequence)
        bases = ['A', 'C', 'G', 'T']

        # 添加伪计数(狄利克雷先验)
        total_count = len(sequence)
        alpha = pseudocount  # 对称狄利克雷参数

        # 贝叶斯估计的概率
        probs = {}
        for base in bases:
            count_base = counts.get(base, 0)
            probs[base] = (count_base + alpha) / (total_count + 4 * alpha)

        # 计算熵
        entropy = -sum(p * log(p) for p in probs.values() if p > 0)

        # 使用gammaln计算模型证据(用于模型比较)
        log_evidence = (gammaln(4 * alpha) -
                        4 * gammaln(alpha) +
                        sum(gammaln(counts.get(base, 0) + alpha) for base in bases) -
                        gammaln(total_count + 4 * alpha))

        return entropy, log_evidence

    DNA序列分析示例
    dna_sequence = "ATGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGCTAGC"
    entropy, log_evidence = dna_sequence_entropy(dna_sequence)
    print(f"DNA序列熵: {entropy:.3f}")
    print(f"模型对数证据: {log_evidence:.3f}")
    #DNA序列熵: 1.386
    #模型对数证据: -59.324

    比较不同序列的复杂性
    sequences = [
        "AAAAAATTTTTTGGGGGGCCCCCC",  # 低复杂性
        "ATCGATCGATCGATCGATCGATCG",  # 中等复杂性
        "ATGCTAGCTAGCTAGCTAGCTAGC"  # 高复杂性
    ]

    for i, seq in enumerate(sequences):
        entropy, _ = dna_sequence_entropy(seq)
        print(f"序列{i + 1}熵: {entropy:.3f}")
    #序列1熵: 1.386
    #序列2熵: 1.386
    #序列3熵: 1.386

    示例7. 机器学习中的变分推断

    变分贝叶斯中的ELBO(证据下界)计算
    def variational_elbo_gamma(data, alpha_q, beta_q, alpha_prior, beta_prior):
        """
        计算伽玛分布变分近似的ELBO
        """
        n = len(data)

        # 期望对数似然
        E_log_lambda = log(beta_q) + digamma(alpha_q)  # digamma是Gamma函数的对数导数
        E_lambda = alpha_q / beta_q

        expected_log_likelihood = (n * E_log_lambda - E_lambda * sum(data) +
                                   (E_log_lambda - 1) * sum(log(data)) -
                                   n * gammaln(1))  # 简化

        # KL散度(变分分布与先验之间)
        kl_divergence = ((alpha_q - alpha_prior) * digamma(alpha_q) -
                         gammaln(alpha_q) + gammaln(alpha_prior) +
                         alpha_prior * (log(beta_q) - log(beta_prior)) +
                         alpha_q * (beta_prior - beta_q) / beta_q)

        elbo = expected_log_likelihood - kl_divergence
        return elbo

    变分推断示例
    variational_params = (2.5, 1.5)  # (alpha_q, beta_q)
    prior_params = (1.0, 1.0)  # (alpha_prior, beta_prior)

    elbo = variational_elbo_gamma(sample_data, *variational_params, *prior_params)
    print(f"变分下界(ELBO): {elbo:.3f}")
    #变分下界(ELBO): -845.937

    示例8. 符号计算的高级应用

    符号微分和级数展开

    计算Gamma函数对数的导数(Digamma函数)
    digamma_expr = diff(loggamma(z), z)
    print(f"d(logΓ(z))/dz = {digamma_expr}")
    #d(logΓ(z))/dz = polygamma(0, z)

    泰勒级数展开
    taylor_series = series(loggamma(z), z, 1, 5)  # 在z=1处展开到5阶
    print(f"logΓ(z)在z=1处的泰勒展开:\n{taylor_series}")
    #logΓ(z)在z=1处的泰勒展开:
    #-EulerGamma*(z - 1) + pi**2*(z - 1)**2/12 - (z - 1)**3*zeta(3)/3 + pi**4*(z - 1)**4/360 + O((z - 1)**5, (z, 1))

    特殊值计算
    special_values = [
        (1, gammaln(1)),
        (0.5, gammaln(0.5)),
        (2, gammaln(2)),
    ]

    for z_val, log_gamma_val in special_values:
        print(f"logΓ({z_val}) = {log_gamma_val}")
    #logΓ(1) = 0.0
    #logΓ(0.5) = 0.5723649429247
    #logΓ(2) = 0.0
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    from scipy.special import gammaln


    def gamma_logarithm(input_str):
        """
         计算gamma函数的自然对数,对标MATLAB的gammaln函数。

         参数:
         input_str (str): 输入的数学表达式字符串,支持标量、矩阵或符号表达式。
                         对于数值输入,必须为非负实数;符号表达式需为合法SymPy表达式。

         返回:
         SymPy表达式/float/np.ndarray/str:
             - 符号输入返回SymPy的loggamma表达式
             - 标量数值输入返回float结果
             - 矩阵输入返回NumPy数组
             - 错误时返回字符串描述

         示例:
         >>> gamma_logarithm("5")          # 标量数值输入
         3.1780538303479458

         >>> gamma_logarithm("z")          # 符号输入
         loggamma(z)

         >>> gamma_logarithm("[[1, 2], [3, 4]]")  # 矩阵输入
         array([[0.        , 0.69314718],
                [1.79175947, 3.17805383]])

         >>> gamma_logarithm("-1")         # 错误输入
         '错误:输入必须为非负实数。'
         """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            if expr.free_symbols:
                result = sp.loggamma(expr)
            elif expr.is_number:
                # 数值型输入验证
                z = float(expr)
                # 使用SciPy计算数值结果
                result = gammaln(z)
            else:
                error = True

            return result if not error else f"输入错误: {input_str}"

        except (sp.SympifyError, TypeError) as e:
            return f"语法错误:无法解析输入 '{input_str}' -> {e}"
        except ValueError as e:
            return f"计算错误:{e}"
        except Exception as e:
            return f"未知错误:{type(e).__name__} - {str(e)}"


    # 符号表达式
    print(gamma_logarithm("x+y"))
    # loggamma(x + y)

    # 标量计算测试
    print(gamma_logarithm("6"))
    # 4.787491742782046
    
    
    伽玛概率密度函数

    p=gampdf(x,a)返回具有a中的形状参数的标准gamma分布的概率密度函数(pdf),在x中的值处进行评估。.

    y=gampdf(x,a,b)返回具有形状参数a和比例参数b的伽马分布的pdf,在x中的值处进行评估.

    x是评估pdf的值,非负标量,非负标量数组

    a是形状参数,正标量值,正标量值数组

    b是比例参数,默认值是1,正标量值,正标量的数组.

    如果输入参数x,a和b中的一个或多个是数组,则数组大小必须相同.在这种情况下,gampdf将每个标量输入扩展为与数组输入大小相同的常量数组.p中的每个元素都是由a和b中的对应元素指定的分布的cdf值, 在x中的相应元素处进行评估.

    示例1. 可靠性工程中的设备寿命建模

    import matplotlib.pyplot as plt

    设备寿命的伽马分布建模
    def plot_gamma_lifetimes():
        """绘制不同形状参数的伽马分布PDF,模拟设备寿命"""
        x = np.linspace(0, 20, 1000)

        # 不同形状参数(故障模式)
        shape_params = [1, 2, 3, 5]
        scale_param = 2  # 平均寿命参数

        plt.figure(figsize=(10, 6))
        for k in shape_params:
            # 计算PDF值
            pdf_values = [gampdf(xi, k, scale_param) for xi in x]
            plt.plot(x, pdf_values, label=f'形状参数 k={k}')

        plt.title('伽马分布模拟设备寿命概率密度')
        plt.xlabel('时间 (千小时)')
        plt.ylabel('概率密度')
        plt.legend()
        plt.grid(True)
        plt.show()

    计算特定设备的故障概率密度
    def equipment_failure_density(operating_time, shape_param, scale_param):
        """计算设备在特定运行时间下的故障概率密度"""
        return gampdf(operating_time, shape_param, scale_param)

    示例:计算设备运行5000小时后的故障概率密度
    operating_hours = 5  # 千小时
    shape = 3.0  # 形状参数(与故障机制相关)
    scale = 2.0  # 尺度参数(平均寿命)

    density = equipment_failure_density(operating_hours, shape, scale)
    print(f"设备运行{operating_hours}千小时后的故障概率密度: {density:.4f}")
    #设备运行5千小时后的故障概率密度: 0.1283

    plot_gamma_lifetimes()

    示例2. 保险精算中的索赔金额分布

    保险索赔金额的伽马分布建模
    def insurance_claim_model():
        """模拟保险索赔金额的分布"""
        claim_amounts = np.linspace(0, 50000, 1000)  # 索赔金额范围

        # 不同风险等级的索赔分布
        risk_profiles = [
            {"name": "低风险", "shape": 2.0, "scale": 5000},
            {"name": "中风险", "shape": 1.5, "scale": 8000},
            {"name": "高风险", "shape": 1.2, "scale": 12000}
        ]

        plt.figure(figsize=(12, 8))
        for profile in risk_profiles:
            pdf_values = []
            for amount in claim_amounts:
                pdf_val = gampdf(amount, profile['shape'], profile['scale'])
                pdf_values.append(pdf_val)

            plt.plot(claim_amounts, pdf_values,
                     label=f"{profile['name']} (k={profile['shape']}, θ={profile['scale']})")

        plt.title('不同风险等级的保险索赔金额概率密度')
        plt.xlabel('索赔金额 ($)')
        plt.ylabel('概率密度')
        plt.legend()
        plt.grid(True)
        plt.xlim(0, 50000)
        plt.show()

    计算特定索赔金额的概率密度
    def claim_probability_density(claim_amount, risk_level="medium"):
        """计算特定索赔金额的概率密度"""
        risk_params = {
            "low": (2.0, 5000),
            "medium": (1.5, 8000),
            "high": (1.2, 12000)
        }

        shape, scale = risk_params.get(risk_level, (1.5, 8000))
        return gampdf(f"({claim_amount}, {shape}, {scale})")

    示例计算
    claim_10k = claim_probability_density(10000, "medium")
    claim_30k = claim_probability_density(30000, "high")
    print(f"中等风险索赔$10,000的概率密度: {claim_10k:.6f}")
    print(f"高风险索赔$30,000的概率密度: {claim_30k:.6f}")
    #中等风险索赔$10,000的概率密度: 0.000045
    #高风险索赔$30,000的概率密度: 0.000009

    insurance_claim_model()

    示例3. 医学统计中的治疗时间分析

    医疗治疗时间的伽马分布分析
    def medical_treatment_analysis():
        """分析不同医疗程序的持续时间分布"""
        treatment_times = np.linspace(0, 120, 1000)  # 治疗时间(分钟)

        # 不同医疗程序的时间分布
        procedures = [
            {"name": "常规检查", "shape": 3.0, "scale": 15},
            {"name": "小型手术", "shape": 2.5, "scale": 25},
            {"name": "复杂手术", "shape": 2.0, "scale": 40}
        ]

        plt.figure(figsize=(12, 8))
        for procedure in procedures:
            pdf_values = []
            for time in treatment_times:
                pdf_val = gampdf(time, procedure['shape'], procedure['scale'])
                pdf_values.append(pdf_val)

            plt.plot(treatment_times, pdf_values,
                     label=f"{procedure['name']} (k={procedure['shape']}, θ={procedure['scale']})")

        plt.title('不同医疗程序持续时间的概率密度分布')
        plt.xlabel('治疗时间 (分钟)')
        plt.ylabel('概率密度')
        plt.legend()
        plt.grid(True)
        plt.show()


    手术室调度优化
    def operating_room_scheduling():
        """使用伽马分布优化手术室调度"""
        # 计算不同手术时间的概率
        surgery_types = [
            ("阑尾切除术", 2.2, 45),
            ("胆囊切除术", 2.5, 60),
            ("心脏搭桥", 1.8, 180)
        ]

        print("手术时间概率分析:")
        for surgery_name, shape, scale in surgery_types:
            # 计算90分钟内的完成概率(使用CDF,这里演示PDF用途)
            time_points = [30, 60, 90, 120]
            densities = []

            for t in time_points:
                density_val = gampdf(f"({t}, {shape}, {scale})")
                densities.append(density_val)
                print(f"{surgery_name}在{t}分钟时的概率密度: {density_val:.6f}")

            print("---")

        return surgery_types


    medical_treatment_analysis()
    surgery_data = operating_room_scheduling()
    #手术时间概率分析:
    #阑尾切除术在30分钟时的概率密度: 0.006366
    #阑尾切除术在60分钟时的概率密度: 0.007508
    #阑尾切除术在90分钟时的概率密度: 0.006271
    #阑尾切除术在120分钟时的概率密度: 0.004547
    #---
    #胆囊切除术在30分钟时的概率密度: 0.002689
    #胆囊切除术在60分钟时的概率密度: 0.004612
    #胆囊切除术在90分钟时的概率密度: 0.005139
    #胆囊切除术在120分钟时的概率密度: 0.004799
    #---
    #心脏搭桥在30分钟时的概率密度: 0.001204
    #心脏搭桥在60分钟时的概率密度: 0.001775
    #心脏搭桥在90分钟时的概率密度: 0.002078
    #心脏搭桥在120分钟时的概率密度: 0.002214

    示例4. 金融中的股价波动建模

    使用伽马分布建模金融资产回报率
    def stock_volatility_model():
        """建模股价波动率的分布"""
        volatilities = np.linspace(0, 0.5, 1000)  # 波动率范围 (0-50%)

        # 不同资产类别的波动率分布
        asset_classes = [
            {"name": "国债", "shape": 4.0, "scale": 0.02},
            {"name": "蓝筹股", "shape": 2.5, "scale": 0.05},
            {"name": "科技股", "shape": 1.8, "scale": 0.08},
            {"name": "加密货币", "shape": 1.2, "scale": 0.15}
        ]

        plt.figure(figsize=(12, 8))
        for asset in asset_classes:
            pdf_values = []
            for vol in volatilities:
                pdf_val = gampdf(vol, asset['shape'], asset['scale'])
                pdf_values.append(pdf_val)

            plt.plot(volatilities, pdf_values,
                     label=f"{asset['name']} (k={asset['shape']}, θ={asset['scale']:.3f})")

        plt.title('不同资产类别的波动率概率密度分布')
        plt.xlabel('年化波动率')
        plt.ylabel('概率密度')
        plt.legend()
        plt.grid(True)
        plt.show()


    风险价值(VaR)计算辅助
    def volatility_risk_assessment():
        """评估特定波动率水平的风险"""
        volatility_levels = [0.1, 0.2, 0.3, 0.4]  # 10%-40%波动率

        print("科技股波动率风险评估:")
        tech_shape, tech_scale = 1.8, 0.08

        for vol in volatility_levels:
            density_val = gampdf(vol, tech_shape, tech_scale)
            risk_level = "低" if density_val > 2 else "中" if density_val > 0.5 else "高"
            print(f"波动率{vol * 100:.0f}%: 概率密度={density_val:.4f} ({risk_level}风险)")

        return tech_shape, tech_scale

    stock_volatility_model()
    tech_params = volatility_risk_assessment()
    #科技股波动率风险评估:
    #波动率10%: 概率密度=4.5966 (低风险)
    #波动率20%: 概率密度=2.2930 (低风险)
    #波动率30%: 概率密度=0.9087 (中风险)
    #波动率40%: 概率密度=0.3277 (高风险)

    示例5. 环境科学中的降雨量分析

    降雨量的伽马分布建模
    def rainfall_distribution_model():
        """建模月降雨量的概率分布"""
        rainfall_mm = np.linspace(0, 300, 1000)  # 月降雨量 (mm)

        # 不同气候区域的降雨分布
        climate_zones = [
            {"name": "干旱区", "shape": 1.5, "scale": 20},
            {"name": "温带区", "shape": 2.0, "scale": 50},
            {"name": "湿润区", "shape": 2.5, "scale": 80}
        ]

        plt.figure(figsize=(12, 8))
        for zone in climate_zones:
            pdf_values = []
            for rain in rainfall_mm:
                pdf_val = gampdf(rain, zone['shape'], zone['scale'])
                pdf_values.append(pdf_val)

            plt.plot(rainfall_mm, pdf_values,
                     label=f"{zone['name']} (k={zone['shape']}, θ={zone['scale']})")

        plt.title('不同气候区域月降雨量的概率密度分布')
        plt.xlabel('月降雨量 (mm)')
        plt.ylabel('概率密度')
        plt.legend()
        plt.grid(True)
        plt.show()


    干旱风险评估
    def drought_risk_assessment():
        """评估不同降雨量水平的干旱风险"""
        rainfall_thresholds = [10, 30, 50, 100]  # 降雨量阈值 (mm)

        # 干旱区的参数
        arid_shape, arid_scale = 1.5, 20

        print("干旱区降雨量风险评估:")
        for threshold in rainfall_thresholds:
            density_val = gampdf(threshold, arid_shape, arid_scale)

            if threshold <= 10:
                risk = "极端干旱"
            elif threshold <= 30:
                risk = "严重干旱"
            elif threshold <= 50:
                risk = "中等干旱"
            else:
                risk = "正常"

            print(f"降雨量{threshold}mm: 概率密度={density_val:.4f} ({risk})")

        return arid_shape, arid_scale


    rainfall_distribution_model()
    arid_params = drought_risk_assessment()
    #干旱区降雨量风险评估:
    #降雨量10mm: 概率密度=0.0242 (极端干旱)
    #降雨量30mm: 概率密度=0.0154 (严重干旱)
    #降雨量50mm: 概率密度=0.0073 (中等干旱)
    #降雨量100mm: 概率密度=0.0009 (正常)

    示例6. 工业生产中的质量控制

    产品尺寸偏差的伽马分布建模
    def manufacturing_quality_control():
        """建模产品制造过程中的尺寸偏差分布"""
        deviations = np.linspace(0, 0.5, 1000)  # 尺寸偏差 (mm)

        # 不同制造工艺的偏差分布
        processes = [
            {"name": "传统加工", "shape": 1.8, "scale": 0.1},
            {"name": "数控加工", "shape": 2.5, "scale": 0.05},
            {"name": "精密加工", "shape": 3.5, "scale": 0.02}
        ]

        plt.figure(figsize=(12, 8))
        for process in processes:
            pdf_values = []
            for dev in deviations:
                pdf_val = gampdf(dev, process['shape'], process['scale'])
                pdf_values.append(pdf_val)

            plt.plot(deviations, pdf_values,
                     label=f"{process['name']} (k={process['shape']}, θ={process['scale']:.3f})")

        plt.title('不同制造工艺的尺寸偏差概率密度分布')
        plt.xlabel('尺寸偏差 (mm)')
        plt.ylabel('概率密度')
        plt.legend()
        plt.grid(True)
        plt.xlim(0, 0.3)
        plt.show()

    公差设计优化
    def tolerance_design_analysis():
        """分析不同公差要求下的质量水平"""
        tolerance_limits = [0.05, 0.1, 0.15, 0.2]  # 公差限 (mm)

        # 数控加工的参数
        cnc_shape, cnc_scale = 2.5, 0.05

        print("数控加工公差设计分析:")
        for tolerance in tolerance_limits:
            density_val = gampdf(tolerance, cnc_shape, cnc_scale)

            # 估算合格率(简化计算)
            if density_val > 1:
                yield_estimate = ">99%"
            elif density_val > 0.1:
                yield_estimate = "95%-99%"
            else:
                yield_estimate = "<95%"

            print(f"公差±{tolerance}mm: 概率密度={density_val:.4f} (预估合格率: {yield_estimate})")

        return cnc_shape, cnc_scale

    manufacturing_quality_control()
    cnc_params = tolerance_design_analysis()
    #数控加工公差设计分析:
    #公差±0.05mm: 概率密度=5.5348 (预估合格率: >99%)
    #公差±0.1mm: 概率密度=5.7590 (预估合格率: >99%)
    #公差±0.15mm: 概率密度=3.8922 (预估合格率: >99%)
    #公差±0.2mm: 概率密度=2.2045 (预估合格率: >99%)

    示例7. 矩阵输入的批量计算示例

    批量处理多个参数组合
    def batch_gamma_pdf_calculation():
        """演示矩阵输入情况下的批量计算"""

        # 创建测试数据矩阵
        x_values = [[1, 2, 3], [4, 5, 6]]  # 输入值矩阵
        k_values = [[1, 1, 1], [2, 2, 2]]  # 形状参数矩阵
        theta_values = [[1, 2, 1], [1, 1, 2]]  # 尺度参数矩阵

        print("矩阵输入批量计算示例:")
        print("x值矩阵:")
        print(np.array(x_values))
        print("\n形状参数k矩阵:")
        print(np.array(k_values))
        print("\n尺度参数θ矩阵:")
        print(np.array(theta_values))

        # 批量计算PDF值
        result = gampdf(x_values, k_values, theta_values)
        print("\n伽马分布PDF结果矩阵:")
        print(result)

        return result

    实际应用:批量风险评估
    def batch_risk_assessment():
        """批量评估多个风险场景"""

        # 不同场景的参数
        scenarios = {
            "设备A_低负荷": (1000, 2.0, 500),
            "设备A_高负荷": (1000, 1.5, 300),
            "设备B_正常": (2000, 2.5, 800),
            "设备B_老化": (2000, 1.8, 600)
        }

        print("\n设备故障风险批量评估:")
        for scenario, params in scenarios.items():
            operating_time, shape, scale = params
            density_val = gampdf(operating_time, shape, scale)

            risk_level = "低" if density_val < 0.001 else "中" if density_val < 0.005 else "高"
            print(f"{scenario}: 概率密度={density_val:.6f} ({risk_level}风险)")

        return scenarios

    执行批量计算示例
    matrix_results = batch_gamma_pdf_calculation()
    #矩阵输入批量计算示例:
    #x值矩阵:
    #[[1 2 3]
      [4 5 6]]

    #形状参数k矩阵:
    #[[1 1 1]
      [2 2 2]]

    #尺度参数θ矩阵:
    #[[1 2 1]
      [1 1 2]]

    #伽马分布PDF结果矩阵:
    #[[0.36787944 0.18393972 0.04978707]
      [0.07326256 0.03368973 0.0746806 ]]

    risk_scenarios = batch_risk_assessment()
    #设备故障风险批量评估:
    #设备A_低负荷: 概率密度=0.000541 (低风险)
    #设备A_高负荷: 概率密度=0.000245 (低风险)
    #设备B_正常: 概率密度=0.000305 (低风险)
    #设备B_老化: 概率密度=0.000167 (低风险)
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    from sympy.stats import Geometric, density, cdf, Gamma, E, variance
    from scipy.stats import gamma as scipy_gamma


    def gamma_pdf(input_str):
        """
        计算伽马分布概率密度函数 (对标MATLAB gampdf)

        参数:
        x: 输入值/矩阵
        k: 形状参数/矩阵
        theta: 尺度参数/矩阵 (默认1)

        返回:
        SymPy矩阵/数值/错误信息

        示例:
        >>> gamma_pdf(2, 1)  # 标量计算
        0.1353352832366127
        >>> gamma_pdf([[1,2],[3,4]], 2, 1)  # 矩阵输入
        Matrix([
        [0.367879441171442, 0.270670566473225],
        [0.149361205103592, 0.073262555554937]])
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            if isinstance(expr, tuple) and len(expr) <= 3:
                if len(expr) == 2:
                    theta = 1
                    if all(e.is_number for e in expr):
                        params = tuple(float(e.evalf()) for e in expr)
                        result = scipy_gamma.pdf(*params, theta)
                    elif any(e.free_symbols for e in expr):
                        G = Gamma("gamma", expr[1], theta)
                        result = density(G)(expr[0])
                elif len(expr) == 3:
                    if all(e.is_number for e in expr):
                        result = scipy_gamma.pdf(*expr)
                    elif any(e.free_symbols for e in expr):
                        G = Gamma("gamma", expr[1], expr[2])
                        result = density(G)(expr[0])
            else:
                error = True

            return result if not error else f"输入错误: {input_str}"

        except Exception as e:
            return f"错误: {str(e)}"


    # 示例测试
    if __name__ == "__main__":
        # 标量测试
        print(gamma_pdf("2, 1"))
        # 0.36787944117144233

        # 符号变量测试
        print(gamma_pdf("x, 1"))
        # exp(-x)
    
    
    伽玛随机数

    r = gamrnd(a,b) 从具有形状参数 a 和尺度参数 b 的 gamma 分布中生成一个随机数.

    r = gamrnd(a,b,sz) 从 gamma 分布中生成一个随机数数组,其中向量 sz 指定 size(r).

    a是形状参数,正标量值,正标量值数组

    b是比例参数,默认值是1,正标量值,正标量的数组.

    如果输入参数a和b都是数组,则数组大小必须相同.如果a或b是标量,则gamrnd会将标量参量扩展为与另一个参量大小相同的常量数组.r中的每个元素均是从a和b中对应元素所指定的分布中生成的随机数.

    示例1. 可靠性工程中的设备寿命模拟

    import matplotlib.pyplot as plt
    import seaborn as sns

    np.random.seed(42)  # 设置随机种子保证可重复性

    不同设备的伽马分布参数
    equipment_types = {
        "服务器": {"shape": 2.5, "scale": 1000},  # 平均寿命2500小时
        "网络设备": {"shape": 3.0, "scale": 800},  # 平均寿命2400小时
        "存储设备": {"shape": 4.0, "scale": 600},  # 平均寿命2400小时
        "工作站": {"shape": 2.0, "scale": 1200}  # 平均寿命2400小时
    }

    为每种设备生成1000个寿命样本
    samples = {}
    for eq_type, params in equipment_types.items():
        shape, scale = params["shape"], params["scale"]
        samples[eq_type] = gamrnd(shape, scale, 1000)

    绘制寿命分布直方图
    plt.figure(figsize=(12, 8))
    for i, (eq_type, data) in enumerate(samples.items()):
        plt.subplot(2, 2, i + 1)
        plt.hist(data, bins=50, alpha=0.7, density=True)
        plt.title(f'{eq_type}寿命分布')
        plt.xlabel('寿命 (小时)')
        plt.ylabel('密度')
        plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    设备寿命模拟结果:
    for eq_type, data in samples.items():
        mean_life = np.mean(data)
        std_life = np.std(data)
        failure_before_2000 = np.mean(data < 2000) * 100

        print(f"{eq_type}: 平均寿命={mean_life:.0f}小时, "
              f"标准差={std_life:.0f}小时, "
              f"2000小时内故障概率={failure_before_2000:.1f}%")
    #服务器: 平均寿命=2569小时, 标准差=1561小时, 2000小时内故障概率=42.6%
    #网络设备: 平均寿命=2420小时, 标准差=1402小时, 2000小时内故障概率=44.1%
    #存储设备: 平均寿命=2369小时, 标准差=1176小时, 2000小时内故障概率=43.2%
    #工作站: 平均寿命=2406小时, 标准差=1727小时, 2000小时内故障概率=50.6%

    示例2. 保险精算中的索赔金额模拟

    np.random.seed(123)

    不同风险等级的索赔分布参数
    risk_categories = {
        "低风险": {"shape": 3.0, "scale": 5000},  # 平均索赔15000
        "中风险": {"shape": 2.0, "scale": 10000},  # 平均索赔20000
        "高风险": {"shape": 1.5, "scale": 15000}  # 平均索赔22500
    }

    生成索赔金额样本
    n_claims = 500  # 每种风险500个索赔
    claim_samples = {}

    for category, params in risk_categories.items():
        shape, scale = params["shape"], params["scale"]
        claim_samples[category] = gamrnd(shape, scale, n_claims)

    可视化索赔分布
    plt.figure(figsize=(14, 6))

    箱线图比较
    plt.subplot(1, 2, 1)
    data_to_plot = [claim_samples[cat] for cat in risk_categories.keys()]
    plt.boxplot(data_to_plot, labels=risk_categories.keys())
    plt.title('不同风险等级的索赔金额分布')
    plt.ylabel('索赔金额 ($)')
    plt.grid(True, alpha=0.3)

    密度图
    plt.subplot(1, 2, 2)
    for category, data in claim_samples.items():
        sns.kdeplot(data, label=category, alpha=0.7)
    plt.title('索赔金额概率密度')
    plt.xlabel('索赔金额 ($)')
    plt.ylabel('密度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    保险索赔风险评估:
    for category, data in claim_samples.items():
        avg_claim = np.mean(data)
        p95_claim = np.percentile(data, 95)  # 95%分位数
        extreme_claims = np.sum(data > 100000)  # 极端索赔数量

        print(f"{category}: 平均索赔=${avg_claim:,.0f}, "
              f"95%分位数=${p95_claim:,.0f}, "
              f"极端索赔(>$100k)数量={extreme_claims}")
    #低风险: 平均索赔=$15,222, 95%分位数=$31,256, 极端索赔(>$100k)数量=0
    #中风险: 平均索赔=$20,324, 95%分位数=$46,446, 极端索赔(>$100k)数量=0
    #高风险: 平均索赔=$22,899, 95%分位数=$58,527, 极端索赔(>$100k)数量=1

    示例3. 医疗统计中的治疗时间模拟

    np.random.seed(456)

    medical_procedures = {
        "常规检查": {"shape": 3.0, "scale": 10},  # 平均30分钟
        "小型手术": {"shape": 2.5, "scale": 20},  # 平均50分钟
        "专科诊疗": {"shape": 2.0, "scale": 25},  # 平均50分钟
        "急诊处理": {"shape": 1.8, "scale": 15}  # 平均27分钟
    }

    生成治疗时间样本
    n_cases = 200
    treatment_times = {}

    for procedure, params in medical_procedures.items():
        shape, scale = params["shape"], params["scale"]
        treatment_times[procedure] = gamrnd(shape, scale, n_cases)

    医疗治疗时间模拟分析:
    plt.figure(figsize=(12, 8))

    for i, (procedure, times) in enumerate(treatment_times.items()):
        # 计算统计量
        mean_time = np.mean(times)
        median_time = np.median(times)
        p90_time = np.percentile(times, 90)

        print(f"{procedure}: 平均={mean_time:.1f}分钟, "
              f"中位数={median_time:.1f}分钟, "
              f"90%分位数={p90_time:.1f}分钟")

        # 绘制累积分布函数
        sorted_times = np.sort(times)
        cdf = np.arange(1, len(sorted_times) + 1) / len(sorted_times)
        plt.plot(sorted_times, cdf, label=procedure, linewidth=2)
    #常规检查: 平均=29.9分钟, 中位数=25.5分钟, 90%分位数=52.9分钟
    #小型手术: 平均=47.8分钟, 中位数=41.1分钟, 90%分位数=90.8分钟
    #专科诊疗: 平均=50.4分钟, 中位数=42.6分钟, 90%分位数=94.1分钟
    #急诊处理: 平均=26.2分钟, 中位数=20.2分钟, 90%分位数=51.8分钟

    plt.title('不同医疗程序治疗时间的累积分布')
    plt.xlabel('治疗时间 (分钟)')
    plt.ylabel('累积概率')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.show()

    手术室利用率分析
    operating_room_hours = 8 * 60  # 8小时工作制
    procedure_sequence = ["常规检查", "小型手术", "专科诊疗", "急诊处理"]

    手术室调度模拟:
    current_time = 0
    for procedure in procedure_sequence:
        # 随机选择一个该程序的治疗时间
        proc_time = np.random.choice(treatment_times[procedure])
        current_time += proc_time

        if current_time <= operating_room_hours:
            status = "完成"
        else:
            status = "超时"

        print(f"{procedure}: {proc_time:.1f}分钟, 累计{current_time:.1f}分钟 - {status}")
    #常规检查: 44.7分钟, 累计44.7分钟 - 完成
    #小型手术: 28.1分钟, 累计72.8分钟 - 完成
    #专科诊疗: 34.6分钟, 累计107.4分钟 - 完成
    #急诊处理: 6.9分钟, 累计114.3分钟 - 完成

    示例4. 金融风险管理中的损失模拟

    np.random.seed(789)

    不同资产类别的损失分布参数
    asset_classes = {
        "债券投资": {"shape": 4.0, "scale": 10000},  # 低风险
        "股票投资": {"shape": 2.5, "scale": 50000},  # 中等风险
        "衍生品投资": {"shape": 1.5, "scale": 100000},  # 高风险
        "风险投资": {"shape": 1.2, "scale": 200000}  # 极高风险
    }

    生成损失样本
    n_scenarios = 10000  # 10000个模拟场景
    loss_samples = {}

    for asset_class, params in asset_classes.items():
        shape, scale = params["shape"], params["scale"]
        loss_samples[asset_class] = gamrnd(shape, scale, n_scenarios)

    风险价值(VaR)和预期短缺(ES)计算
    confidence_levels = [0.95, 0.99]

    金融风险度量分析:
    plt.figure(figsize=(15, 10))

    for i, (asset_class, losses) in enumerate(loss_samples.items()):
        plt.subplot(2, 2, i + 1)

        # 计算风险指标
        var_values = {}
        es_values = {}

        for cl in confidence_levels:
            var = np.percentile(losses, cl * 100)
            # ES是超过VaR的条件期望
            excess_losses = losses[losses > var]
            es = np.mean(excess_losses) if len(excess_losses) > 0 else var

            var_values[cl] = var
            es_values[cl] = es

        # 绘制损失分布和VaR线
        plt.hist(losses, bins=100, alpha=0.7, density=True)
        for cl in confidence_levels:
            plt.axvline(var_values[cl], color='red', linestyle='--',
                        label=f'{cl * 100}% VaR = ${var_values[cl]:,.0f}')

        plt.title(f'{asset_class}损失分布')
        plt.xlabel('损失金额 ($)')
        plt.ylabel('密度')
        plt.legend()
        plt.grid(True, alpha=0.3)

        # 输出风险指标
        print(f"\n{asset_class}:")
        for cl in confidence_levels:
            print(f"  {cl * 100}% VaR: ${var_values[cl]:,.0f}")
            print(f"  {cl * 100}% ES: ${es_values[cl]:,.0f}")
    #债券投资:
    #  95.0% VaR: $78,271
    #  95.0% ES: $93,316
    #  99.0% VaR: $103,080
    #  99.0% ES: $117,009

    #股票投资:
    #  95.0% VaR: $278,903
    #  95.0% ES: $338,190
    #  99.0% VaR: $368,382
    #  99.0% ES: $429,035

    #衍生品投资:
    #  95.0% VaR: $393,148
    #  95.0% ES: $504,418
    #  99.0% VaR: $569,512
    #  99.0% ES: $683,083

    plt.tight_layout()
    plt.show()

    示例5. 环境科学中的降雨量模拟

    np.random.seed(321)

    climate_regions = {
        "干旱地区": {"shape": 1.8, "scale": 15},  # 低降雨量
        "半干旱地区": {"shape": 2.2, "scale": 30},  # 中等降雨量
        "湿润地区": {"shape": 2.5, "scale": 60},  # 高降雨量
        "热带雨林": {"shape": 3.0, "scale": 100}  # 极高降雨量
    }

    生成120个月(10年)的降雨量数据
    n_months = 120
    rainfall_data = {}

    for region, params in climate_regions.items():
        shape, scale = params["shape"], params["scale"]
        rainfall_data[region] = gamrnd(shape, scale, n_months)

    降雨量模式分析:
    plt.figure(figsize=(15, 10))

    时间序列图
    plt.subplot(2, 1, 1)
    for region, rainfall in rainfall_data.items():
        plt.plot(rainfall, label=region, alpha=0.7)

    plt.axhline(y=30, color='red', linestyle='--', label='干旱阈值 (30mm)')
    plt.title('月降雨量时间序列 (10年)')
    plt.xlabel('月份')
    plt.ylabel('降雨量 (mm)')
    plt.legend()
    plt.grid(True, alpha=0.3)

    季节性分析(按月份分组)
    plt.subplot(2, 1, 2)
    months = np.arange(12)

    for region, rainfall in rainfall_data.items():
        seasonal_means = []
        for month in months:
            # 获取所有该月份的降雨量
            month_data = rainfall[month::12]
            seasonal_means.append(np.mean(month_data))

        plt.plot(months, seasonal_means, 'o-', label=region, markersize=8)

    plt.title('月平均降雨量季节性模式')
    plt.xlabel('月份')
    plt.ylabel('平均降雨量 (mm)')
    plt.xticks(months, ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'])
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    干旱分析
    drought_threshold = 30  # 月降雨量低于30mm视为干旱

    干旱频率分析:
    for region, rainfall in rainfall_data.items():
        drought_months = np.sum(rainfall < drought_threshold)
        drought_frequency = drought_months / n_months * 100

        # 最长连续干旱期
        drought_sequence = rainfall < drought_threshold
        max_consecutive = 0
        current = 0
        for is_drought in drought_sequence:
            if is_drought:
                current += 1
                max_consecutive = max(max_consecutive, current)
            else:
                current = 0

        print(f"{region}: 干旱月份={drought_months} ({drought_frequency:.1f}%), "
              f"最长连续干旱={max_consecutive}个月")
    #干旱地区: 干旱月份=82 (68.3%), 最长连续干旱=13个月
    #半干旱地区: 干旱月份=27 (22.5%), 最长连续干旱=4个月
    #湿润地区: 干旱月份=1 (0.8%), 最长连续干旱=1个月
    #热带雨林: 干旱月份=1 (0.8%), 最长连续干旱=1个月

    示例6. 工业生产中的质量控制模拟

    np.random.seed(654)

    manufacturing_processes = {
        "传统加工": {"shape": 2.0, "scale": 0.05},  # 较高变异
        "数控加工": {"shape": 3.0, "scale": 0.02},  # 中等变异
        "精密加工": {"shape": 4.0, "scale": 0.01},  # 低变异
        "超精密加工": {"shape": 5.0, "scale": 0.005}  # 极低变异
    }

    每种工艺生成500个产品的尺寸偏差
    n_products = 500
    quality_data = {}

    for process, params in manufacturing_processes.items():
        shape, scale = params["shape"], params["scale"]
        quality_data[process] = gamrnd(shape, scale, n_products)

    制造过程质量分析:

    规格限设定
    usl = 0.1  # 上限规格限
    lsl = -0.1  # 下限规格限(假设对称)

    plt.figure(figsize=(14, 10))

    偏差分布图
    for i, (process, deviations) in enumerate(quality_data.items()):
        plt.subplot(2, 2, i + 1)

        # 添加正负偏差(实际制造中偏差可正可负)
        symmetric_deviations = deviations * np.random.choice([-1, 1], len(deviations))

        plt.hist(symmetric_deviations, bins=50, alpha=0.7)
        plt.axvline(lsl, color='red', linestyle='--', label=f'规格限 ±{usl}')
        plt.axvline(usl, color='red', linestyle='--')
        plt.title(f'{process}尺寸偏差分布')
        plt.xlabel('尺寸偏差 (mm)')
        plt.ylabel('频数')
        plt.legend()
        plt.grid(True, alpha=0.3)

        # 过程能力指标计算
        cpk = min((usl - np.mean(symmetric_deviations)) / (3 * np.std(symmetric_deviations)),
                  (np.mean(symmetric_deviations) - lsl) / (3 * np.std(symmetric_deviations)))

        yield_rate = np.mean((symmetric_deviations >= lsl) & (symmetric_deviations <= usl)) * 100

        print(f"{process}: Cpk = {cpk:.2f}, 合格率 = {yield_rate:.1f}%")
    #传统加工: Cpk = 0.27, 合格率 = 59.6%
    #数控加工: Cpk = 0.48, 合格率 = 87.2%
    #精密加工: Cpk = 0.73, 合格率 = 98.6%
    #超精密加工: Cpk = 1.20, 合格率 = 100.0%

    plt.tight_layout()
    plt.show()

    批量生产质量预测:
    batch_sizes = [100, 1000, 10000]

    for process, params in manufacturing_processes.items():
        shape, scale = params["shape"], params["scale"]

        print(f"\n{process}工艺:")
        for batch_size in batch_sizes:
            # 模拟批量生产
            batch_deviations = gamrnd(shape, scale, batch_size)
            symmetric_batch = batch_deviations * np.random.choice([-1, 1], batch_size)

            defects = np.sum((symmetric_batch < lsl) | (symmetric_batch > usl))
            defect_rate = defects / batch_size * 100

            print(f"  批量大小 {batch_size}: 缺陷数={defects}, 缺陷率={defect_rate:.2f}%")
    #传统加工工艺:
    #  批量大小 100: 缺陷数=41, 缺陷率=41.00%
    #  批量大小 1000: 缺陷数=423, 缺陷率=42.30%
    #  批量大小 10000: 缺陷数=4082, 缺陷率=40.82%

    #数控加工工艺:
    #  批量大小 100: 缺陷数=11, 缺陷率=11.00%
    #  批量大小 1000: 缺陷数=134, 缺陷率=13.40%
    #  批量大小 10000: 缺陷数=1201, 缺陷率=12.01%

    #精密加工工艺:
    #  批量大小 100: 缺陷数=0, 缺陷率=0.00%
    #  批量大小 1000: 缺陷数=11, 缺陷率=1.10%
    #  批量大小 10000: 缺陷数=121, 缺陷率=1.21%

    #超精密加工工艺:
    #  批量大小 100: 缺陷数=0, 缺陷率=0.00%
    #  批量大小 1000: 缺陷数=0, 缺陷率=0.00%
    #  批量大小 10000: 缺陷数=0, 缺陷率=0.00%

    示例7. 高级应用:蒙特卡洛风险模拟

    np.random.seed(999)

    模拟投资组合的多个风险因素
    n_simulations = 10000

    市场风险(股票回报)
    market_risk = gamrnd(2.0, 0.02, n_simulations) - 0.02  # 中心化

    信用风险(违约损失)
    credit_risk = gamrnd(1.5, 0.01, n_simulations)

    操作风险(意外损失)
    operational_risk = gamrnd(2.5, 0.005, n_simulations)

    流动性风险(交易成本)
    liquidity_risk = gamrnd(3.0, 0.002, n_simulations)

    组合风险计算(简化模型)
    portfolio_returns = 0.08 + market_risk - credit_risk - operational_risk - liquidity_risk

    风险分析
    plt.figure(figsize=(15, 10))

    回报分布
    plt.subplot(2, 2, 1)
    plt.hist(portfolio_returns, bins=100, alpha=0.7, density=True)
    plt.axvline(np.mean(portfolio_returns), color='red', linestyle='--',
                label=f'平均回报: {np.mean(portfolio_returns):.3f}')
    plt.title('投资组合回报分布')
    plt.xlabel('回报率')
    plt.ylabel('密度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    风险贡献分析
    risk_factors = {
        '市场风险': market_risk,
        '信用风险': credit_risk,
        '操作风险': operational_risk,
        '流动性风险': liquidity_risk
    }

    risk_contributions = {}
    total_variance = np.var(portfolio_returns)

    for factor_name, factor_data in risk_factors.items():
        # 简化计算风险贡献
        correlation = np.corrcoef(factor_data, portfolio_returns)[0, 1]
        contribution = correlation ** 2 * np.var(factor_data) / total_variance * 100
        risk_contributions[factor_name] = contribution

    风险贡献饼图
    plt.subplot(2, 2, 2)
    plt.pie(risk_contributions.values(), labels=risk_contributions.keys(), autopct='%1.1f%%')
    plt.title('风险贡献分析')

    极端损失分析
    plt.subplot(2, 2, 3)
    negative_returns = portfolio_returns[portfolio_returns < 0]
    if len(negative_returns) > 0:
        plt.hist(-negative_returns, bins=50, alpha=0.7, density=True)  # 损失为正数
        plt.title('损失分布(负回报)')
        plt.xlabel('损失率')
        plt.ylabel('密度')
        plt.grid(True, alpha=0.3)

    风险指标表
    plt.subplot(2, 2, 4)
    plt.axis('off')

    risk_metrics = {
        '平均回报': f"{np.mean(portfolio_returns):.4f}",
        '回报标准差': f"{np.std(portfolio_returns):.4f}",
        '95% VaR': f"{-np.percentile(portfolio_returns, 5):.4f}",
        '最大回撤': f"{-np.min(portfolio_returns):.4f}",
        '夏普比率': f"{(np.mean(portfolio_returns) - 0.03) / np.std(portfolio_returns):.2f}"
    }

    table_data = [[metric, value] for metric, value in risk_metrics.items()]
    table = plt.table(cellText=table_data,
                      colLabels=['风险指标', '数值'],
                      loc='center',
                      cellLoc='center')
    table.auto_set_font_size(False)
    table.set_fontsize(10)
    table.scale(1, 2)

    plt.tight_layout()
    plt.show()

    蒙特卡洛风险模拟结果:
    for metric, value in risk_metrics.items():
        print(f"{metric}: {value}")
    #平均回报: 0.0668
    #回报标准差: 0.0323
    #95% VaR: -0.0211
    #最大回撤: 0.0325
    #夏普比率: 1.14
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    def gamma_random_samples(input_str):
        """
        根据输入参数生成伽马分布的随机样本,模拟MATLAB的gamrnd函数行为。

        参数:
        input_str (str): 输入字符串,应能解析为包含形状参数a、比例参数b及可选大小参数的元组。
                         例如:"(2, 3)", "(1, 5, 10)", "([1,2], [3,4], 5, 2)"。

        返回:
        numpy.ndarray 或 float: 生成的随机样本数组或标量。若输入错误则返回错误信息字符串。

        示例:
        >>> gamma_random_samples("(2, 3)")
        # 生成一个形状参数2、比例参数3的样本

        >>> gamma_random_samples("(2, 5, 10)")
        # 生成10个形状参数2、比例参数5的样本

        >>> gamma_random_samples("([1,2], [3,4], 5, 2)")
        # 生成5x2的数组,每个元素基于对应的形状和比例参数
        """
        try:
            expr = sp.sympify(input_str)
            if isinstance(expr, tuple):
                if len(expr) >= 2:
                    a, b = expr[0], expr[1]
                    size = tuple(expr[2:]) if len(expr) > 2 else None
                    # 生成伽马分布样本
                    return np.random.gamma(a, b, size=size)
                else:
                    return f"输入错误: 元组长度不足,至少需要形状参数a和比例参数b。"
            else:
                return f"输入错误: 输入必须为包含a和b的元组。"
        except Exception as e:
            return f"错误: {e}"


    # 示例代码
    if __name__ == "__main__":
        # 示例1: 生成单个样本
        print("示例1 输出:", gamma_random_samples("(2, 5)"))
        # 8.0401321476408

        # 示例2: 生成5个样本
        print("示例2 输出形状:", gamma_random_samples("(2, 5, 5)"))
        # [22.3469496   7.22552538 13.73268475  1.51002786  9.18842614]

        # 示例3: 生成5x2矩阵,参数为数组
        samples = gamma_random_samples("([1, 2], [3, 4], 5, 2)")
        print("示例3 输出形状:", samples)
        # [[0.39950036 7.19800049]
        #  [5.23155375 5.40451038]
        #  [0.67944897 8.87343055]
        #  [2.5881992  3.66194587]
        #  [1.17191571 0.99974115]]
    
    
    伽玛均值和方差

    [M,V]=gamstat(A,B)返回形状参数在A中,尺度参数在B中的伽马分布的均值和方差.A和B可以是具有相同大小的向量.矩阵,这也是M和V的大小.

    A或B的标量输入被扩展为与另一输入具有相同维度的常数数组.A和B中的参数必须为正.

    参数A和B的伽马分布的平均值为AB.方差为A*B^2.

    示例1. 可靠性工程中的设备寿命分析

    import numpy as np
    import matplotlib.pyplot as plt

    不同设备的伽马分布参数
    equipment_params = {
        "服务器": {"shape": 2.5, "scale": 1000},
        "网络设备": {"shape": 3.0, "scale": 800},
        "存储设备": {"shape": 4.0, "scale": 600},
        "工作站": {"shape": 2.0, "scale": 1200}
    }

    设备寿命分布统计分析:

    results = {}
    for equipment, params in equipment_params.items():
        shape, scale = params["shape"], params["scale"]
        mean, variance = gamstat(shape, scale)
        std_dev = np.sqrt(variance)
        cv = std_dev / mean  # 变异系数

        results[equipment] = {
            "mean": mean,
            "variance": variance,
            "std_dev": std_dev,
            "cv": cv
        }

        print(f"{equipment:>10}: 平均寿命={mean:>6.0f}小时, "
              f"标准差={std_dev:>5.0f}小时, 变异系数={cv:.3f}")
    #服务器: 平均寿命=  2500小时, 标准差= 1581小时, 变异系数=0.632
    #网络设备: 平均寿命=  2400小时, 标准差= 1386小时, 变异系数=0.577
    #存储设备: 平均寿命=  2400小时, 标准差= 1200小时, 变异系数=0.500
    #工作站: 平均寿命=  2400小时, 标准差= 1697小时, 变异系数=0.707

    可视化比较
    equipment_names = list(equipment_params.keys())
    means = [results[eq]["mean"] for eq in equipment_names]
    std_devs = [results[eq]["std_dev"] for eq in equipment_names]

    plt.figure(figsize=(12, 8))

    平均寿命和标准差条形图
    plt.subplot(2, 2, 1)
    x_pos = np.arange(len(equipment_names))
    plt.bar(x_pos, means, yerr=std_devs, capsize=5, alpha=0.7)
    plt.title('设备平均寿命与标准差')
    plt.ylabel('小时')
    plt.xticks(x_pos, equipment_names, rotation=45)
    plt.grid(True, alpha=0.3)

    变异系数比较
    plt.subplot(2, 2, 2)
    cvs = [results[eq]["cv"] for eq in equipment_names]
    plt.bar(x_pos, cvs, alpha=0.7)
    plt.title('设备寿命变异系数')
    plt.ylabel('变异系数')
    plt.xticks(x_pos, equipment_names, rotation=45)
    plt.grid(True, alpha=0.3)

    可靠性曲线(生存函数)
    plt.subplot(2, 2, 3)
    time_points = np.linspace(0, 5000, 100)
    for equipment, params in equipment_params.items():
        shape, scale = params["shape"], params["scale"]
        mean_life = results[equipment]["mean"]
        # 简化生存概率计算(基于均值)
        survival_probs = np.exp(-time_points / mean_life)
        plt.plot(time_points, survival_probs, label=equipment, linewidth=2)

    plt.title('设备可靠性曲线(简化模型)')
    plt.xlabel('时间 (小时)')
    plt.ylabel('生存概率')
    plt.legend()
    plt.grid(True, alpha=0.3)

    维护策略分析
    plt.subplot(2, 2, 4)
    maintenance_intervals = [1000, 2000, 3000, 4000]
    failure_risks = {}

    for equipment, params in equipment_params.items():
        shape, scale = params["shape"], params["scale"]
        mean_life = results[equipment]["mean"]
        risks = []
        for interval in maintenance_intervals:
            # 简化计算:在维护间隔内故障的概率
            risk = 1 - np.exp(-interval / mean_life)
            risks.append(risk * 100)  # 转换为百分比

        failure_risks[equipment] = risks
        plt.plot(maintenance_intervals, risks, 'o-', label=equipment, markersize=6)

    plt.title('不同维护间隔的故障风险')
    plt.xlabel('维护间隔 (小时)')
    plt.ylabel('故障风险 (%)')
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    示例2. 保险精算中的索赔分析

    不同风险等级的伽马分布参数
    risk_profiles = {
        "低风险": {"shape": 3.0, "scale": 5000},
        "中风险": {"shape": 2.0, "scale": 10000},
        "高风险": {"shape": 1.5, "scale": 15000}
    }

    保险索赔分布统计分析:

    claim_stats = {}
    for risk_level, params in risk_profiles.items():
        shape, scale = params["shape"], params["scale"]
        mean, variance = gamstat(shape, scale)
        std_dev = np.sqrt(variance)

        claim_stats[risk_level] = {
            "mean_claim": mean,
            "variance": variance,
            "std_dev": std_dev,
            "cv": std_dev / mean
        }

        print(f"{risk_level:>8}: 平均索赔=${mean:>8,.0f}, "
              f"标准差=${std_dev:>8,.0f}, 变异系数={std_dev / mean:.3f}")
    #低风险: 平均索赔=$  15,000, 标准差=$   8,660, 变异系数=0.577
    #中风险: 平均索赔=$  20,000, 标准差=$  14,142, 变异系数=0.707
    #高风险: 平均索赔=$  22,500, 标准差=$  18,371, 变异系数=0.816

    保费定价分析
    for risk_level, stats in claim_stats.items():
        base_premium = stats["mean_claim"] * 1.2  # 20%的安全边际
        risk_load = stats["cv"] * 0.1  # 风险附加费率

        total_premium = base_premium * (1 + risk_load)

        print(f"{risk_level:>8}: 基础保费=${base_premium:>8,.0f}, "
              f"风险附加={risk_load:.1%}, 总保费=${total_premium:>8,.0f}")
    #低风险: 基础保费=$  18,000, 风险附加=5.8%, 总保费=$  19,039
    #中风险: 基础保费=$  24,000, 风险附加=7.1%, 总保费=$  25,697
    #高风险: 基础保费=$  27,000, 风险附加=8.2%, 总保费=$  29,205

    风险资本计算
    confidence_level = 0.99
    for risk_level, stats in claim_stats.items():
        # 简化风险资本计算(基于正态近似)
        var_amount = stats["mean_claim"] + 2.33 * stats["std_dev"]  # 99% VaR
        capital_requirement = var_amount * 1.5  # 150%的VaR作为资本要求

        print(f"{risk_level:>8}: 99% VaR=${var_amount:>8,.0f}, "
              f"风险资本=${capital_requirement:>8,.0f}")
    #低风险: 99% VaR=$  35,178, 风险资本=$  52,768
    #中风险: 99% VaR=$  52,951, 风险资本=$  79,427
    #高风险: 99% VaR=$  65,305, 风险资本=$  97,957

    示例3. 医疗统计中的治疗时间分析

    medical_procedures = {
        "常规检查": {"shape": 3.0, "scale": 10},
        "小型手术": {"shape": 2.5, "scale": 20},
        "专科诊疗": {"shape": 2.0, "scale": 25},
        "急诊处理": {"shape": 1.8, "scale": 15}
    }

    医疗程序时间分布分析:

    treatment_stats = {}
    for procedure, params in medical_procedures.items():
        shape, scale = params["shape"], params["scale"]
        mean, variance = gamstat(f"({shape}, {scale})")
        std_dev = np.sqrt(variance)

        treatment_stats[procedure] = {
            "mean_time": mean,
            "std_dev": std_dev,
            "cv": std_dev / mean
        }

        print(f"{procedure:>8}: 平均时间={mean:>5.1f}分钟, "
              f"标准差={std_dev:>4.1f}分钟, 变异系数={std_dev / mean:.3f}")
    #常规检查: 平均时间= 30.0分钟, 标准差=17.3分钟, 变异系数=0.577
    #小型手术: 平均时间= 50.0分钟, 标准差=31.6分钟, 变异系数=0.632
    #专科诊疗: 平均时间= 50.0分钟, 标准差=35.4分钟, 变异系数=0.707
    #急诊处理: 平均时间= 27.0分钟, 标准差=20.1分钟, 变异系数=0.745

    手术室调度优化

    working_hours = 8 * 60  # 8小时工作制(分钟)
    buffer_factor = 0.2  # 20%的缓冲时间

    for procedure, stats in treatment_stats.items():
        scheduled_time = stats["mean_time"] * (1 + buffer_factor)
        procedures_per_day = working_hours / scheduled_time

        print(f"{procedure:>8}: 建议安排时间={scheduled_time:>4.0f}分钟, "
              f"每日可安排{procedures_per_day:>3.1f}台")
    #常规检查: 建议安排时间=  36分钟, 每日可安排13.3台
    #小型手术: 建议安排时间=  60分钟, 每日可安排8.0台
    #专科诊疗: 建议安排时间=  60分钟, 每日可安排8.0台
    #急诊处理: 建议安排时间=  32分钟, 每日可安排14.8台

    患者等待时间预测:

    arrival_rate = 4  # 每小时到达4个患者
    for procedure, stats in treatment_stats.items():
        service_rate = 60 / stats["mean_time"]  # 每小时服务患者数
        utilization = arrival_rate / service_rate

        if utilization < 1:
            # 排队论中的平均等待时间(M/G/1队列)
            avg_waiting_time = (utilization ** 2 + (stats["cv"]) ** 2) / (2 * service_rate * (1 - utilization)) * 60
            print(f"{procedure:>8}: 利用率={utilization:.2f}, 平均等待时间={avg_waiting_time:.1f}分钟")
        else:
            print(f"{procedure:>8}: 利用率={utilization:.2f} (系统不稳定)")
    #常规检查: 利用率=2.00 (系统不稳定)
    #小型手术: 利用率=3.33 (系统不稳定)
    #专科诊疗: 利用率=3.33 (系统不稳定)
    #急诊处理: 利用率=1.80 (系统不稳定)

    示例4. 金融风险管理中的波动率分析

    asset_classes = {
        "国债": {"shape": 4.0, "scale": 0.02},
        "蓝筹股": {"shape": 2.5, "scale": 0.05},
        "科技股": {"shape": 1.8, "scale": 0.08},
        "加密货币": {"shape": 1.2, "scale": 0.15}
    }

    资产波动率分布分析:

    volatility_stats = {}
    for asset_class, params in asset_classes.items():
        shape, scale = params["shape"], params["scale"]
        mean, variance = gamstat(shape, scale)
        std_dev = np.sqrt(variance)

        volatility_stats[asset_class] = {
            "mean_vol": mean,
            "std_dev": std_dev,
            "cv": std_dev / mean
        }

        print(f"{asset_class:>8}: 平均波动率={mean:>6.3f}, "
              f"标准差={std_dev:>6.3f}, 变异系数={std_dev / mean:.3f}")
    #国债: 平均波动率= 0.080, 标准差= 0.040, 变异系数=0.500
    #蓝筹股: 平均波动率= 0.125, 标准差= 0.079, 变异系数=0.632
    #科技股: 平均波动率= 0.144, 标准差= 0.107, 变异系数=0.745
    #加密货币: 平均波动率= 0.180, 标准差= 0.164, 变异系数=0.913

    风险调整回报分析

    expected_returns = {
        "国债": 0.03,
        "蓝筹股": 0.08,
        "科技股": 0.12,
        "加密货币": 0.20
    }

    for asset_class, stats in volatility_stats.items():
        sharpe_ratio = (expected_returns[asset_class] - 0.03) / stats["mean_vol"]  # 无风险利率3%

        print(f"{asset_class:>8}: 预期回报={expected_returns[asset_class]:.1%}, "
              f"夏普比率={sharpe_ratio:.2f}")
    #国债: 预期回报=3.0%, 夏普比率=0.00
    #蓝筹股: 预期回报=8.0%, 夏普比率=0.40
    #科技股: 预期回报=12.0%, 夏普比率=0.62
    #加密货币: 预期回报=20.0%, 夏普比率=0.94

    投资组合优化

    total_investment = 1000000  # 100万美元
    for asset_class, stats in volatility_stats.items():
        # 基于波动率倒数分配权重(简化方法)
        weight = 1 / stats["mean_vol"]
        print(f"{asset_class:>8}: 相对权重={weight:.2f}")
    #国债: 相对权重=12.50
    #蓝筹股: 相对权重=8.00
    #科技股: 相对权重=6.94
    #加密货币: 相对权重=5.56

    归一化权重
    total_weight = sum(1 / stats["mean_vol"] for stats in volatility_stats.values())

    实际投资金额:
    for asset_class, stats in volatility_stats.items():
        weight = (1 / stats["mean_vol"]) / total_weight
        investment = total_investment * weight
        print(f"{asset_class:>8}: 权重={weight:.1%}, 投资金额=${investment:,.0f}")
    #国债: 权重=37.9%, 投资金额=$378,788
    #蓝筹股: 权重=24.2%, 投资金额=$242,424
    #科技股: 权重=21.0%, 投资金额=$210,438
    #加密货币: 权重=16.8%, 投资金额=$168,350

    示例5. 环境科学中的降雨量分析

    climate_regions = {
        "干旱地区": {"shape": 1.8, "scale": 15},
        "半干旱地区": {"shape": 2.2, "scale": 30},
        "湿润地区": {"shape": 2.5, "scale": 60},
        "热带雨林": {"shape": 3.0, "scale": 100}
    }

    降雨量分布分析:

    rainfall_stats = {}
    for region, params in climate_regions.items():
        shape, scale = params["shape"], params["scale"]
        mean, variance = gamstat(shape, scale)
        std_dev = np.sqrt(variance)

        rainfall_stats[region] = {
            "mean_rainfall": mean,
            "std_dev": std_dev,
            "cv": std_dev / mean
        }

        print(f"{region:>8}: 平均降雨量={mean:>5.1f}mm, "
              f"标准差={std_dev:>4.1f}mm, 变异系数={std_dev / mean:.3f}")
    #干旱地区: 平均降雨量= 27.0mm, 标准差=20.1mm, 变异系数=0.745
    #半干旱地区: 平均降雨量= 66.0mm, 标准差=44.5mm, 变异系数=0.674
    #湿润地区: 平均降雨量=150.0mm, 标准差=94.9mm, 变异系数=0.632
    #热带雨林: 平均降雨量=300.0mm, 标准差=173.2mm, 变异系数=0.577

    干旱风险评估

    drought_thresholds = {
        "轻度干旱": 0.5,  # 平均降雨量的50%
        "中度干旱": 0.3,  # 平均降雨量的30%
        "严重干旱": 0.1  # 平均降雨量的10%
    }

    for region, stats in rainfall_stats.items():
        print(f"\n{region}:")
        for drought_level, threshold_ratio in drought_thresholds.items():
            threshold = stats["mean_rainfall"] * threshold_ratio
            # 简化干旱概率计算(基于正态近似)
            z_score = (threshold - stats["mean_rainfall"]) / stats["std_dev"]
            drought_probability = max(0, 0.5 * (1 + sp.erf(z_score / np.sqrt(2))))

            print(f"  {drought_level:>10}: 阈值={threshold:>4.1f}mm, "
                  f"发生概率={drought_probability:.1%}")
    #干旱地区:
    #    轻度干旱: 阈值=13.5mm, 发生概率=25.1%
    #    中度干旱: 阈值= 8.1mm, 发生概率=17.4%
    #    严重干旱: 阈值= 2.7mm, 发生概率=11.4%

    #半干旱地区:
    #    轻度干旱: 阈值=33.0mm, 发生概率=22.9%
    #    中度干旱: 阈值=19.8mm, 发生概率=15.0%
    #    严重干旱: 阈值= 6.6mm, 发生概率=9.1%

    #湿润地区:
    #    轻度干旱: 阈值=75.0mm, 发生概率=21.5%
    #    中度干旱: 阈值=45.0mm, 发生概率=13.4%
    #    严重干旱: 阈值=15.0mm, 发生概率=7.7%

    #热带雨林:
    #    轻度干旱: 阈值=150.0mm, 发生概率=19.3%
    #    中度干旱: 阈值=90.0mm, 发生概率=11.3%
    #    严重干旱: 阈值=30.0mm, 发生概率=6.0%

    水资源规划

    population_density = {
        "干旱地区": 50,  # 人/平方公里
        "半干旱地区": 100,  # 人/平方公里
        "湿润地区": 200,  # 人/平方公里
        "热带雨林": 150  # 人/平方公里
    }

    water_requirement = 100  # 每人每年100立方米

    for region, stats in rainfall_stats.items():
        # 简化水资源计算(假设10%的降雨可收集利用)
        collectable_water = stats["mean_rainfall"] * 0.1  # mm -> 立方米/公顷
        population_support = (collectable_water * 10000) / (water_requirement * population_density[region])

        print(f"{region:>8}: 可收集水量={collectable_water:.0f}立方米/公顷, "
              f"可支持人口密度={population_support:.0f}人/平方公里")
    #干旱地区: 可收集水量=3立方米/公顷, 可支持人口密度=5人/平方公里
    #半干旱地区: 可收集水量=7立方米/公顷, 可支持人口密度=7人/平方公里
    #湿润地区: 可收集水量=15立方米/公顷, 可支持人口密度=8人/平方公里
    #热带雨林: 可收集水量=30立方米/公顷, 可支持人口密度=20人/平方公里

    示例6. 矩阵输入的批量计算示例

    创建测试数据矩阵
    shape_params = [[1.5, 2.0, 2.5], [3.0, 3.5, 4.0]]  # 形状参数矩阵
    scale_params = [[10, 15, 20], [25, 30, 35]]  # 尺度参数矩阵

    形状参数矩阵:
    print(np.array(shape_params))
    #[[1.5 2.  2.5]
      [3.  3.5 4. ]]

    尺度参数矩阵:
    print(np.array(scale_params))
    #[[10 15 20]
      [25 30 35]]

    批量计算均值和方差
    means, variances = gamstat(shape_params, scale_params)

    print("\n均值矩阵:")
    print(means)
    print("\n方差矩阵:")
    print(variances)
    #均值矩阵:
    #[[ 15.  30.  50.]
      [ 75. 105. 140.]]

    #方差矩阵:
    #[[ 150.  450. 1000.]
      [1875. 3150. 4900.]]

    计算标准差和变异系数
    std_devs = np.sqrt(variances)
    coefficients_of_variation = std_devs / means

    print("\n标准差矩阵:")
    print(std_devs)
    print("\n变异系数矩阵:")
    print(coefficients_of_variation)
    #标准差矩阵:
    #[[12.24744871 21.21320344 31.6227766 ]
      [43.30127019 56.1248608  70.        ]]

    #变异系数矩阵:
    #[[0.81649658 0.70710678 0.63245553]
      [0.57735027 0.53452248 0.5       ]]

    实际应用:批量风险评估

    risk_categories = ["低风险", "中风险", "高风险", "极高风险"]

    for i in range(means.shape[0]):
        for j in range(means.shape[1]):
            mean_val = means[i, j]
            cv_val = coefficients_of_variation[i, j]

            # 基于均值和变异系数的风险评估
            if mean_val < 20 and cv_val < 0.5:
                risk_level = "低风险"
            elif mean_val < 50 and cv_val < 0.8:
                risk_level = "中风险"
            elif mean_val < 100 and cv_val < 1.2:
                risk_level = "高风险"
            else:
                risk_level = "极高风险"

            print(f"位置({i},{j}): 均值={mean_val:.1f}, 变异系数={cv_val:.3f} -> {risk_level}")
    #位置(0,0): 均值=15.0, 变异系数=0.816 -> 高风险
    #位置(0,1): 均值=30.0, 变异系数=0.707 -> 中风险
    #位置(0,2): 均值=50.0, 变异系数=0.632 -> 高风险
    #位置(1,0): 均值=75.0, 变异系数=0.577 -> 高风险
    #位置(1,1): 均值=105.0, 变异系数=0.535 -> 极高风险
    #位置(1,2): 均值=140.0, 变异系数=0.500 -> 极高风险
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    from sympy.stats import Gamma, E, variance
    import numpy as np


    def gamstat(k, theta):
        """
        计算Gamma分布的均值和方差,对标MATLAB的gamstat函数

        参数:
        k : 形状参数(shape parameter),可以是标量、向量或多维数组
        theta : 尺度参数(scale parameter),可以是标量、向量或多维数组

        返回:
        (mean, var) : 包含均值和方差的元组,形状与广播后的输入一致

        数学公式:
        均值 = k * theta
        方差 = k * theta^2
        """
        # 转换为NumPy数组
        k_arr = np.asarray(k, dtype=float)
        theta_arr = np.asarray(theta, dtype=float)

        # 检查参数有效性
        if np.any(k_arr <= 0) or np.any(theta_arr <= 0):
            raise ValueError("参数k和theta必须大于0")

        # 使用广播机制计算
        mean = k_arr * theta_arr
        var = k_arr * (theta_arr ** 2)

        return mean, var


    def gamma_mean_variance(input_str):
        """
        计算Gamma分布的均值和方差,对标MATLAB的gamstat函数。

        参数:
        input_str (str): 输入字符串,应能解析为包含形状参数a和比例参数b的元组。
                         支持标量、列表或矩阵形式,例如:"(2, 3)", "([1,2], [3,4])"。

        返回:
        tuple: 包含均值矩阵和方差矩阵的元组,若输入错误则返回错误信息字符串。

        示例:
        >>> gamma_mean_variance("(2, 3)")
        (6, 18)

        >>> gamma_mean_variance("([1, 2], [3, 4])")
        (Matrix([[3, 8]]), Matrix([[9, 32]]))

        >>> gamma_mean_variance("([1, 2], 2)")
        (Matrix([[2, 4]]), Matrix([[4, 16]]))
        """
        try:
            expr = sp.sympify(input_str)
            M, V = None, None  # 初始化均值和方差结果

            # 定义符号参数
            a_sym = sp.Symbol("a", positive=True)
            b_sym = sp.Symbol("b", positive=True)
            X = Gamma("X", a_sym, b_sym)  # 定义Gamma随机变量

            # 符号表达式计算均值和方差
            mean_expr = E(X)
            var_expr = variance(X)

            def eval_mean_var(a_val, b_val):
                """代入数值计算均值和方差"""
                return (
                    mean_expr.subs({a_sym: a_val, b_sym: b_val}).evalf(),
                    var_expr.subs({a_sym: a_val, b_sym: b_val}).evalf()
                )

            # 检查输入是否为二元组
            if not isinstance(expr, tuple) or len(expr) != 2:
                return f"输入错误: 需要形状参数a和比例参数b的二元组,当前输入: {input_str}"

            # 情况4: a和b均为标量
            if all(e.is_number for e in expr):
                params = tuple(float(e.evalf()) for e in expr)
                M, V = gamstat(*params)
            elif any(e.free_symbols for e in expr):
                M, V = eval_mean_var(*expr)
            else:
                raise ValueError(f"输入错误:{input_str}")

            return (M, V)

        except Exception as e:
            return f"错误: {str(e)}"


    # 示例代码
    if __name__ == "__main__":
        # 示例1: 标量参数
        print("示例1:", gamma_mean_variance("(2, 3)"))
        # (6.0, 18.0)
    
    
    广义自回归条件异方差模型拟合

    是特别用来建立条件方差模型并对其进行预测的.

    这些模型被运用于经济学领域,尤其是金融时间序列分析中.

    示例1. 股票收益率波动性分析

    模拟典型的股票日收益率数据(百分比形式)
    stock_returns = [
        0.52, -1.23, 0.78, 2.15, -0.89, -2.34, 1.67, 0.45, -1.56, 0.92,
        -0.67, 1.34, -2.01, 0.23, 1.89, -1.12, 0.56, -0.78, 2.34, -1.45,
        0.67, -2.12, 1.56, -0.89, 0.34, 1.23, -1.78, 0.45, -0.92, 2.67
    ]

    stock_result = GarchFit(stock_returns)

    print(f"参数估计: {stock_result['参数估计']}")
    print(f"模型类型: {stock_result['模型类型']}")
    print(f"AIC: {stock_result['AIC']:.4f}")
    #参数估计: {'均值': 6.699949696678251, '常数项': 10037.738334961734, 'ARCH(1)系数': 0.0, 'GARCH(1)系数': 0.5092528370787296}
    #模型类型: GARCH
    #AIC: 390.3290

    示例2. 汇率波动建模

    模拟汇率日变化率(特征:持续性波动)
    exchange_rate_changes = [
        0.12, -0.08, 0.05, -0.15, 0.03, 0.07, -0.02, -0.11, 0.09, -0.06,
        0.04, 0.01, -0.13, 0.08, -0.04, 0.11, -0.07, 0.02, -0.09, 0.06,
        -0.03, 0.10, -0.05, 0.07, -0.01, -0.12, 0.04, 0.09, -0.08, 0.03
    ]

    fx_result = GarchFit(exchange_rate_changes)
    print(f"ARCH系数: {fx_result['参数估计'].get('ARCH(1)系数', 'N/A')}")
    print(f"GARCH系数: {fx_result['参数估计'].get('GARCH(1)系数', 'N/A')}")
    #ARCH系数: 6.219731413742339e-14
    #GARCH系数: 0.9887817961831756

    示例3. 商品价格波动分析

    模拟商品价格收益率(特征:大幅波动)
    commodity_returns = [
        1.5, -2.3, 3.1, -1.8, 0.9, -3.2, 2.4, -0.7, 1.8, -2.1,
        3.5, -1.2, 0.6, -2.8, 1.9, -0.5, 2.7, -1.6, 0.8, -3.1,
        2.2, -0.9, 1.4, -2.5, 3.3, -1.1, 0.7, -2.9, 2.1, -0.8
    ]

    commodity_result = GarchFit(commodity_returns)
    print(f"条件波动率范围: {min(commodity_result['条件波动率']):.4f} - {max(commodity_result['条件波动率']):.4f}")
    #条件波动率范围: 205.5241 - 211.8954

    示例4. 市场恐慌期波动率建模

    模拟市场恐慌期的收益率(特征:极端波动)
    crisis_returns = [
        -0.5, -1.2, -3.8, 2.1, -4.5, 1.8, -5.2, -2.7, 3.4, -6.1,
        0.9, -3.9, -1.6, 4.2, -2.8, -5.7, 1.3, -4.8, -0.7, 2.9,
        -3.5, 0.6, -2.4, -4.1, 1.7, -5.9, -1.8, 3.2, -4.7, 0.8
    ]

    crisis_result = GarchFit(crisis_returns)
    print(f"波动率持续性: {crisis_result['参数估计'].get('GARCH(1)系数', 0) + crisis_result['参数估计'].get('ARCH(1)系数', 0):.4f}")
    #波动率持续性: 0.7127

    示例5. 低波动环境建模

    模拟低波动环境的收益率(特征:小幅波动)
    low_vol_returns = [
        0.1, -0.2, 0.3, -0.1, 0.2, -0.3, 0.1, 0.0, -0.2, 0.3,
        -0.1, 0.2, 0.0, -0.3, 0.1, -0.2, 0.3, -0.1, 0.2, -0.3,
        0.1, 0.0, -0.2, 0.3, -0.1, 0.2, 0.0, -0.3, 0.1, -0.2
    ]

    low_vol_result = GarchFit(low_vol_returns)
    print(f"常数项(omega): {low_vol_result['参数估计'].get('常数项', 'N/A')}")
    #常数项(omega): 194.94450723700578
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    from arch import arch_model


    def garchfit_regression_expression(input_str,model_type='Garch', p=1, q=1, dist='normal', update_freq=0):
        """
        对输入的时间序列数据进行 ARCH 模型拟合。

        参数:
        input_str: 输入的字符串表达式,表示时间序列数据(矩阵或列表)。

        返回:
        如果输入有效,则返回 ARCH 模型的拟合参数(以中文命名);否则返回错误信息。
        """
        try:
            # 将输入字符串转换为 SymPy 表达式
            expr = sp.sympify(input_str)

            # 检查输入是否为矩阵
            if isinstance(expr, list):
                # 将 SymPy 矩阵转换为 NumPy 数组并展平
                A = np.array(expr, dtype=float).ravel()
            else:
                return f"输入错误: {input_str}"

            # 使用 ARCH 模型进行拟合
            # 假设 p=1(ARCH(1) 模型),vol='ARCH'(ARCH 模型)
            am = arch_model(A * 100, vol='Garch', p=p, dist=dist)
            # 拟合模型,设置 update_freq=0 和 disp='off' 以关闭输出
            res = am.fit(update_freq=update_freq, disp=update_freq > 0)

            # 获取拟合参数
            params_dict = dict(res.params)

            # 创建一个新的字典,用于存储重命名后的参数
            renamed_params_dict = {}

            # 遍历原始字典,将键重命名为更具描述性的中文名称
            # 根据模型类型重命名参数
            for key, value in params_dict.items():
                if key == 'mu':
                    renamed_params_dict['均值'] = value
                elif key == 'omega':
                    renamed_params_dict['常数项'] = value
                elif key.startswith('alpha'):
                    idx = key.split('[')[1].split(']')[0] if '[' in key else '1'
                    renamed_params_dict[f'ARCH({idx})系数'] = value
                elif key.startswith('beta'):
                    idx = key.split('[')[1].split(']')[0] if '[' in key else '1'
                    renamed_params_dict[f'GARCH({idx})系数'] = value
                elif key == 'nu' and dist == 't':
                    renamed_params_dict['自由度'] = value
                elif key == 'lambda' and dist == 'skewt':
                    renamed_params_dict['偏度参数'] = value
                else:
                    renamed_params_dict[key] = value

            # 计算一些有用的统计量
            volatility = res.conditional_volatility
            residuals = res.resid

            # 返回结果字典
            result = {
                '参数估计': renamed_params_dict,
                '模型类型': model_type,
                '阶数': f"ARCH({p})" if model_type == 'ARCH' else f"GARCH({p},{q})",
                '误差分布': dist,
                '对数似然值': res.loglikelihood,
                'AIC': res.aic,
                'BIC': res.bic,
                '条件波动率': volatility.tolist(),
                '残差': residuals.tolist(),
                '模型摘要': str(res.summary())
            }

            return result
        except Exception as e:
            return f"错误: {e}"


    def main():
        """
        主函数,用于演示 archfit_regression_expression 函数的使用。
        """
        # 示范代码
        input_examples = [
            "[[1, 2, 3, 4, 5]]",  # 时间序列数据
            # 结果: {'均值': 2.999870510602842, '方差偏移': 1.9871738584685994, '方差系数': 0.00810550114746725}
            "[[0.1, 0.2, 0.3, 0.4, 0.5]]",  # 时间序列数据
            # 结果: {'均值': 0.2999917328352241, '方差偏移': 0.019852350048059936, '方差系数': 0.00921009134817112}
        ]

        for input_str in input_examples:
            print(f"输入: {input_str}")
            result = garchfit_regression_expression(input_str)
            print(f"结果: {result}")
            print("-" * 40)


    if __name__ == "__main__":
        main()
    
    
    高斯拟合

    gauss1: Y = a1*exp(-((x-b1)/c1)^2)

    gauss2: Y = a1*exp(-((x-b1)/c1)^2)+a2*exp(-((x-b2)/c2)^2)

    gauss3: Y = a1*exp(-((x-b1)/c1)^2)+...+a3*exp(-((x-b3)/c3)^2)

    gauss8: Y = a1*exp(-((x-b1)/c1)^2)+...+a8*exp(-((x-b8)/c8)^2)

    以此类推,最大到 gauss8

    示例1. 光谱分析 - 原子发射光谱

    模拟原子发射光谱数据(如钠双线)

    模拟钠的D线:589.0nm和589.6nm
    wavelength = np.linspace(580, 600, 200)

    # 两个高斯峰叠加,模拟钠双线
    intensity = (2.5 * np.exp(-((wavelength - 589.0) / 0.3) ** 2) +
                 2.0 * np.exp(-((wavelength - 589.6) / 0.25) ** 2) +
                 np.random.normal(0, 0.05, len(wavelength)))

    result = gaussfit(wavelength, intensity, 2)

    原子发射光谱拟合结果:
    print(f"拟合函数: {result}")
    #拟合函数: 2.0296*exp(-24176.6183185059*(0.00222861984692947*x - 1)**2) + 1.9706*exp(-64682.0349195574*(0.00136322559897747*x - 1)**2)

    绘制结果
    import matplotlib.pyplot as plt
    plt.figure(figsize=(10, 6))
    plt.plot(wavelength, intensity, 'b.', label='实验数据', alpha=0.6)

    计算拟合曲线
    x_fit = np.linspace(580, 600, 400)
    y_fit = [float(result.subs('x', xi)) for xi in x_fit]
    plt.plot(x_fit, y_fit, 'r-', label='高斯拟合', linewidth=2)

    plt.xlabel('波长 (nm)')
    plt.ylabel('强度')
    plt.title('钠原子发射光谱的高斯拟合')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.show()

    示例2. 物理实验 - X射线衍射峰

    模拟X射线衍射数据,晶体结构分析
    two_theta = np.linspace(10, 80, 500)

    模拟多晶材料的衍射峰
    intensity = (8.0 * np.exp(-((two_theta - 28.4) / 0.4) ** 2) +
                 6.5 * np.exp(-((two_theta - 32.8) / 0.35) ** 2) +
                 4.2 * np.exp(-((two_theta - 47.5) / 0.5) ** 2) +
                 3.8 * np.exp(-((two_theta - 56.2) / 0.45) ** 2) +
                 2.1 * np.exp(-((two_theta - 68.7) / 0.6) ** 2) +
                 np.random.normal(0, 0.2, len(two_theta)))

    result = gaussfit(two_theta, intensity, 5)

    X射线衍射分析拟合结果:
    print(f"拟合函数: {result}")
    #拟合函数: 7.8525*exp(-4687.60959974145*(0.0352200726237897*x - 1)**2) +
              6.522*exp(-8653.06115141254*(0.0304796274170345*x - 1)**2) +
              4.232*exp(-9901.89693628553*(0.0210547148875783*x - 1)**2) +
              3.5839*exp(-13661.0783125254*(0.0177947975129991*x - 1)**2) +
              1.9857*exp(-11578.3865102754*(0.0145459834903087*x - 1)**2)

    示例3. 生物医学 - 蛋白质电泳条带分析

    模拟蛋白质电泳条带的强度分布
    migration_distance = np.linspace(0, 100, 200)

    模拟不同分子量蛋白质的条带
    band_intensity = (15 * np.exp(-((migration_distance - 25) / 4) ** 2) +
                      12 * np.exp(-((migration_distance - 45) / 5) ** 2) +
                      8 * np.exp(-((migration_distance - 65) / 6) ** 2) +
                      20 * np.exp(-((migration_distance - 80) / 3) ** 2) +
                      np.random.normal(0, 0.3, len(migration_distance)))

    result = gaussfit(migration_distance, band_intensity, 4)

    蛋白质电泳条带分析结果:
    print(f"拟合函数: {result}")
    #拟合函数: 6.1472*exp(-1.7122351336583*(0.0182527716833801*x - 1)**2) +
              1.4598*exp(-24.2254686864556*(0.00824973600844773*x + 1)**2) +
              14.9839*exp(-621.758688213008*(0.00541764635771635*x - 1)**2) +
              17.188*exp(-5807.31813286032*(0.00224091795170239*x - 1)**2)
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    from scipy.optimize import curve_fit


    def gauss_fit_nonlinear(input_str):
        """
        使用非线性最小二乘法进行高斯曲线拟合,支持1到8阶高斯函数。

        参数:
        input_str: 字符串形式的输入数据,格式为"(x_data, y_data, n)",其中
                   x_data 和 y_data 是数据点,n 是要拟合的高斯函数阶数。

        返回:
        拟合后的高斯函数表达式(SymPy 表达式)或错误信息。
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            maxfev = 10000  # 最大函数评估次数

            # 定义1到8阶高斯函数
            def gauss1(x, a1, b1, c1):
                return a1 * np.exp(-((x - b1) / c1) ** 2)

            def gauss2(x, a1, b1, c1, a2, b2, c2):
                return gauss1(x, a1, b1, c1) + gauss1(x, a2, b2, c2)

            def gauss3(x, a1, b1, c1, a2, b2, c2, a3, b3, c3):
                return gauss2(x, a1, b1, c1, a2, b2, c2) + gauss1(x, a3, b3, c3)

            def gauss4(x, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4):
                return gauss3(x, a1, b1, c1, a2, b2, c2, a3, b3, c3) + gauss1(x, a4, b4, c4)

            def gauss5(x, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4, a5, b5, c5):
                return gauss4(x, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4) + gauss1(x, a5, b5, c5)

            def gauss6(x, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4, a5, b5, c5, a6, b6, c6):
                return gauss5(x, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4, a5, b5, c5) + gauss1(x, a6, b6, c6)

            def gauss7(x, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4, a5, b5, c5, a6, b6, c6, a7, b7, c7):
                return gauss6(x, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4, a5, b5, c5, a6, b6, c6) + gauss1(x, a7, b7,
                                                                                                                  c7)

            def gauss8(x, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4, a5, b5, c5, a6, b6, c6, a7, b7, c7, a8, b8, c8):
                return gauss7(x, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4, a5, b5, c5, a6, b6, c6, a7, b7,
                              c7) + gauss1(x, a8, b8, c8)

            # 解析输入数据
            if isinstance(expr, tuple):
                if len(expr) > 2:
                    x, y, n = expr[0], expr[1], int(expr[2])
                else:
                    x, y = expr[0], expr[1]
                    n = 1

                # 转换为NumPy数组
                if x is None or y is None:
                    raise ValueError("Invalid input format")
                x_data = np.array(x, dtype=float).ravel()
                y_data = np.array(y, dtype=float).ravel()
            else:
                raise ValueError("Input must be a tuple")

            # 参数边界设置 (a≥0, b∈ℝ, c≥0)
            lower_bounds = [0, -np.inf, 0] * n
            upper_bounds = [np.inf, np.inf, np.inf] * n
            param_bounds = (lower_bounds, upper_bounds)

            # 生成初始猜测参数
            initial_guess = []
            sorted_indices = np.argsort(x_data)
            sorted_x = x_data[sorted_indices]
            sorted_y = y_data[sorted_indices]

            # 通过寻找峰值改进初始猜测
            peak_indices = np.argsort(sorted_y)[-n:][::-1]  # 取最大的n个y值对应的索引
            peak_x = sorted_x[peak_indices]
            peak_x.sort()

            for i in range(n):
                a_guess = sorted_y[peak_indices[i]] - np.min(sorted_y)
                b_guess = peak_x[i]
                c_guess = (np.max(sorted_x) - np.min(sorted_x)) / (2 * n)
                initial_guess.extend([a_guess, b_guess, c_guess])

            # 选择对应阶数的高斯函数进行拟合
            gauss_funcs = [None, gauss1, gauss2, gauss3, gauss4,
                           gauss5, gauss6, gauss7, gauss8]
            if n < 1 or n > 8:
                raise ValueError("n must be between 1 and 8")

            params, _ = curve_fit(gauss_funcs[n], x_data, y_data,
                                  p0=initial_guess, maxfev=maxfev,
                                  bounds=param_bounds)

            # 生成拟合表达式
            terms = []
            for i in range(n):
                a, b, c = params[3 * i: 3 * i + 3]
                terms.append(f"{a:.4f}*exp(-((x - {b:.4f})/{c:.4f})**2)")
            return sp.sympify("+".join(terms))

        except Exception as e:
            return f"Error: {str(e)}"


    # 示例使用
    if __name__ == "__main__":
        # 生成测试数据(两个高斯峰叠加)
        x = np.linspace(0, 10, 100)
        y = 3 * np.exp(-(x - 2) ** 2 / 1) + 2 * np.exp(-(x - 7) ** 2 / 0.5) + np.random.normal(0, 0.1, 100)

        # 构造输入字符串(注意需要转换为Python列表)
        input_str = f"({x.tolist()}, {y.tolist()}, 2)"
        print(input_str)
        # 进行二阶高斯拟合
        result = gauss_fit_nonlinear(input_str)
        print("拟合结果:", result)
        # 3.0246*exp(-3.9764864633667*(0.500375281461096*x - 1)**2) + 2.0451*exp(-93.9532479488075*(0.143209027897119*x - 1)**2)
    
    
    高斯窗

    w = gausswin(L,std,sym=1) 返回一个长度为L个点的修正的高斯窗 默认sym=1

    当sym=1, 生成一个对称窗口,用于滤波器设计.

    当sym=0, 生成一个周期性窗口,用于光谱分析.

    示例1. 信号处理 - 频谱分析中的加窗

    在频谱分析中使用高斯窗减少频谱泄漏

    import matplotlib.pyplot as plt
    from scipy.fft import fft, fftfreq

    生成测试信号:两个频率分量
    fs = 1000  # 采样频率
    t = np.linspace(0, 1, fs, endpoint=False)
    signal_data = (1.0 * np.sin(2 * np.pi * 50 * t) +
                   0.5 * np.sin(2 * np.pi * 120 * t) +
                   0.2 * np.random.normal(0, 0.1, len(t)))

    应用不同参数的高斯窗
    windows = {
        '矩形窗(无窗)': np.ones(len(signal_data)),
        '高斯窗(α=2.5)': gausswin(len(t),2.5),
        '高斯窗(α=1.0)': gausswin(len(t),1.0),
        '高斯窗(α=0.4)': gausswin(len(t),0.4)
    }

    plt.figure(figsize=(12, 8))

    for i, (name, window) in enumerate(windows.items()):
        # 加窗
        windowed_signal = signal_data * window

        # 计算FFT
        fft_vals = fft(windowed_signal)
        freqs = fftfreq(len(t), 1 / fs)

        # 绘制频谱
        plt.subplot(2, 2, i + 1)
        plt.plot(freqs[:len(freqs) // 2], np.abs(fft_vals[:len(fft_vals) // 2]))
        plt.title(f'{name} - 频谱')
        plt.xlabel('频率 (Hz)')
        plt.ylabel('幅度')
        plt.grid(True, alpha=0.3)

        # 标记主要频率分量
        plt.axvline(x=50, color='r', linestyle='--', alpha=0.7, label='50Hz')
        plt.axvline(x=120, color='g', linestyle='--', alpha=0.7, label='120Hz')
        plt.legend()

    plt.tight_layout()
    plt.show()

    示例2. 图像处理 - 高斯模糊滤波器

    import matplotlib.pyplot as plt
    from scipy import ndimage

    创建测试图像(简单的几何形状)
    image = np.zeros((100, 100))

    在图像中心画一个矩形
    image[30:70, 30:70] = 1.0

    添加一些噪声
    image += 0.1 * np.random.normal(0, 1, image.shape)

    生成2D高斯窗(可分离滤波器)
    window_size = 15
    gauss_1d = gausswin(window_size,2.5)

    创建2D高斯滤波器
    gauss_2d = np.outer(gauss_1d, gauss_1d)
    gauss_2d = gauss_2d / np.sum(gauss_2d)  # 归一化

    应用高斯模糊
    blurred_image = ndimage.convolve(image, gauss_2d, mode='constant', cval=0.0)

    显示结果
    fig, axes = plt.subplots(1, 3, figsize=(15, 5))

    axes[0].imshow(image, cmap='gray')
    axes[0].set_title('原始图像')
    axes[0].axis('off')

    axes[1].imshow(gauss_2d, cmap='hot')
    axes[1].set_title('高斯滤波器')
    axes[1].axis('off')

    axes[2].imshow(blurred_image, cmap='gray')
    axes[2].set_title('高斯模糊后')
    axes[2].axis('off')

    plt.tight_layout()
    plt.show()

    示例3. 音频处理 - 语音信号的短时傅里叶变换

    import matplotlib.pyplot as plt

    生成模拟语音信号(啁啾信号)
    fs = 8000  # 采样率
    duration = 2  # 秒
    t = np.linspace(0, duration, int(fs * duration))

    创建频率变化的信号
    freq_sweep = 100 + 200 * t  # 频率从100Hz线性增加到500Hz
    audio_signal = np.sin(2 * np.pi * freq_sweep * t)

    添加一些突发信号模拟语音特性
    audio_signal[5000:5200] += 0.5 * np.sin(2 * np.pi * 800 * t[:200])
    audio_signal[12000:12200] += 0.3 * np.sin(2 * np.pi * 1200 * t[:200])

    STFT参数
    window_size = 256
    hop_size = 64

    生成高斯窗
    gauss_window = gausswin(window_size,3.0)

    计算STFT
    def compute_stft(signal, window, hop):
        num_frames = (len(signal) - window_size) // hop + 1
        stft_matrix = np.zeros((window_size // 2 + 1, num_frames), dtype=complex)

        for i in range(num_frames):
            start = i * hop
            frame = signal[start:start + window_size] * window
            spectrum = np.fft.rfft(frame)
            stft_matrix[:, i] = spectrum

        return stft_matrix

    stft_result = compute_stft(audio_signal, gauss_window, hop_size)

    绘制时频谱
    plt.figure(figsize=(12, 8))

    plt.subplot(2, 1, 1)
    plt.plot(t, audio_signal)
    plt.title('原始音频信号')
    plt.xlabel('时间 (s)')
    plt.ylabel('幅度')
    plt.grid(True, alpha=0.3)

    plt.subplot(2, 1, 2)
    显示频谱图
    spectrogram = 20 * np.log10(np.abs(stft_result) + 1e-10)
    plt.imshow(spectrogram, aspect='auto', origin='lower',
               extent=[0, duration, 0, fs / 2], cmap='viridis')
    plt.title('STFT时频谱(高斯窗)')
    plt.xlabel('时间 (s)')
    plt.ylabel('频率 (Hz)')
    plt.colorbar(label='幅度 (dB)')

    plt.tight_layout()
    plt.show()

    示例4. 数字滤波器设计 - FIR滤波器

    import matplotlib.pyplot as plt

    滤波器规格
    filter_order = 64  # 滤波器阶数
    cutoff_freq = 0.2  # 归一化截止频率 (0.5对应奈奎斯特频率)

    设计理想低通滤波器的冲激响应
    n = np.arange(-filter_order // 2, filter_order // 2 + 1)
    ideal_response = 2 * cutoff_freq * np.sinc(2 * cutoff_freq * n)

    应用不同参数的高斯窗
    windows = {
        '矩形窗': np.ones(len(n)),
        '高斯窗(α=2.5)': gausswin(len(n),2.5),
        '高斯窗(α=1.5)': gausswin(len(n),1.5),
        '高斯窗(α=0.8)': gausswin(len(n),0.8)
    }

    plt.figure(figsize=(12, 10))

    for i, (name, window) in enumerate(windows.items()):
        # 加窗得到实际滤波器系数
        fir_coeff = ideal_response * window

        # 计算频率响应
        w, h = signal.freqz(fir_coeff)
        freq = w / np.pi  # 归一化频率

        # 绘制频率响应
        plt.subplot(2, 2, i + 1)
        plt.plot(freq, 20 * np.log10(np.abs(h) + 1e-10))
        plt.axvline(x=cutoff_freq, color='r', linestyle='--', alpha=0.7, label='截止频率')
        plt.title(f'{name} - 频率响应')
        plt.xlabel('归一化频率 (×π rad/sample)')
        plt.ylabel('幅度 (dB)')
        plt.grid(True, alpha=0.3)
        plt.legend()
        plt.ylim([-100, 5])

    plt.tight_layout()
    plt.show()

    示例5. 数据平滑 - 时间序列滤波

    import matplotlib.pyplot as plt

    生成带噪声的时间序列数据(模拟股票价格)
    np.random.seed(42)
    t = np.linspace(0, 100, 500)

    基础趋势 + 季节性 + 噪声
    trend = 0.02 * t
    seasonal = 2 * np.sin(2 * np.pi * t / 20)
    noise = 0.5 * np.random.normal(0, 1, len(t))

    time_series = 50 + trend + seasonal + noise

    创建不同宽度的高斯平滑滤波器
    window_sizes = [10, 25, 50]

    plt.figure(figsize=(12, 8))
    plt.plot(t, time_series, 'b-', alpha=0.3, label='原始数据', linewidth=1)

    for window_size in window_sizes:
        # 生成高斯窗
        gauss_window = gausswin(window_size,2.0)
        gauss_window = gauss_window / np.sum(gauss_window)  # 归一化

        # 应用卷积进行平滑
        smoothed = np.convolve(time_series, gauss_window, mode='same')

        plt.plot(t, smoothed, linewidth=2,
                 label=f'高斯平滑 (窗口大小={window_size})')

    plt.title('时间序列数据的高斯平滑')
    plt.xlabel('时间')
    plt.ylabel('数值')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.show()

    示例6. 峰值检测 - 信号预处理

    import matplotlib.pyplot as plt

    生成带多个峰值的信号
    t = np.linspace(0, 10, 1000)

    创建多个高斯峰叠加的信号
    peaks = [
        (1.0, 2.0, 0.3),  # (幅度, 位置, 宽度)
        (0.8, 4.0, 0.2),
        (1.2, 6.0, 0.4),
        (0.9, 8.0, 0.25)
    ]

    clean_signal = np.zeros_like(t)
    for amp, pos, width in peaks:
        clean_signal += amp * np.exp(-((t - pos) / width) ** 2)

    # 添加噪声
    noisy_signal = clean_signal + 0.1 * np.random.normal(0, 1, len(t))

    使用高斯窗进行平滑以改善峰值检测
    gauss_window = gausswin(51,1.5)
    gauss_window = gauss_window / np.sum(gauss_window)
    smoothed_signal = np.convolve(noisy_signal, gauss_window, mode='same')

    峰值检测
    peaks_clean, _ = signal.find_peaks(clean_signal, height=0.5)
    peaks_noisy, _ = signal.find_peaks(noisy_signal, height=0.5)
    peaks_smoothed, _ = signal.find_peaks(smoothed_signal, height=0.5)

    绘制结果
    plt.figure(figsize=(12, 8))

    plt.subplot(3, 1, 1)
    plt.plot(t, clean_signal, 'b-', label='原始信号')
    plt.plot(t[peaks_clean], clean_signal[peaks_clean], 'ro', label='检测到的峰值')
    plt.title('无噪声信号峰值检测')
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.subplot(3, 1, 2)
    plt.plot(t, noisy_signal, 'g-', label='带噪声信号', alpha=0.7)
    plt.plot(t[peaks_noisy], noisy_signal[peaks_noisy], 'ro', label='检测到的峰值')
    plt.title('带噪声信号峰值检测')
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.subplot(3, 1, 3)
    plt.plot(t, smoothed_signal, 'm-', label='高斯平滑后信号')
    plt.plot(t[peaks_smoothed], smoothed_signal[peaks_smoothed], 'ro', label='检测到的峰值')
    plt.title('高斯平滑后峰值检测')
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import scipy.signal as signal


    def gausswin_window(input_str):
        """
        对标MATLAB的gausswin函数,生成高斯窗口。

        参数:
        input_str (str): 输入的参数字符串,格式应为 "M", "M, alpha" 或 "M, alpha, sym_flag"
            - M: 窗口长度(正整数)
            - alpha: 高斯窗的alpha参数(正数,默认2.5),对应MATLAB中的alpha,与标准差σ的关系为σ = (M-1)/(2*alpha)
            - sym_flag: 可选参数,0表示非对称窗口(sym=False),其他值表示对称窗口(默认,sym=True)

        返回:
        list: 高斯窗口数组,或错误信息字符串。
        """
        try:
            expr = sp.sympify(input_str)
            m = None
            alpha = 2.5  # MATLAB默认alpha为2.5
            sym = True  # 默认对称窗口

            # 解析输入参数
            if isinstance(expr, (int, sp.Integer, float, sp.Float)):
                # 单个参数,例如 "64"
                m = int(expr)
            elif isinstance(expr, tuple):
                # 元组参数,例如 "64, 0.4" 或 "64, 0.4, 0"
                if len(expr) >= 1:
                    m = int(expr[0])
                if len(expr) >= 2:
                    alpha = float(expr[1])
                if len(expr) >= 3:
                    # 处理第三个参数(sym_flag)
                    sym_flag = str(expr[2])
                    sym = False if sym_flag == '0' else True
                if len(expr) > 3:
                    raise ValueError("参数过多,最多支持3个参数")
            else:
                return f"输入错误:无法解析的参数格式 '{input_str}'"

            # 参数有效性检查
            if m is None or m <= 0:
                return "错误:窗口长度M必须为正整数"
            if alpha <= 0:
                return "错误:alpha必须为正数"

            # 计算标准差σ,根据MATLAB公式 σ = (M-1)/(2*alpha)
            std = (m - 1) / (2 * alpha)

            # 生成高斯窗口
            window = signal.windows.gaussian(m, std, sym)

            return list(window)
        except Exception as e:
            return f"错误:{e}"


    # 示例代码
    if __name__ == "__main__":
        # 示例1:默认参数(M=64, alpha=2.5, sym=True)
        print("示例1 默认参数:", gausswin_window("64")[:5])
        # [0.04393693362340742, 0.053411098929097026, 0.06452050267116646, 0.0774512497553297, 0.09238970420181072]

        # 示例2:自定义alpha(M=64, alpha=0.4, sym=True)
        print("示例2 自定义alpha:", gausswin_window("64,0.4")[:5])
        # [0.9231163463866358, 0.9277423175922188, 0.9322411350082428, 0.936610727772961, 0.9408490778060681]

        # 示例3:非对称窗口(M=64, alpha=0.4, sym=False)
        print("示例3 非对称窗口:", gausswin_window("64,0.4,0")[:5])
        # [0.9207563392996183, 0.9254450947656505, 0.9300077511714193, 0.9344422118574613, 0.938746432156527]
    
    
    最大公约数

    G = gcd(A,B,v=0) 返回 A 和 B 的元素的最大公约数. G 中的元素始终是非负值, gcd(0,0) 返回 0. 此语法支持任何数值类型的输入

    [G,U,V] = gcd(A,B,v=1) 还返回 Bézout 系数 U 和 V,它们满足:A.*U + B.*V = G。Bézout 系数用于对 Diophantine 方程求解。

    A,B — 输入值,标量,向量或实整数值数组

    示例1. 分数简化 - 数学计算

    fractions = [
        (24, 36),
        (48, 60),
        (125, 75),
        (81, 27),
        (17, 51)
    ]

    for numerator, denominator in fractions:
        # 计算GCD
        gcd_result = gcd(numerator, denominator)

        # 简化分数
        simplified_num = numerator // gcd_result
        simplified_den = denominator // gcd_result

        print(f"{numerator}/{denominator} = {simplified_num}/{simplified_den} (GCD: {gcd_result})")
    #24/36 = 2/3 (GCD: 12)
    #48/60 = 4/5 (GCD: 12)
    #125/75 = 5/3 (GCD: 25)
    #81/27 = 3/1 (GCD: 27)
    #17/51 = 1/3 (GCD: 17)

    示例2. 时间周期同步 - 物理系统

    三个行星的公转周期(天)
    planet_periods = [88, 225, 365]  # 水星、金星、地球

    计算它们同时回到起点的最小时间(最小公倍数)
    def lcm(a, b):
        return abs(a * b) // gcd(a, b)

    def lcm_multiple(numbers):
        result = 1
        for num in numbers:
            result = lcm(result, num)
        return result

    sync_time = lcm_multiple(planet_periods)

    print(f"行星公转周期: {planet_periods} 天")
    print(f"它们同时回到起点需要: {sync_time} 天")
    print(f"即大约 {sync_time / 365:.1f} 年")
    #行星公转周期: [88, 225, 365] 天
    #它们同时回到起点需要: 1445400 天
    #即大约 3960.0 年

    验证GCD计算
    for i in range(len(planet_periods)):
        for j in range(i + 1, len(planet_periods)):
            gcd_val = gcd(planet_periods[i], planet_periods[j])
            print(f"GCD({planet_periods[i]}, {planet_periods[j]}) = {gcd_val}")
    #GCD(88, 225) = 1
    #GCD(88, 365) = 1
    #GCD(225, 365) = 5

    示例3. 密码学 - RSA算法中的密钥生成

    选择两个质数
    p, q = 61, 53

    计算n和φ(n)
    n = p * q
    phi_n = (p - 1) * (q - 1)

    选择的质数: p = {p}, q = {q}
    print(f"n = p × q = {n}")
    print(f"φ(n) = (p-1)(q-1) = {phi_n}")
    #n = p × q = 3233
    #φ(n) = (p-1)(q-1) = 3120

    选择加密指数e,需要满足 gcd(e, φ(n)) = 1
    possible_e_values = [3, 5, 7, 11, 13, 17, 19, 23, 29, 31]

    寻找合适的加密指数e:
    for e in possible_e_values:
        gcd_val = gcd(e, phi_n)
        status = "✓ 合适" if gcd_val == 1 else "✗ 不合适"
        print(f"e = {e}: gcd({e}, {phi_n}) = {gcd_val} {status}")
    #e = 3: gcd(3, 3120) = 3 ✗ 不合适
    #e = 5: gcd(5, 3120) = 5 ✗ 不合适
    #e = 7: gcd(7, 3120) = 1 ✓ 合适
    #e = 11: gcd(11, 3120) = 1 ✓ 合适
    #e = 13: gcd(13, 3120) = 13 ✗ 不合适
    #e = 17: gcd(17, 3120) = 1 ✓ 合适
    #e = 19: gcd(19, 3120) = 1 ✓ 合适
    #e = 23: gcd(23, 3120) = 1 ✓ 合适
    #e = 29: gcd(29, 3120) = 1 ✓ 合适
    #e = 31: gcd(31, 3120) = 1 ✓ 合适

    选择第一个合适的e
    e = next(e for e in possible_e_values if gcd(e, phi_n) == 1)

    print(f"\n选择的加密指数: e = {e}")
    #选择的加密指数: e = 7

    使用扩展欧几里得算法计算解密指数d
    gcd_result = gcd(e, phi_n, 1)
    g, d, _ = gcd_result
    # 确保d是正数
    d = d[0] if d[0] > 0 else d[0] + phi_n

    print(f"计算的解密指数: d = {d}")
    print(f"验证: e × d mod φ(n) = {e} × {d} mod {phi_n} = {(e * d) % phi_n}")
    #计算的解密指数: d = 1783
    #验证: e × d mod φ(n) = 7 × 1783 mod 3120 = 1

    示例4. 工程测量 - 齿轮传动比

    齿轮系统的设计需求
    required_ratio_numerator = 120
    required_ratio_denominator = 75

    计算GCD来简化传动比
    gcd_val = gcd(required_ratio_numerator, required_ratio_denominator)

    simplified_numerator = required_ratio_numerator // gcd_val
    simplified_denominator = required_ratio_denominator // gcd_val

    print(f"原始传动比: {required_ratio_numerator}:{required_ratio_denominator}")
    print(f"最大公约数: {gcd_val}")
    print(f"简化传动比: {simplified_numerator}:{simplified_denominator}")
    #原始传动比: 120:75
    #最大公约数: 15
    #简化传动比: 8:5

    实际齿轮齿数选择(考虑制造限制)
    min_teeth = 15
    max_teeth = 120

    寻找满足比例且在限制范围内的齿数
    multiplier = 1
    while True:
        gear1 = simplified_numerator * multiplier
        gear2 = simplified_denominator * multiplier

        if gear1 <= max_teeth and gear2 <= max_teeth and gear1 >= min_teeth and gear2 >= min_teeth:
            break
        multiplier += 1

    推荐的齿轮齿数:
    print(f"主动轮: {gear1} 齿")
    print(f"从动轮: {gear2} 齿")
    print(f"实际传动比: {gear1}:{gear2} = {gear1 / gear2:.3f}")
    #主动轮: 24 齿
    #从动轮: 15 齿
    #实际传动比: 24:15 = 1.600

    验证GCD
    verification_gcd = gcd_number(f"{gear1}, {gear2}")
    print(f"验证GCD({gear1}, {gear2}) = {verification_gcd}")
    #验证GCD(24, 15) = 3

    示例5. 计算机图形学 - 像素比例简化

    常见屏幕分辨率
    resolutions = [
        (1920, 1080),
        (2560, 1440),
        (3840, 2160),
        (2560, 1080),
        (3440, 1440),
        (1920, 1200),
        (1680, 1050),
    ]

    屏幕分辨率比例分析:
    for width, height in resolutions:
        gcd_val = gcd(width, height)
        aspect_width = width // gcd_val
        aspect_height = height // gcd_val

        print(f"{width}×{height} → 比例 {aspect_width}:{aspect_height} (GCD: {gcd_val})")
    #1920×1080 → 比例 16:9 (GCD: 120)
    #2560×1440 → 比例 16:9 (GCD: 160)
    #3840×2160 → 比例 16:9 (GCD: 240)
    #2560×1080 → 比例 64:27 (GCD: 40)
    #3440×1440 → 比例 43:18 (GCD: 80)
    #1920×1200 → 比例 8:5 (GCD: 240)
    #1680×1050 → 比例 8:5 (GCD: 210)

    图像缩放时的比例保持
    original_width, original_height = 1200, 800
    target_width = 600

    gcd_val = gcd(original_width, original_height)
    aspect_ratio = original_width / original_height

    计算保持比例的目标高度
    target_height = int(target_width / aspect_ratio)

    print(f"原始尺寸: {original_width}×{original_height} (比例 {original_width // gcd_val}:{original_height // gcd_val})")
    print(f"缩放宽度到: {target_width}")
    print(f"保持比例的高度: {target_height}")
    #原始尺寸: 1200×800 (比例 3:2)
    #缩放宽度到: 600
    #保持比例的高度: 400

    验证新尺寸的GCD
    new_gcd = gcd(target_width, target_height)
    print(f"新尺寸比例: {target_width // new_gcd}:{target_height // new_gcd}")
    #新尺寸比例: 3:2

    示例6. 音乐理论 - 节拍和节奏

    不同音符的时值(以最小时间单位为1)
    note_durations = {
        "全音符": 16,
        "二分音符": 8,
        "四分音符": 4,
        "八分音符": 2,
        "十六分音符": 1
    }

    计算各种音符组合的GCD来确定最小时间单位
    durations = list(note_durations.values())

    计算所有时值的GCD
    current_gcd = durations[0]
    for duration in durations[1:]:
        current_gcd = gcd(current_gcd, duration)

    音符时值系统:
    for note, duration in note_durations.items():
        relative_duration = duration // current_gcd
        print(f"{note}: {duration} → 相对时值 {relative_duration}")
    #全音符: 16 → 相对时值 16
    #二分音符: 8 → 相对时值 8
    #四分音符: 4 → 相对时值 4
    #八分音符: 2 → 相对时值 2
    #十六分音符: 1 → 相对时值 1

    print(f"\n最小时间单位: {current_gcd}")
    #最小时间单位: 1

    节奏模式分析
    rhythm_patterns = [
        [4, 4, 4, 4],  # 4/4拍
        [4, 4, 2],  # 3/4拍
        [8, 8, 4, 8, 8],  # 复合节奏
        [2, 2, 2, 2, 2, 2],  # 6/8拍
    ]

    节奏模式分析:
    for i, pattern in enumerate(rhythm_patterns):
        pattern_gcd = pattern[0]
        for duration in pattern[1:]:
            pattern_gcd = gcd(pattern_gcd, duration)

        simplified_pattern = [d // pattern_gcd for d in pattern]
        print(f"模式 {i + 1}: {pattern} → 简化 {simplified_pattern} (GCD: {pattern_gcd})")
    #模式 1: [4, 4, 4, 4] → 简化 [1, 1, 1, 1] (GCD: 4)
    #模式 2: [4, 4, 2] → 简化 [2, 2, 1] (GCD: 2)
    #模式 3: [8, 8, 4, 8, 8] → 简化 [2, 2, 1, 2, 2] (GCD: 4)
    #模式 4: [2, 2, 2, 2, 2, 2] → 简化 [1, 1, 1, 1, 1, 1] (GCD: 2)

    示例7. 资源分配 - 最优包装方案

    仓库包装问题:有不同尺寸的箱子,要装满固定容量的货柜
    box_sizes = [12, 18, 24]  # 三种箱子的容量
    container_capacity = 360  # 货柜总容量

    计算所有箱子尺寸的GCD
    gcd_all = box_sizes[0]
    for size in box_sizes[1:]:
        gcd_all = gcd(gcd_all, size)

    print(f"箱子尺寸: {box_sizes}")
    print(f"所有箱子尺寸的GCD: {gcd_all}")
    print(f"货柜容量: {container_capacity}")
    #箱子尺寸: [12, 18, 24]
    #所有箱子尺寸的GCD: 6
    #货柜容量: 360

    检查货柜容量是否能被GCD整除
    if container_capacity % gcd_all == 0:
        print("✓ 货柜可以被完全装满")
    else:
        print("✗ 货柜无法被完全装满")
        print(f"最大可利用容量: {container_capacity - (container_capacity % gcd_all)}")
    #✓ 货柜可以被完全装满

    寻找最优包装方案
    solutions = []

    for count1 in range(container_capacity // box_sizes[0] + 1):
        for count2 in range(container_capacity // box_sizes[1] + 1):
            for count3 in range(container_capacity // box_sizes[2] + 1):
                total = count1 * box_sizes[0] + count2 * box_sizes[1] + count3 * box_sizes[2]
                if total == container_capacity:
                    solutions.append((count1, count2, count3))

    if solutions:
        print(f"找到 {len(solutions)} 种包装方案")
        for i, sol in enumerate(solutions[:3]):  # 只显示前3种方案
            print(f"方案 {i + 1}: {sol[0]}个{box_sizes[0]}箱 + {sol[1]}个{box_sizes[1]}箱 + {sol[2]}个{box_sizes[2]}箱")
    else:
        print("没有找到完全装满的方案")
    #找到 91 种包装方案
    #方案 1: 0个12箱 + 0个18箱 + 15个24箱
    #方案 2: 0个12箱 + 4个18箱 + 12个24箱
    #方案 3: 0个12箱 + 8个18箱 + 9个24箱

    示例8. 数论问题 - 扩展欧几里得算法应用

    线性同余方程求解:ax ≡ b (mod m)
    equations = [
        (7, 3, 11),  # 7x ≡ 3 (mod 11)
        (15, 6, 21),  # 15x ≡ 6 (mod 21)
        (8, 5, 12),  # 8x ≡ 5 (mod 12)
    ]

    for a, b, m in equations:
        print(f"\n求解方程: {a}x ≡ {b} (mod {m})")

        # 计算 gcd(a, m)
        gcd_am = gcd(a, m)
        print(f"gcd({a}, {m}) = {gcd_am}")

        # 检查解的存在性
        if b % gcd_am != 0:
            print("无解,因为 gcd(a,m) 不能整除 b")
            continue

        # 使用扩展欧几里得算法求特解
        result = gcd(f"{a}, {m}, 1")
        if isinstance(result, tuple):
            g, u, v = result
            u_val, v_val = u[0], v[0]

            print(f"扩展欧几里得结果: {a}×({u_val}) + {m}×({v_val}) = {g}")

            # 计算特解
            x0 = (u_val * (b // g)) % m
            if x0 < 0:
                x0 += m

            print(f"特解: x₀ = {x0}")

            # 所有解
            if gcd_am > 1:
                print(f"所有解: x ≡ {x0} + k×{m // gcd_am} (mod {m}), k=0,1,...,{gcd_am - 1}")
                solutions = [(x0 + k * (m // gcd_am)) % m for k in range(gcd_am)]
                print(f"具体解: {solutions}")
            else:
                print(f"唯一解: x ≡ {x0} (mod {m})")

            # 验证
            verification = (a * x0) % m
            print(f"验证: {a}×{x0} mod {m} = {verification} ≡ {b} (mod {m})")
    #求解方程: 7x ≡ 3 (mod 11)
    #gcd(7, 11) = 1
    #扩展欧几里得结果: 7×(-3) + 11×(2) = [1]
    #特解: x₀ = [2]
    #唯一解: x ≡ [2] (mod 11)
    #验证: 7×[2] mod 11 = [3] ≡ 3 (mod 11)

    #求解方程: 15x ≡ 6 (mod 21)
    #gcd(15, 21) = 3
    #扩展欧几里得结果: 15×(3) + 21×(-2) = [3]
    #特解: x₀ = [6]
    #所有解: x ≡ [6] + k×7 (mod 21), k=0,1,...,2
    #具体解: [array([6]), array([13]), array([20])]
    #验证: 15×[6] mod 21 = [6] ≡ 6 (mod 21)

    #求解方程: 8x ≡ 5 (mod 12)
    #gcd(8, 12) = 4
    #无解,因为 gcd(a,m) 不能整除 b
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np

    def gcd_number(input_str):
        """
        对标MATLAB的gcd函数,计算最大公约数及Bézout系数

        参数:
        input_str (str): 输入的参数字符串,格式应为 "a, b"(支持标量或矩阵)

        返回:
        tuple: (G, U, V) 包含最大公约数和Bézout系数的矩阵/标量
        str: 错误信息(格式错误/非整数输入/矩阵形状不匹配等)

        功能说明:
        1. 支持标量计算:gcd(6,15) → (3, -2, 1)
        2. 支持矩阵计算:逐元素计算gcd
        3. 自动处理标量与矩阵的广播
        4. 返回Bézout系数满足 a*u + b*v = gcd(a,b)
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            def extended_gcd(a, b):
                # 转换为 NumPy 数组并确保是整数类型
                a0 = np.array(a, dtype=np.int64, ndmin=1, copy=False)
                b0 = np.array(b, dtype=np.int64, ndmin=1, copy=False)

                # 应用广播规则
                a_broadcast, b_broadcast = np.broadcast_arrays(a0, b0)

                # 初始化结果数组
                shape = a_broadcast.shape
                g_arr = np.zeros(shape, dtype=np.int64)
                u_arr = np.zeros(shape, dtype=np.int64)
                v_arr = np.zeros(shape, dtype=np.int64)

                # 对每个元素单独计算扩展欧几里得算法
                for idx in np.ndindex(shape):
                    a_val = a_broadcast[idx]
                    b_val = b_broadcast[idx]

                    sign_a = np.sign(a_val) if a_val != 0 else 1
                    sign_b = np.sign(b_val) if b_val != 0 else 1

                    a1 = np.abs(a_val)
                    b1 = np.abs(b_val)

                    u, v = 1, 0
                    u1, v1 = 0, 1

                    while b1 != 0:
                        q = a1 // b1
                        r = a1 % b1
                        new_u = u - q * u1
                        new_v = v - q * v1

                        a1, b1 = b1, r
                        u, v = u1, v1
                        u1, v1 = new_u, new_v

                    g_arr[idx] = a1
                    u_arr[idx] = u * sign_a
                    v_arr[idx] = v * sign_b

                return g_arr, u_arr, v_arr

            # 检查传入的 expr 是否为元组类型
            if isinstance(expr, tuple):
                # 如果 expr 是一个长度为 3 的元组
                if len(expr) == 3:
                    # 从元组中提取第一个元素作为底数 n(这里注释提到 base b 可能有误,推测应该是 base n)
                    n = expr[0]
                    # 从元组中提取第二个元素
                    x = expr[1]
                    # 将元组中的第三个元素转换为整数类型
                    v = int(expr[2])
                    # 检查 v 是否既不等于 0 也不等于 1
                    if v != 0 and v != 1:
                        # 如果不满足条件,抛出 ValueError 异常,提示参数必须是 0 或 1
                        raise ValueError("参数必须是0或1")
                # 如果 expr 是一个长度为 2 的元组
                elif len(expr) == 2:
                    # 从元组中提取第一个元素作为底数 n
                    n = expr[0]
                    # 从元组中提取第二个元素
                    x = expr[1]
                    # 将 v 的值设为 0
                    v = 0

                if v == 0:
                    result = np.gcd(n, x)
                else:
                    result = extended_gcd(n, x)
            # 如果 expr 不是元组类型
            else:
                # 将错误标志设为 True
                error = True

            return result if not error else f"输入错误: {input_str}"

        except Exception as e:
            return f"输入错误:{input_str}"


    # 示例代码 ======================================================================
    if __name__ == "__main__":
        # 示例1:标量计算
        print("示例1:gcd(6, 15, 1)")
        result = gcd_number("6, 15, 1")
        print(result)
        print("\n")
        # (array([3]), array([-2]), array([1]))

        # 示例2:
        test_input = "12,15"
        print("输入:", test_input)
        result = gcd_number(test_input)
        print(result)
        print("\n")
        # 3

        test_input = "5, 15, 1"
        print("输入:", test_input)
        result = gcd_number(test_input)
        print(result)
        print("\n")
        # (array([5]), array([1]), array([0]))
    
    
    最大公约数矩阵

    A = gcdmat(n) 返回 n×n 矩阵,其 A(i,j) 等于 gcd(i,j)

    对于所有非负r, 矩阵 A 是对称正定矩阵, A^r 是对称半正定矩阵

    n — 输入,标量
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    def generate_gcd_matrix(n):
        """
        生成n×n的GCD矩阵,其中元素A[i][j] = gcd(i+1, j+1)

        参数:
        n (int): 矩阵维度(正整数)

        返回:
        np.ndarray: 生成的GCD矩阵
        """
        # 初始化n×n的零矩阵
        A = np.zeros((n, n), dtype=int)
        # 遍历每个元素计算gcd(注意i和j从0开始,对应1-based编号)
        for i in range(n):
            for j in range(n):
                A[i][j] = sp.gcd(i + 1, j + 1)
        return A


    def gcdmat_matrix(input_str):
        """
        根据输入字符串生成GCD矩阵

        参数:
        input_str (str): 输入的矩阵维度字符串表达式(需能解析为正整数)

        返回:
        sp.Matrix | str: 生成的Sympy矩阵对象或错误信息
        """
        try:
            # 将输入字符串解析为Sympy表达式
            expr = sp.sympify(input_str)

            # 检查是否为有效正整数
            if not expr.is_integer:  # 检查数学上是否为整数
                return f"错误:输入必须为整数,但收到 {input_str}"
            n = int(expr)  # 转换为Python整数
            if n <= 0:
                return f"错误:维度必须为正整数,但收到 {n}"

            # 生成矩阵并转换为Sympy矩阵对象
            return sp.Matrix(generate_gcd_matrix(n))

        except sp.SympifyError:
            return f"解析错误:'{input_str}' 不是有效的数学表达式"
        except Exception as e:
            return f"运行时错误:{str(e)}"


    if __name__ == "__main__":
        # 示例测试代码
        test_cases = [
            "3",
            # Matrix([[1, 1, 1],
            #         [1, 2, 1],
            #         [1, 1, 3]])

            "4"
            # Matrix([[1, 1, 1, 1],
            #         [1, 2, 1, 2],
            #         [1, 1, 3, 1],
            #         [1, 2, 1, 4]])
            ]

        for case in test_cases:
            print(f"输入 '{case}':")
            result = gcdmat_matrix(case)
            if isinstance(result, sp.Matrix):
                print(f"生成的 {result.rows}x{result.cols} 矩阵:")
                print(result)
            else:
                print(result)
            print("\n" + "-" * 50 + "\n")
    
    
    Gear矩阵

    A = gearmat(n,i,j) 返回 n×n 矩阵, 其中下对角线和上对角线上为 1, (1,abs(i)) 位置为 sign(i), (n,n+1-abs(j)) 位置为 sign(j), 其余所有位置为 0.

    参量 i 和 j 的默认值分别为 n 和 -n. 它们必须为 -n 到 n 范围内的整数

    矩阵 A 是奇异矩阵,可具有双重和三重特征值,并且可以是亏损矩阵

    所有特征值的形式均为 2*cos(a),特征向量的形式为 [sin(w+a), sin(w+2a), …, sin(w+na)]

    n,i,j — 输入,标量
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    def generate_gear_matrix(n, i, j):
        """
        生成n×n的齿轮矩阵,具有以下特征:
        1. 次对角线(上下对角线)填充1
        2. (1,|i|)位置填充sign(i)
        3. (n, n+1-|j|)位置填充sign(j)

        参数:
        n (int): 矩阵维度(>=2的正整数)
        i (int): 第一行特征位置(非零整数,-n <= i <=n)
        j (int): 最后一行特征位置(非零整数,-n <= j <=n)

        返回:
        np.ndarray: 生成的齿轮矩阵

        异常:
        ValueError: 参数不符合要求时抛出
        """
        # 参数验证
        if n < 1:
            raise ValueError("矩阵维度n必须是正整数")
        if i == 0 or j == 0:
            raise ValueError("参数i和j不能为零")
        if not (-n <= i <= n) or not (-n <= j <= n):
            raise ValueError(f"参数i和j必须在[-{n}, {n}]范围内")

        # 创建基础矩阵
        A = np.zeros((n, n), dtype=int)

        # 填充次对角线(Python使用0-based索引)
        # 下对角线(主对角线下方)
        np.fill_diagonal(A[1:], 1)
        # 上对角线(主对角线上方)
        np.fill_diagonal(A[:, 1:], 1)

        # 设置特征元素(转换为0-based索引)
        # 第一行:位置(0, abs(i)-1)
        A[0, abs(i) - 1] = np.sign(i)
        # 最后一行:位置(n-1, n - abs(j) -1)
        # 计算公式调整为:n - abs(j) 对应MATLAB的n+1-|j|
        A[n - 1, n - abs(j)] = np.sign(j)

        return A


    def gearmat_matrix(input_str):
        """
        解析输入字符串并生成齿轮矩阵

        参数:
        input_str (str): 支持两种格式:
                       - 单整数:"n" 生成默认矩阵(i=n, j=-n)
                       - 元组:"(n,i,j)" 或 "n,i,j" 生成自定义矩阵

        返回:
        sp.Matrix | str: Sympy矩阵对象或错误信息
        """
        try:
            expr = sp.sympify(input_str)

            # 处理元组输入 (n, i, j)
            if isinstance(expr, tuple):
                if len(expr) != 3:
                    return f"需要3个参数,但收到{len(expr)}个"

                # 验证所有元素为整数
                if not all(e.is_integer for e in expr):
                    return "所有参数必须为整数"

                n, i, j = map(int, expr)
                matrix = generate_gear_matrix(n, i, j)

            # 处理单整数输入
            elif expr.is_integer:
                n = int(expr)
                if n < 1:
                    return f"维度必须≥1,但收到{n}"
                matrix = generate_gear_matrix(n, i=n, j=-n)  # 默认参数

            else:
                return "无效的输入格式"

            return sp.Matrix(matrix)

        except (sp.SympifyError, ValueError) as e:
            return f"输入错误:{str(e)}"
        except Exception as e:
            return f"运行时错误:{str(e)}"


    if __name__ == "__main__":
        # 示例测试
        test_cases = [
            "3",
            # Matrix([[0, 1, 1],
            #         [1, 0, 1],
            #         [-1, 1, 0]])

            "(4, 2, -3)",
            # Matrix([[0, 1, 0, 0],
            #         [1, 0, 1, 0],
            #         [0, 1, 0, 1],
            #         [0, -1, 1, 0]])
        ]

        for case in test_cases:
            print(f"输入: {case}")
            result = gearmat_matrix(case)
            if isinstance(result, sp.Matrix):
                print(f"生成 {result.rows}x{result.cols} 齿轮矩阵:")
                print(result)
            else:
                print(result)
            print("\n" + "=" * 50 + "\n")
    
    
    几何分布的累积分布函数

    y=geocdf(x,p)返回几何分布的累积分布函数(cdf),使用p中的相应概率在x中的每个值处进行评估。

    x -- 整数标量, 向量,矩阵,多维数组,是第一次成功之前的失败次数

    p -- 标量,向量,矩阵,多维数组,是成功的概率

    y -- cdf值,作为标量或[0,1]范围内的标量数组返回。在任何必要的标量展开后,y与x和p的大小相同。

    示例1. 质量控制 - 检测第一个次品

    假设生产线的次品率为1%
    defect_rate = 0.01

    print(f"生产线次品率: {defect_rate * 100}%")
    #生产线次品率: 1.0%

    在前N个产品中发现第一个次品的概率:
    for n in [10, 50, 100, 200, 500]:
        prob = geocdf(n, defect_rate)
        print(f"前{n}个产品中发现第一个次品的概率: {prob:.4f} ({prob * 100:.2f}%)")
    #前10个产品中发现第一个次品的概率: 0.0956 (9.56%)
    #前50个产品中发现第一个次品的概率: 0.3950 (39.50%)
    #前100个产品中发现第一个次品的概率: 0.6340 (63.40%)
    #前200个产品中发现第一个次品的概率: 0.8660 (86.60%)
    #前500个产品中发现第一个次品的概率: 0.9934 (99.34%)

    计算达到特定置信度需要的检查数量
    confidence_levels = [0.5, 0.9, 0.95, 0.99]

    达到特定置信度需要检查的产品数量:
    for confidence in confidence_levels:
        # 解方程: 1 - (1-p)^n = confidence
        n_needed = np.ceil(np.log(1 - confidence) / np.log(1 - defect_rate))
        actual_prob = geocdf(n_needed, defect_rate)
        print(f"{confidence * 100}% 置信度: 需要检查 {int(n_needed)} 个产品 (实际概率: {actual_prob:.4f})")
    #50.0% 置信度: 需要检查 69 个产品 (实际概率: 0.5002)
    #90.0% 置信度: 需要检查 230 个产品 (实际概率: 0.9009)
    #95.0% 置信度: 需要检查 299 个产品 (实际概率: 0.9505)
    #99.0% 置信度: 需要检查 459 个产品 (实际概率: 0.9901)

    示例2. 网络传输 - 数据包重传分析

    假设网络丢包率为5%
    packet_loss_rate = 0.05
    success_rate = 1 - packet_loss_rate

    print(f"网络丢包率: {packet_loss_rate * 100}%")
    print(f"单次传输成功率: {success_rate * 100}%")
    #网络丢包率: 5.0%
    #单次传输成功率: 95.0%

    分析不同重传次数下的成功概率
    max_attempts = 10
    for attempts in range(1, max_attempts + 1):
        prob = geocdf(attempts, success_rate)
        print(f"前{attempts}次尝试内传输成功的概率: {prob:.4f} ({prob * 100:.2f}%)")
    #前1次尝试内传输成功的概率: 0.9500 (95.00%)
    #前2次尝试内传输成功的概率: 0.9975 (99.75%)
    #前3次尝试内传输成功的概率: 0.9999 (99.99%)
    #前4次尝试内传输成功的概率: 1.0000 (100.00%)
    #前5次尝试内传输成功的概率: 1.0000 (100.00%)
    #前6次尝试内传输成功的概率: 1.0000 (100.00%)
    #前7次尝试内传输成功的概率: 1.0000 (100.00%)
    #前8次尝试内传输成功的概率: 1.0000 (100.00%)
    #前9次尝试内传输成功的概率: 1.0000 (100.00%)
    #前10次尝试内传输成功的概率: 1.0000 (100.00%)

    计算达到99%成功概率所需的最大重传次数
    target_prob = 0.99
    max_retries = np.ceil(np.log(1 - target_prob) / np.log(packet_loss_rate))
    actual_prob = geocdf(max_retries, success_rate)

    print(f"\n达到{target_prob * 100}%成功概率需要最多 {int(max_retries)} 次重传")
    print(f"实际概率: {actual_prob:.4f}")
    #达到99.0%成功概率需要最多 2 次重传
    #实际概率: 0.9975

    不同网络质量下的比较
    network_conditions = {
        "优秀网络 (丢包率1%)": 0.01,
        "良好网络 (丢包率5%)": 0.05,
        "一般网络 (丢包率10%)": 0.10,
        "较差网络 (丢包率20%)": 0.20
    }

    for desc, loss_rate in network_conditions.items():
        success_prob = geocdf(5, 1 - loss_rate)  # 5次尝试内的成功概率
        print(f"{desc}: 5次尝试内成功概率 = {success_prob:.4f}")
    #优秀网络 (丢包率1%): 5次尝试内成功概率 = 1.0000
    #良好网络 (丢包率5%): 5次尝试内成功概率 = 1.0000
    #一般网络 (丢包率10%): 5次尝试内成功概率 = 1.0000
    #较差网络 (丢包率20%): 5次尝试内成功概率 = 0.9997

    示例3. 市场营销 - 客户转化分析

    假设每次营销接触的转化率为2%
    conversion_rate = 0.02

    print(f"单次营销接触转化率: {conversion_rate * 100}%")
    #单次营销接触转化率: 2.0%

    分析不同接触次数下的累积转化概率
    contact_points = [1, 3, 5, 7, 10, 15, 20]

    不同营销接触次数下的累积转化概率:
    for contacts in contact_points:
        prob = geocdf(contacts, conversion_rate)
        print(f"前{contacts:2d}次接触内转化的概率: {prob:.4f} ({prob * 100:6.2f}%)")
    #前 1次接触内转化的概率: 0.0200 (  2.00%)
    #前 3次接触内转化的概率: 0.0588 (  5.88%)
    #前 5次接触内转化的概率: 0.0961 (  9.61%)
    #前 7次接触内转化的概率: 0.1319 ( 13.19%)
    #前10次接触内转化的概率: 0.1829 ( 18.29%)
    #前15次接触内转化的概率: 0.2614 ( 26.14%)
    #前20次接触内转化的概率: 0.3324 ( 33.24%)

    计算最优营销策略

    成本假设:每次接触成本1单位,转化价值100单位
    contact_cost = 1
    conversion_value = 100

    optimal_contacts = 0
    max_profit = 0

    for contacts in range(1, 31):
        conversion_prob = geocdf(contacts, conversion_rate)
        expected_value = conversion_prob * conversion_value
        total_cost = contacts * contact_cost
        expected_profit = expected_value - total_cost

        if expected_profit > max_profit:
            max_profit = expected_profit
            optimal_contacts = contacts

        if contacts in [5, 10, 15, 20, 25, 30]:
            print(f"{contacts:2d}次接触: 期望利润 = {expected_profit:6.2f}")
    # 5次接触: 期望利润 =   4.61
    #10次接触: 期望利润 =   8.29
    #15次接触: 期望利润 =  11.14
    #20次接触: 期望利润 =  13.24
    #25次接触: 期望利润 =  14.65
    #30次接触: 期望利润 =  15.45

    print(f"\n最优策略: 进行 {optimal_contacts} 次营销接触")
    print(f"最大期望利润: {max_profit:.2f}")
    #最优策略: 进行 30 次营销接触
    #最大期望利润: 15.45

    示例4. 医学研究 - 疾病检测灵敏度

    假设某种检测方法的灵敏度为90%
    test_sensitivity = 0.90

    print(f"单次检测灵敏度: {test_sensitivity * 100}%")
    #单次检测灵敏度: 90.0% (即对真实患者检测出阳性的概率)

    分析重复检测对灵敏度的提升

    for num_tests in [1, 2, 3, 4, 5]:
        # 至少一次检测为阳性的概率
        overall_sensitivity = geocdf(num_tests, test_sensitivity)
        print(f"{num_tests}次检测的总体灵敏度: {overall_sensitivity:.6f} ({overall_sensitivity * 100:.4f}%)")
    #1次检测的总体灵敏度: 0.900000 (90.0000%)
    #2次检测的总体灵敏度: 0.990000 (99.0000%)
    #3次检测的总体灵敏度: 0.999000 (99.9000%)
    #4次检测的总体灵敏度: 0.999900 (99.9900%)
    #5次检测的总体灵敏度: 0.999990 (99.9990%)

    不同疾病检测场景

    scenarios = {
        "高灵敏度检测 (95%)": 0.95,
        "标准检测 (90%)": 0.90,
        "快速检测 (85%)": 0.85,
        "筛查检测 (80%)": 0.80
    }

    for desc, sensitivity in scenarios.items():
        # 3次检测内的累积灵敏度
        cumul_sensitivity = geocdf(3, sensitivity)
        print(f"{desc}: 3次检测累积灵敏度 = {cumul_sensitivity:.6f}")
    #高灵敏度检测 (95%): 3次检测累积灵敏度 = 0.999875
    #标准检测 (90%): 3次检测累积灵敏度 = 0.999000
    #快速检测 (85%): 3次检测累积灵敏度 = 0.996625
    #筛查检测 (80%): 3次检测累积灵敏度 = 0.992000

    计算达到99.9%灵敏度所需的检测次数
    target_sensitivity = 0.999
    tests_needed = np.ceil(np.log(1 - target_sensitivity) / np.log(1 - test_sensitivity))
    actual_sensitivity = geocdf(f"{tests_needed}, {test_sensitivity}")

    print(f"\n达到{target_sensitivity * 100}%灵敏度需要 {int(tests_needed)} 次检测")
    print(f"实际灵敏度: {actual_sensitivity:.6f}")
    #达到99.9%灵敏度需要 3 次检测
    #实际灵敏度: 0.999000

    示例5. 游戏设计 - 稀有物品掉落机制

    假设稀有物品的掉落率为1%
    drop_rate = 0.01

    print(f"稀有物品掉落率: {drop_rate * 100}%")
    #稀有物品掉落率: 1.0%

    分析玩家在不同尝试次数下获得物品的概率
    attempts_range = [10, 50, 100, 200, 500, 1000]

    在不同尝试次数下获得至少一个稀有物品的概率:
    for attempts in attempts_range:
        prob = geocdf(attempts, drop_rate)
        print(f"{attempts:4d} 次尝试: {prob:.4f} ({prob * 100:6.2f}%)")
    #  10 次尝试: 0.0956 (  9.56%)
    #  50 次尝试: 0.3950 ( 39.50%)
    # 100 次尝试: 0.6340 ( 63.40%)
    # 200 次尝试: 0.8660 ( 86.60%)
    # 500 次尝试: 0.9934 ( 99.34%)
    #1000 次尝试: 1.0000 (100.00%)

    计算"保底"机制的设计
    pity_system_thresholds = [100, 200, 300, 500]

    for threshold in pity_system_thresholds:
        natural_prob = geocdf(threshold, drop_rate)
        print(f"在{threshold}次尝试内自然获得的概率: {natural_prob:.4f}")
        print(f"  需要保底机制覆盖的玩家比例: {(1 - natural_prob) * 100:.2f}%")
    #在100次尝试内自然获得的概率: 0.6340
    #  需要保底机制覆盖的玩家比例: 36.60%
    #在200次尝试内自然获得的概率: 0.8660
    #  需要保底机制覆盖的玩家比例: 13.40%
    #在300次尝试内自然获得的概率: 0.9510
    #  需要保底机制覆盖的玩家比例: 4.90%
    #在500次尝试内自然获得的概率: 0.9934
    #  需要保底机制覆盖的玩家比例: 0.66%

    玩家体验分析
    milestone_attempts = [50, 100, 150, 200]
    for attempts in milestone_attempts:
        prob = geocdf(attempts, drop_rate)
        unlucky_players = (1 - prob) * 100
        print(f"尝试{attempts}次仍未获得的玩家: {unlucky_players:.2f}%")
    #尝试50次仍未获得的玩家: 60.50%
    #尝试100次仍未获得的玩家: 36.60%
    #尝试150次仍未获得的玩家: 22.15%
    #尝试200次仍未获得的玩家: 13.40%

    示例6. 可靠性工程 - 设备故障分析

    假设设备每天发生故障的概率为0.5%
    daily_failure_rate = 0.005

    print(f"设备每日故障率: {daily_failure_rate * 100}%")
    print(f"平均无故障时间: {1 / daily_failure_rate:.1f} 天")
    #设备每日故障率: 0.5%
    #平均无故障时间: 200.0 天

    分析不同时间范围内的故障概率
    time_periods = [30, 90, 180, 365, 730]  # 天数

    在不同时间范围内发生首次故障的概率:
    for days in time_periods:
        prob = geocdf(days, daily_failure_rate)
        print(f"{days:3d} 天内发生故障的概率: {prob:.4f} ({prob * 100:.2f}%)")
    # 30 天内发生故障的概率: 0.1396 (13.96%)
    # 90 天内发生故障的概率: 0.3631 (36.31%)
    #180 天内发生故障的概率: 0.5943 (59.43%)
    #365 天内发生故障的概率: 0.8395 (83.95%)
    #730 天内发生故障的概率: 0.9742 (97.42%)

    不同可靠性要求的维护策略
    reliability_targets = {
        "关键设备 (99.9%)": 0.999,
        "重要设备 (99%)": 0.99,
        "一般设备 (95%)": 0.95
    }

    for desc, target in reliability_targets.items():
        # 计算达到可靠性目标的最大运行天数
        max_days = np.floor(np.log(1 - target) / np.log(1 - daily_failure_rate))
        actual_reliability = 1 - geocdf(max_days, daily_failure_rate)
        print(f"{desc}: 最多运行 {int(max_days)} 天 (实际可靠性: {actual_reliability:.6f})")
    #关键设备 (99.9%): 最多运行 1378 天 (实际可靠性: 0.001000)
    #重要设备 (99%): 最多运行 918 天 (实际可靠性: 0.010037)
    #一般设备 (95%): 最多运行 597 天 (实际可靠性: 0.050163)

    不同质量设备的比较
    failure_rates = {
        "高质量设备": 0.001,
        "标准设备": 0.005,
        "经济型设备": 0.01
    }

    for desc, rate in failure_rates.items():
        yearly_failure_prob = geocdf(365, rate)
        print(f"{desc}: 一年内故障概率 = {yearly_failure_prob:.4f}")
    #高质量设备: 一年内故障概率 = 0.3059
    #标准设备: 一年内故障概率 = 0.8395
    #经济型设备: 一年内故障概率 = 0.9745

    示例7. 金融服务 - 贷款违约预测

    假设月度违约率为0.2%
    monthly_default_rate = 0.002

    print(f"贷款月度违约率: {monthly_default_rate * 100}%")
    #贷款月度违约率: 0.2%

    分析不同贷款期限内的累计违约概率
    loan_terms = [12, 24, 36, 48, 60]  # 月数

    不同贷款期限内的累计违约概率:
    for months in loan_terms:
        prob = geocdf(months, monthly_default_rate)
        print(f"{months:2d} 个月内的违约概率: {prob:.4f} ({prob * 100:.3f}%)")
    #12 个月内的违约概率: 0.0237 (2.374%)
    #24 个月内的违约概率: 0.0469 (4.691%)
    #36 个月内的违约概率: 0.0695 (6.954%)
    #48 个月内的违约概率: 0.0916 (9.162%)
    #60 个月内的违约概率: 0.1132 (11.319%)

    基于风险的贷款定价分析
    risk_categories = {
        "优质客户 (违约率0.1%)": 0.001,
        "标准客户 (违约率0.2%)": 0.002,
        "次级客户 (违约率0.5%)": 0.005,
        "高风险客户 (违约率1%)": 0.01
    }

    loan_term = 36  # 3年贷款
    base_interest_rate = 0.05  # 基准利率5%

    for desc, default_rate in risk_categories.items():
        default_prob = geocdf(loan_term, default_rate)
        # 简化风险溢价计算
        risk_premium = default_prob * 2  # 假设风险溢价为违约概率的2倍
        total_interest = base_interest_rate + risk_premium
        print(f"{desc}: {loan_term}个月违约概率 = {default_prob:.4f}")
        print(f"  建议利率: {(total_interest * 100):.2f}%")
    #优质客户 (违约率0.1%): 36个月违约概率 = 0.0354
    #  建议利率: 12.08%
    #标准客户 (违约率0.2%): 36个月违约概率 = 0.0695
    #  建议利率: 18.91%
    #次级客户 (违约率0.5%): 36个月违约概率 = 0.1651
    #  建议利率: 38.02%
    #高风险客户 (违约率1%): 36个月违约概率 = 0.3036
    #  建议利率: 65.72%

    示例8. 符号计算应用 - 理论分析

    使用符号变量进行理论推导

    计算几何分布的CDF符号表达式
    symbolic_result = geocdf(k, p)
    print(f"几何分布CDF的符号表达式: {symbolic_result}")
    #几何分布CDF的符号表达式:
    #Piecewise((p*Piecewise((floor(k)/(1.0 - p), Eq(p, 0)),
              ((-p - (1.0 - p)**(floor(k) + 1.0) + 1.0)/(p*(1.0 - p)), True)), k >= 1), (0, True))

    分析不同参数下的行为
    specific_cases = [
        ("p = 0.5", geocdf(k, 0.5)),
        ("p = 0.1", geocdf(k, 0.1)),
        ("p = 0.01", geocdf(k, 0.01))
    ]

    for desc, expr in specific_cases:
        print(f"{desc}: {expr}")
    #p = 0.5: Piecewise((1.0 - 2.0*0.5**(floor(k) + 1.0), k >= 1), (0, True))
    #p = 0.1: Piecewise((1.0 - 1.11111111111111*0.9**(floor(k) + 1.0), k >= 1), (0, True))
    #p = 0.01: Piecewise((0.999999999999999 - 1.01010101010101*0.99**(floor(k) + 1.0), k >= 1), (0, True))

    期望值和方差的理论计算

    期望值 E[X] = 1/p
    expected_value = 1 / p

    方差 Var[X] = (1-p)/p²
    variance = (1 - p) / (p ** 2)

    print(f"期望值 E[X] = {expected_value}")
    print(f"方差 Var[X] = {variance}")
    #期望值 E[X] = 1/p
    #方差 Var[X] = (1 - p)/p**2

    可视化不同参数下的CDF形状
    try:
        import matplotlib.pyplot as plt

        # 数值计算示例
        k_values = np.arange(0, 50)
        p_values = [0.1, 0.3, 0.5, 0.7, 0.9]

        plt.figure(figsize=(10, 6))
        for p_val in p_values:
            cdf_values = [float(geometric_cdf(f"{k}, {p_val}")) for k in k_values]
            plt.plot(k_values, cdf_values, marker='o', label=f'p = {p_val}')

        plt.xlabel('试验次数 k')
        plt.ylabel('累积概率 F(k)')
        plt.title('几何分布累积分布函数')
        plt.legend()
        plt.grid(True, alpha=0.3)
        plt.show()

    except ImportError:
        print("(需要matplotlib来显示图形)")
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import scipy.stats as st
    import sympy as sp
    from sympy.stats import Geometric, cdf


    # 几何分布的累积分布函数
    def geometric_cdf(input_str):
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            # 计算卡方分布的概率密度函数 (PDF)
            # 转换为 SymPy 数组(仅在符号分支使用)

            if isinstance(expr, tuple) and len(expr) == 2:
                if all(e.is_number for e in expr):
                    k = int(expr[0])  # 实验的次数,标量或数组
                    p = float(expr[1])  # 成功的概率
                    # 计算概率值,处理k为负值的情况(设置概率为0)
                    result = np.where(k >= 0, st.geom.cdf(k, p), 0)
                elif any(e.free_symbols for e in expr):
                    k, p = expr
                    X = Geometric('geom', p)
                    cdf_expr = cdf(X)(k)
                    result = cdf_expr.evalf()
            else:
                error = True

            return result if not error else f"输入错误: {input_str}"


        except Exception as e:
            return f"错误:{e}"


    # 示例使用:
    # 标量输入
    print(geometric_cdf("3, 0.5"))
    # 0.875

    # 符号变量输入
    print(geometric_cdf("x, 0.5"))
    # Piecewise((1.0 - 2.0*0.5**(floor(x) + 1.0), x >= 1), (0, True))
    
    
    几何分布的概率质量函数

    y=geopdf(x,p)使用p中的相应概率返回x中每个值处的几何分布的概率密度函数(pdf)。x和p可以是向量、矩阵或多维数组。标量输入被扩展为与其他输入具有相同维度的常数数组。p中的参数必须位于[0,1]区间内。

    x -- 整数标量, 向量,矩阵,多维数组,是第一次成功之前的失败次数

    p -- 标量,向量,矩阵,多维数组,是成功的概率

    示例1. 质量控制 - 第一次成功检测分析

    分析在生产线中第一次检测到次品的概率分布

    假设次品率为2%
    defect_rate = 0.02

    print(f"生产线次品率: {defect_rate * 100}%")
    #生产线次品率: 2.0%

    在前N个产品中第一次发现次品的概率分布:

    计算前20个产品中第一次发现次品的概率
    k_values = range(1, 21)
    probabilities = [geopdf(k, defect_rate) for k in k_values]

    for k, prob in zip(k_values, probabilities):
        print(f"在第{k:2d}个产品第一次发现次品的概率: {prob:.4f} ({prob * 100:.2f}%)")
    #在第 1个产品第一次发现次品的概率: 0.0200 (2.00%)
    #在第 2个产品第一次发现次品的概率: 0.0196 (1.96%)
    #在第 3个产品第一次发现次品的概率: 0.0192 (1.92%)
    #在第 4个产品第一次发现次品的概率: 0.0188 (1.88%)
    #在第 5个产品第一次发现次品的概率: 0.0184 (1.84%)
    #在第 6个产品第一次发现次品的概率: 0.0181 (1.81%)
    #在第 7个产品第一次发现次品的概率: 0.0177 (1.77%)
    #在第 8个产品第一次发现次品的概率: 0.0174 (1.74%)
    #在第 9个产品第一次发现次品的概率: 0.0170 (1.70%)
    #在第10个产品第一次发现次品的概率: 0.0167 (1.67%)
    #在第11个产品第一次发现次品的概率: 0.0163 (1.63%)
    #在第12个产品第一次发现次品的概率: 0.0160 (1.60%)
    #在第13个产品第一次发现次品的概率: 0.0157 (1.57%)
    #在第14个产品第一次发现次品的概率: 0.0154 (1.54%)
    #在第15个产品第一次发现次品的概率: 0.0151 (1.51%)
    #在第16个产品第一次发现次品的概率: 0.0148 (1.48%)
    #在第17个产品第一次发现次品的概率: 0.0145 (1.45%)
    #在第18个产品第一次发现次品的概率: 0.0142 (1.42%)
    #在第19个产品第一次发现次品的概率: 0.0139 (1.39%)
    #在第20个产品第一次发现次品的概率: 0.0136 (1.36%)

    找到最可能第一次发现次品的位置
    max_prob_index = np.argmax(probabilities)
    print(f"\n最可能第一次发现次品的位置: 第{max_prob_index + 1}个产品")
    print(f"对应的概率: {probabilities[max_prob_index]:.4f}")
    #最可能第一次发现次品的位置: 第1个产品
    #对应的概率: 0.0200

    可视化概率分布
    try:
        import matplotlib.pyplot as plt

        plt.figure(figsize=(10, 6))
        plt.bar(k_values, probabilities, alpha=0.7, color='skyblue')
        plt.xlabel('检测的产品序号')
        plt.ylabel('概率')
        plt.title('第一次发现次品的概率分布')
        plt.grid(True, alpha=0.3)
        plt.show()

    except ImportError:
        print("(需要matplotlib来显示图形)")

    示例2. 网络传输 - 数据包成功传输分析

    分析数据包第k次尝试才成功传输的概率分布

    假设单次传输成功率为80%
    success_rate = 0.80

    print(f"单次数据包传输成功率: {success_rate * 100}%")
    #单次数据包传输成功率: 80.0%

    第k次尝试才成功传输的概率分布:
    分析前10次尝试的概率分布
    attempt_values = range(1, 11)
    pdf_values = [geopdf(k, success_rate) for k in attempt_values]

    for attempt, prob in zip(attempt_values, pdf_values):
        print(f"第{attempt}次尝试才成功的概率: {prob:.4f} ({prob * 100:.2f}%)")
    #第1次尝试才成功的概率: 0.8000 (80.00%)
    #第2次尝试才成功的概率: 0.1600 (16.00%)
    #第3次尝试才成功的概率: 0.0320 (3.20%)
    #第4次尝试才成功的概率: 0.0064 (0.64%)
    #第5次尝试才成功的概率: 0.0013 (0.13%)
    #第6次尝试才成功的概率: 0.0003 (0.03%)
    #第7次尝试才成功的概率: 0.0001 (0.01%)
    #第8次尝试才成功的概率: 0.0000 (0.00%)
    #第9次尝试才成功的概率: 0.0000 (0.00%)
    #第10次尝试才成功的概率: 0.0000 (0.00%)

    计算期望传输次数
    expected_attempts = 1 / success_rate
    print(f"\n期望传输次数: {expected_attempts:.2f} 次")
    #期望传输次数: 1.25 次

    不同网络质量下的首次成功传输概率分布
    network_conditions = {
        "优秀网络 (成功率95%)": 0.95,
        "良好网络 (成功率80%)": 0.80,
        "一般网络 (成功率60%)": 0.60,
        "较差网络 (成功率30%)": 0.30
    }

    for desc, rate in network_conditions.items():
        prob_1st = geopdf(1, rate)
        prob_3rd = geopdf(3, rate)
        print(f"{desc}: 第1次成功概率={prob_1st:.4f}, 第3次成功概率={prob_3rd:.4f}")
    #优秀网络 (成功率95%): 第1次成功概率=0.9500, 第3次成功概率=0.0024
    #良好网络 (成功率80%): 第1次成功概率=0.8000, 第3次成功概率=0.0320
    #一般网络 (成功率60%): 第1次成功概率=0.6000, 第3次成功概率=0.0960
    #较差网络 (成功率30%): 第1次成功概率=0.3000, 第3次成功概率=0.1470

    示例3. 销售漏斗 - 客户转化时机分析

    分析客户在第几次接触时才转化的概率分布

    假设每次营销接触的转化率为3%
    conversion_rate = 0.03

    print(f"单次营销接触转化率: {conversion_rate * 100}%")
    #单次营销接触转化率: 3.0%

    客户在第k次接触时才转化的概率分布:

    分析前15次接触的概率分布
    contact_values = range(1, 16)
    pdf_values = [geopdf(k, conversion_rate) for k in contact_values]

    print("接触次数 | 概率    | 累计概率")
    print("-" * 35)
    cumulative_prob = 0
    for contact, prob in zip(contact_values, pdf_values):
        cumulative_prob += prob
        print(f"第{contact:2d}次   | {prob:.4f} | {cumulative_prob:.4f}")
    #接触次数 | 概率    | 累计概率
    #-----------------------------------
    #第 1次   | 0.0300 | 0.0300
    #第 2次   | 0.0291 | 0.0591
    #第 3次   | 0.0282 | 0.0873
    #第 4次   | 0.0274 | 0.1147
    #第 5次   | 0.0266 | 0.1413
    #第 6次   | 0.0258 | 0.1670
    #第 7次   | 0.0250 | 0.1920
    #第 8次   | 0.0242 | 0.2163
    #第 9次   | 0.0235 | 0.2398
    #第10次   | 0.0228 | 0.2626
    #第11次   | 0.0221 | 0.2847
    #第12次   | 0.0215 | 0.3062
    #第13次   | 0.0208 | 0.3270
    #第14次   | 0.0202 | 0.3472
    #第15次   | 0.0196 | 0.3667

    找到转化概率最高的接触点
    max_prob_contact = np.argmax(pdf_values) + 1
    print(f"\n转化概率最高的接触点: 第{max_prob_contact}次接触")
    #转化概率最高的接触点: 第1次接触

    基于概率分布的营销策略建议:
    high_prob_contacts = [i + 1 for i, p in enumerate(pdf_values) if p > 0.02]
    print(f"应重点优化的接触点: {high_prob_contacts}")
    #应重点优化的接触点: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

    示例4. 游戏设计 - 稀有物品掉落分析

    分析玩家在第几次尝试才获得稀有物品的概率分布

    假设稀有物品掉落率为1%
    drop_rate = 0.01

    print(f"稀有物品掉落率: {drop_rate * 100}%")
    #稀有物品掉落率: 1.0%

    玩家在第k次尝试才获得稀有物品的概率分布:

    分析概率分布
    attempt_values = range(1, 201, 10)  # 每10次尝试采样一次
    pdf_values = [geopdf(k, drop_rate) for k in attempt_values]

    for attempt, prob in zip(attempt_values, pdf_values):
        if prob > 0.0001:  # 只显示概率大于0.01%的情况
            print(f"第{attempt:3d}次尝试才获得的概率: {prob:.6f}")
    #第  1次尝试才获得的概率: 0.010000
    #第 11次尝试才获得的概率: 0.009044
    #第 21次尝试才获得的概率: 0.008179
    #第 31次尝试才获得的概率: 0.007397
    #第 41次尝试才获得的概率: 0.006690
    #第 51次尝试才获得的概率: 0.006050
    #第 61次尝试才获得的概率: 0.005472
    #第 71次尝试才获得的概率: 0.004948
    #第 81次尝试才获得的概率: 0.004475
    #第 91次尝试才获得的概率: 0.004047
    #第101次尝试才获得的概率: 0.003660
    #第111次尝试才获得的概率: 0.003310
    #第121次尝试才获得的概率: 0.002994
    #第131次尝试才获得的概率: 0.002708
    #第141次尝试才获得的概率: 0.002449
    #第151次尝试才获得的概率: 0.002215
    #第161次尝试才获得的概率: 0.002003
    #第171次尝试才获得的概率: 0.001811
    #第181次尝试才获得的概率: 0.001638
    #第191次尝试才获得的概率: 0.001481

    分析"幸运"和"不幸"玩家的概率

    幸运玩家(前10次获得)
    lucky_prob = sum([geopdf(k, drop_rate) for k in range(1, 11)])
    print(f"幸运玩家(前10次获得)的概率: {lucky_prob:.4f}")
    #幸运玩家(前10次获得)的概率: 0.0956

    普通玩家(11-100次获得)
    normal_prob = sum([geopdf(k, drop_rate) for k in range(11, 101)])
    print(f"普通玩家(11-100次获得)的概率: {normal_prob:.4f}")
    #普通玩家(11-100次获得)的概率: 0.5383

    不幸玩家(100次后获得)
    unlucky_prob = 1 - lucky_prob - normal_prob
    print(f"不幸玩家(100次后获得)的概率: {unlucky_prob:.4f}")
    #不幸玩家(100次后获得)的概率: 0.3660

    保底机制设计
    pity_threshold = 100
    natural_prob = sum([geopdf(k, drop_rate) for k in range(1, pity_threshold + 1)])
    print(f"\n前{pity_threshold}次自然获得的概率: {natural_prob:.4f}")
    print(f"需要保底机制的玩家比例: {(1 - natural_prob) * 100:.2f}%")
    #前100次自然获得的概率: 0.6340
    #需要保底机制的玩家比例: 36.60%

    示例5. 医学诊断 - 疾病检测分析

    假设单次检测的确诊率为85%
    diagnosis_rate = 0.85

    print(f"单次检测确诊率: {diagnosis_rate * 100}%")
    #单次检测确诊率: 85.0%

    在第k次检测才确诊的概率分布:

    分析前5次检测的概率分布
    test_values = range(1, 6)
    pdf_values = [geopdf(k, diagnosis_rate) for k in test_values]

    for test, prob in zip(test_values, pdf_values):
        print(f"第{test}次检测才确诊的概率: {prob:.4f} ({prob * 100:.2f}%)")
    #第1次检测才确诊的概率: 0.8500 (85.00%)
    #第2次检测才确诊的概率: 0.1275 (12.75%)
    #第3次检测才确诊的概率: 0.0191 (1.91%)
    #第4次检测才确诊的概率: 0.0029 (0.29%)
    #第5次检测才确诊的概率: 0.0004 (0.04%)

    不同检测方法的效率比较:
    test_methods = {
        "高精度检测 (95%)": 0.95,
        "标准检测 (85%)": 0.85,
        "快速检测 (70%)": 0.70,
        "筛查检测 (50%)": 0.50
    }

    for desc, rate in test_methods.items():
        prob_1st = geopdf(1, rate)
        prob_2nd = geopdf(2, rate)
        expected_tests = 1 / rate
        print(f"{desc}: 第1次确诊概率={prob_1st:.4f}, 期望检测次数={expected_tests:.2f}")
    #高精度检测 (95%): 第1次确诊概率=0.9500, 期望检测次数=1.05
    #标准检测 (85%): 第1次确诊概率=0.8500, 期望检测次数=1.18
    #快速检测 (70%): 第1次确诊概率=0.7000, 期望检测次数=1.43
    #筛查检测 (50%): 第1次确诊概率=0.5000, 期望检测次数=2.00

    示例6. 客户服务 - 问题解决分析

    假设单次联系解决问题的概率为40%
    resolution_rate = 0.40

    print(f"单次联系问题解决率: {resolution_rate * 100}%")
    #单次联系问题解决率: 40.0%

    客户问题在第k次联系才解决的概率分布:

    分析前8次联系的概率分布
    contact_values = range(1, 9)
    pdf_values = [geopdf(k, resolution_rate) for k in contact_values]

    cumulative_prob = 0
    for contact, prob in zip(contact_values, pdf_values):
        cumulative_prob += prob
        print(f"第{contact}次联系解决: 概率={prob:.4f}, 累计概率={cumulative_prob:.4f}")
    #第1次联系解决: 概率=0.4000, 累计概率=0.4000
    #第2次联系解决: 概率=0.2400, 累计概率=0.6400
    #第3次联系解决: 概率=0.1440, 累计概率=0.7840
    #第4次联系解决: 概率=0.0864, 累计概率=0.8704
    #第5次联系解决: 概率=0.0518, 累计概率=0.9222
    #第6次联系解决: 概率=0.0311, 累计概率=0.9533
    #第7次联系解决: 概率=0.0187, 累计概率=0.9720
    #第8次联系解决: 概率=0.0112, 累计概率=0.9832

    服务质量评估

    一次联系解决的客户比例
    first_contact_resolution = geopdf(1, resolution_rate)
    print(f"一次联系解决率: {first_contact_resolution * 100:.1f}%")
    #一次联系解决率: 40.0%

    三次联系内解决的客户比例
    three_contact_resolution = sum([geopdf(k, resolution_rate) for k in range(1, 4)])
    print(f"三次联系内解决率: {three_contact_resolution * 100:.1f}%")
    #三次联系内解决率: 78.4%

    需要升级处理的客户比例
    escalation_threshold = 5
    escalation_prob = 1 - sum([geopdf(k, resolution_rate) for k in range(1, escalation_threshold + 1)])
    print(f"需要升级处理的客户比例: {escalation_prob * 100:.1f}%")
    #需要升级处理的客户比例: 7.8%

    示例7. 科学研究 - 实验成功分析

    假设单次实验成功的概率为20%
    experiment_success_rate = 0.20

    print(f"单次实验成功率: {experiment_success_rate * 100}%")
    #单次实验成功率: 20.0%

    在第k次实验才成功的概率分布:

    分析概率分布
    experiment_values = range(1, 16)
    pdf_values = [geopdf(k, experiment_success_rate) for k in experiment_values]

    for exp, prob in zip(experiment_values, pdf_values):
        print(f"第{exp:2d}次实验才成功的概率: {prob:.4f}")
    #第 1次实验才成功的概率: 0.2000
    #第 2次实验才成功的概率: 0.1600
    #第 3次实验才成功的概率: 0.1280
    #第 4次实验才成功的概率: 0.1024
    #第 5次实验才成功的概率: 0.0819
    #第 6次实验才成功的概率: 0.0655
    #第 7次实验才成功的概率: 0.0524
    #第 8次实验才成功的概率: 0.0419
    #第 9次实验才成功的概率: 0.0336
    #第10次实验才成功的概率: 0.0268
    #第11次实验才成功的概率: 0.0215
    #第12次实验才成功的概率: 0.0172
    #第13次实验才成功的概率: 0.0137
    #第14次实验才成功的概率: 0.0110
    #第15次实验才成功的概率: 0.0088

    科研资源规划

    期望实验次数
    expected_experiments = 1 / experiment_success_rate
    print(f"期望实验次数: {expected_experiments:.1f} 次")
    #期望实验次数: 5.0 次

    不同置信度下需要的最大实验次数
    confidence_levels = [0.5, 0.8, 0.9, 0.95]
    for confidence in confidence_levels:
        max_experiments = np.ceil(np.log(1 - confidence) / np.log(1 - experiment_success_rate))
        actual_prob = sum(
            [geopdf(k, experiment_success_rate) for k in range(1, int(max_experiments) + 1)])
        print(f"{confidence * 100}%置信度: 最多需要{int(max_experiments)}次实验 (实际概率: {actual_prob:.4f})")
    #50.0%置信度: 最多需要4次实验 (实际概率: 0.5904)
    #80.0%置信度: 最多需要8次实验 (实际概率: 0.8322)
    #90.0%置信度: 最多需要11次实验 (实际概率: 0.9141)
    #95.0%置信度: 最多需要14次实验 (实际概率: 0.9560)

    不同难度实验的成功时机比较:
    difficulty_levels = {
        "简单实验 (50%成功率)": 0.50,
        "中等实验 (20%成功率)": 0.20,
        "困难实验 (5%成功率)": 0.05,
        "极难实验 (1%成功率)": 0.01
    }

    for desc, rate in difficulty_levels.items():
        prob_5th = geopdf(5, rate)
        expected = 1 / rate
        print(f"{desc}: 第5次成功概率={prob_5th:.4f}, 期望次数={expected:.1f}")
    #简单实验 (50%成功率): 第5次成功概率=0.0312, 期望次数=2.0
    #中等实验 (20%成功率): 第5次成功概率=0.0819, 期望次数=5.0
    #困难实验 (5%成功率): 第5次成功概率=0.0407, 期望次数=20.0
    #极难实验 (1%成功率): 第5次成功概率=0.0096, 期望次数=100.0

    示例8. 符号计算与理论分析

    计算几何分布的PMF符号表达式
    symbolic_pmf = geopdf(k, p)
    print(f"几何分布PMF的符号表达式: {symbolic_pmf}")
    #几何分布PMF的符号表达式: p*(1.0 - p)**(k - 1.0)

    验证概率和为1
    理论上:∑_{k=1}^∞ (1-p)^{k-1} * p = 1
    theoretical_sum = sp.Sum(p * (1 - p) ** (k - 1), (k, 1, sp.oo))
    sum_value = theoretical_sum.doit()
    print(f"理论概率和: {sum_value}")
    #理论概率和: p*Piecewise((1/p, Abs(p - 1) < 1), (Sum((1 - p)**(k - 1), (k, 1, oo)), True))

    计算期望和方差
    期望值 E[X] = 1/p
    expected_value = 1 / p
    print(f"期望值 E[X] = {expected_value}")
    #期望值 E[X] = 1/p

    方差 Var[X] = (1-p)/p²
    variance = (1 - p) / (p ** 2)
    print(f"方差 Var[X] = {variance}")
    #方差 Var[X] = (1 - p)/p**2

    不同参数下的概率分布可视化
    try:
        import matplotlib.pyplot as plt

        # 数值计算示例
        k_values = np.arange(1, 21)
        p_values = [0.1, 0.3, 0.5, 0.7, 0.9]

        plt.figure(figsize=(12, 8))
        for p_val in p_values:
            pmf_values = [float(geopdf(k, p_val)) for k in k_values]
            plt.plot(k_values, pmf_values, marker='o', label=f'p = {p_val}')

        plt.xlabel('试验次数 k')
        plt.ylabel('概率 P(X=k)')
        plt.title('几何分布概率质量函数')
        plt.legend()
        plt.grid(True, alpha=0.3)
        plt.show()

        # 累积分布可视化
        plt.figure(figsize=(12, 8))
        for p_val in p_values:
            pmf_values = [float(geopdf(k, p_val)) for k in k_values]
            cdf_values = np.cumsum(pmf_values)
            plt.plot(k_values, cdf_values, marker='s', label=f'p = {p_val}')

        plt.xlabel('试验次数 k')
        plt.ylabel('累积概率 P(X≤k)')
        plt.title('几何分布累积分布函数')
        plt.legend()
        plt.grid(True, alpha=0.3)
        plt.show()

    except ImportError:
        print("(需要matplotlib来显示图形)")

    无记忆性验证
    几何分布具有无记忆性:P(X>m+n | X>m) = P(X>n)

    conditional_prob = (1 - p) ** (m + n) / (1 - p) ** m
    unconditional_prob = (1 - p) ** n
    print(f"条件概率 P(X>{m + n}|X>{m}) = {conditional_prob}")
    print(f"无条件概率 P(X>{n}) = {unconditional_prob}")
    print(f"无记忆性成立: {sp.simplify(conditional_prob - unconditional_prob) == 0}")
    #条件概率 P(X>m + n|X>m) = (1 - p)**(m + n)/(1 - p)**m
    #无条件概率 P(X>n) = (1 - p)**n
    #无记忆性成立: True
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import scipy.stats as st
    import sympy as sp
    from sympy.stats import Geometric, density


    # 几何分布的概率质量函数
    def geometric_pdf(input_str):
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            # 计算卡方分布的概率密度函数 (PDF)
            # 转换为 SymPy 数组(仅在符号分支使用)

            if isinstance(expr, tuple) and len(expr) == 2:
                if all(e.is_number for e in expr):
                    k = int(expr[0])  # 实验的次数,标量或数组
                    p = float(expr[1])  # 成功的概率
                    # 计算概率值,处理k为负值的情况(设置概率为0)
                    result = np.where(k >= 0, st.geom.pmf(k, p), 0)
                elif any(e.free_symbols for e in expr):
                    k, p = expr
                    X = Geometric('geom', p)
                    density_expr = density(X)(k)
                    result = density_expr.evalf()
            else:
                error = True

            return result if not error else f"输入错误: {input_str}"


        except Exception as e:
            return f"错误:{e}"


    # 示例使用:
    # 标量输入
    print(geometric_pdf("3, 0.5"))
    # 0.125

    # 符号变量输入
    print(geometric_pdf("x, 0.5"))
    # 0.5*0.5**(x - 1.0)
    
    
    平面几何图

    GeoPlot(Point2d,Segment,Circle,Ellipse,Polygon,Fill,Legend)绘制点,线,圆,椭圆及多边形。

    Point2d[a,b]绘制(a,b)坐标的点。

    Segment(a1,b1,a2,b2)绘制(a1,b1)到(a2,b2)的线条。

    Circle(a,b,r)绘制以(a,b)为圆心,r为半径的圆。

    Ellipse(a,b,r,vr)绘制以(a,b)为圆心,r为半径, vr为垂直半径的椭圆。

    Polygon(a1,b1,a2,b2,a3,b3....)绘制多点之间的多边形。

    Fill: 是否在几何体内填充颜色。

    Legend: 是否有注释
    
    立体几何图

    GeoPlot3D(Point3d,Line3d,Plane,Legend)绘制点,线,平面。

    Point3d[x,y,z]绘制(x,y,z)空间坐标的点。

    Line3d(x1,y1,z1,x2,y2,z2)绘制空间(x1,y1,z1)到(x2,y2,z2)的线条。

    Plane(x1,y1,z1,x2,y2,z2,(x_range),(y_range),(z_range))绘制空间平面。

    Legend: 是否有注释
    
    几何分布的随机采样函数

    r=geornd(p)从具有概率参数p的几何分布中生成随机数。p可以是向量、矩阵或多维数组。r的大小等于p的大小。p中的参数必须位于[0,1]区间内。

    r=geornd(p,m,n,…)或r=georn d(p、[m、n,…])生成多维m-by-n-by-。..包含来自具有概率参数p的几何分布的随机数的数组。p可以是标量或与r大小相同的数组。

    几何分布有助于在一系列独立试验中模拟一次成功之前的失败次数,其中每次试验都会导致成功或失败,任何单个试验的成功概率都是常数p。
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    from scipy.stats import geom


    def geornd_scipy(p, size=None):
        """
        几何分布随机采样函数(使用 SciPy)
        返回首次成功前的失败次数(k=0,1,2,...)

        参数:
            p: 成功概率(标量或矩阵)
            size: 输出形状(整数或元组)

        返回:
            随机数或随机数矩阵
        """
        # 处理标量概率
        if np.isscalar(p):
            if not 0 < p <= 1:
                raise ValueError("概率 p 必须在 (0,1] 区间")
            # 使用 SciPy 的几何分布生成器(p 参数对应失败概率)
            return geom.rvs(p, size=size) - 1

        # 处理矩阵概率
        p_arr = np.asarray(p)
        if p_arr.ndim == 0:
            return geom.rvs(p_arr, size=size) - 1

        # 检查所有概率值是否有效
        if np.any((p_arr <= 0) | (p_arr > 1)):
            raise ValueError("所有概率值必须在 (0,1] 区间")

        # 为每个概率值生成随机数
        return np.vectorize(lambda p_val: geom.rvs(p_val) - 1)(p_arr)


    # 示例用法
    if __name__ == "__main__":
        np.random.seed(42)  # 设置随机种子

        # 示例1:标量概率(单个随机数)
        print("单个随机数:", geornd_scipy(0.3))
        # 1

        # 示例2:指定维度(2x3矩阵)
        print("\n2x3矩阵:")
        print(geornd_scipy(0.5, size=(2, 3)))
        # [[4 1 1]
        #  [0 0 0]]

        # 示例3:矩阵概率
        prob_matrix = [[0.2, 0.5], [0.3, 0.7]]
        print("\n矩阵概率:")
        print(geornd_scipy(prob_matrix))
        # [[4 1]
        #  [0 2]]

        # 示例4:不同形状
        print("\n一维数组:")
        print(geornd_scipy(0.6, size=5))
        # [1 0 0 0 0]
    
    
    冈珀茨拟合

    gompertz: Y = d+(a-d)*exp(-exp(-b*(x-c)))

    返回冈珀茨拟合方程式
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    from scipy.optimize import curve_fit


    def gompertz_fit_nonlinear(input_str):
        try:
            expr = sp.sympify(input_str)
            error = False
            expression = None
            maxfev = 100000
            x_sym = sp.symbols('x')  # 定义符号变量x

            # 定义 Gompertz 函数
            def gompertz(x, a, b, c, d):
                return d + (a - d) * np.exp(-np.exp(-b * (x - c)))

            # 检查输入是否为包含两个元素的元组
            if isinstance(expr, tuple) and len(expr) == 2:
                x_part, y_part = expr[0], expr[1]

                # 转换为矩阵并验证
                if not isinstance(x_part, list) or not isinstance(y_part, list):
                    error = True
                else:
                    x_data = np.array(x_part, dtype=float).ravel()
                    y_data = np.array(y_part, dtype=float).ravel()

                    if len(x_data) != len(y_data):
                        error = True
                    else:
                        # 初始参数猜测
                        initial_guess = [max(y_data), 1, np.mean(x_data), min(y_data)]

                        # 非线性拟合
                        params, _ = curve_fit(
                            gompertz,
                            x_data,
                            y_data,
                            p0=initial_guess,
                            maxfev=maxfev
                        )

                        # 提取参数并构造Sympy表达式
                        a, b, c, d = params
                        expression = f"{d:.4f} + ({a:.4f} - {d:.4f}) * exp(-exp(-{b:.4f} * (x - {c:.4f})))"
            else:
                error = True  # 输入格式不正确

            if error:
                return f"输入错误: {input_str}"
            else:
                return sp.simplify(expression)

        except Exception as e:
            return f"错误: {e}"


    # 示例输入:x和y数据点
    input_data = "([1,2,3,4,5], [2.0, 4.5, 6.5, 8.0, 8.5])"
    result = gompertz_fit_nonlinear(input_data)
    print(result)
    # 0.4148 + 8.7322*exp(-3.77555321883638*exp(-0.7963*x))
    
    
    符号标量场的梯度向量(数值梯度)

    FX = gradient(F) 返回向量F的一维数值梯度.输出FX对应于∂F/∂x,即x(水平)方向上的差分.点之间的间距假定为1

    FX = gradient(F,[vars],[points]) 返回符号表达式列表的符号标量场的梯度向量.

    [FX,FY] = gradient(F) 返回矩阵F的二维数值梯度的x和y分量.附加输出FY对应于∂F/∂y,即y(垂直)方向上的差分.每个方向上的点之间的间距假定为1

    F — 输入数组,向量,矩阵,符号表达式

    vars -- 符号变量列表.

    points -- 数值列表.

    FX, FY — 数值梯度,数组
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    def get_result_value(symbols_set, points=None, result=None):
        """
        将符号表达式代入具体数值点求值。

        参数:
        symbols_set: 符号集合
        points: 数值点列表,与符号一一对应
        result: 待代入的表达式

        返回:
        代入后的数值结果或符号表达式
        """
        if points is not None and result is not None:
            if len(points) != len(symbols_set):
                raise ValueError(f"提供的点数({len(points)})与符号数量({len(symbols_set)})不匹配。")
            subs_dict = {symbol: value for symbol, value in zip(symbols_set, points)}
            try:
                # 尝试数值求值
                result = result.subs(subs_dict).evalf()
            except Exception as e:
                # 非数值情况直接代入
                result = result.subs(subs_dict)
        return result


    def gradient_by_function(input_str):
        """
            对标 MATLAB 的 gradient 函数,计算数值或符号梯度。

            MATLAB梯度规则:
            - 对于向量:中心差分(边界使用单边差分)
            - 对于矩阵:对每个维度分别计算梯度

            参数:
            input_str (str): 输入表达式,可以是以下形式:
                1. 纯矩阵 (如 "Matrix([[1,2],[3,4]])")
                2. 符号表达式 (如 "x**2 + y**3")
                3. 元组结构 (如 "(f, [x,y], [1,2])")
                   其中最后一个元素为可选的代入点

            返回:
            SymPy 矩阵/表达式 或错误信息字符串
            """
        try:
            # 将输入的字符串转换为 SymPy 表达式
            expr = sp.sympify(input_str)
            # 初始化错误标志为 False
            error = False
            # 初始化结果变量
            result = None

            def remove_last_from_tuple(tup):
                """
                移除元组的最后一个元素。

                参数:
                tup (tuple): 待处理的元组

                返回:
                tuple: 移除最后一个元素后的元组
                """
                return tup[:-1] if len(tup) > 1 else tup

            # 检查输入是否为元组,且最后一个元素为数值列表
            if isinstance(expr, tuple) and isinstance(expr[-1], list) and all(item.is_number for item in expr[-1]):
                # 提取代入点
                points = expr[-1]
                # 移除元组的最后一个元素
                expr = remove_last_from_tuple(expr)
            else:
                # 如果不满足条件,代入点设为 None
                points = None

            # 检查输入是否为包含两个元素的元组
            if isinstance(expr, tuple) and len(expr) == 2:
                # 提取函数和变量
                func, variables = expr
                # 计算函数关于变量的梯度
                grad = sp.derive_by_array(func, variables)
                # 如果梯度结果长度大于 1,转换为 SymPy 矩阵
                result = sp.Matrix(grad) if len(grad) > 1 else grad
                # 将变量代入梯度结果
                result = get_result_value(variables, points, result)
            # 检查输入是否为 SymPy 矩阵
            elif isinstance(expr, list):
                # 检查矩阵是否为数值矩阵
                sp_matrix = sp.Matrix(expr)
                if sp_matrix.is_symbolic() is False:
                    # 检查矩阵是否为向量(行数或列数为 1)
                    is_vector = sp_matrix.rows == 1 or sp_matrix.cols == 1
                    if is_vector:
                        # 将向量转换为一维 NumPy 数组
                        A = np.ravel(np.array(sp_matrix, dtype=float))
                        # 计算向量的梯度
                        np_grad = np.gradient(A)
                    else:
                        # 将矩阵转换为 NumPy 数组
                        np_array = np.array(sp_matrix.tolist(), dtype=float)
                        # 计算矩阵的梯度
                        np_grad = np.gradient(np_array)

                    # 将 NumPy 梯度结果转换为 SymPy 矩阵
                    if isinstance(np_grad, list):
                        result = [sp.Matrix(g) for g in np_grad]
                    else:
                        result = sp.Matrix(np_grad)
                else:
                    # 提取矩阵中的自由符号
                    symbols = sp_matrix.free_symbols
                    # 计算矩阵关于符号的梯度
                    result = sp.derive_by_array(sp_matrix, list(symbols))
                    # 将梯度结果转换为 SymPy 矩阵
                    result = sp.Matrix(result)
                    # 将变量代入梯度结果
                    result = get_result_value(symbols, points, result)
            # 检查输入表达式是否包含自由符号
            elif expr.free_symbols:
                # 提取表达式中的自由符号
                symbols_set = list(expr.free_symbols)
                # 计算表达式关于符号的梯度
                result = sp.derive_by_array(expr, symbols_set)
                # 将梯度结果转换为 SymPy 矩阵
                result = sp.Matrix(result)
                # 将变量代入梯度结果
                result = get_result_value(symbols_set, points, result)
            else:
                # 如果输入表达式不包含自由符号,设置错误标志为 True
                error = True

            # 如果没有错误,返回结果;否则返回错误信息
            return result if not error else f"输入错误: {input_str}"
        except Exception as e:
            return f"输入错误:{e}"


    # 示例用法
    if __name__ == "__main__":
        # 示例1: 符号表达式梯度
        print("\n示例1: 符号梯度")
        x, y = sp.symbols('x y')
        input_expr = "x**2 + y**3"
        grad = gradient_by_function(input_expr)
        print(f"\n表达式: {input_expr}")
        print("符号梯度:")
        print(grad)
        # Matrix([[2*x],
        #         [3*y**2]])

        # 示例2: 带代入点的符号梯度
        print("\n示例2: 带代入点的梯度")
        input_tuple = "(x**2 + y**3, [x, y], [1, 2])"
        grad = gradient_by_function(input_tuple)
        print(f"\n输入:{input_tuple}")
        print("代入点后的数值梯度:")
        print(grad)
        # Matrix([[2.00000000000000],
        #         [12.0000000000000]])
    
    
    具有敏感特征值的托普利茨矩阵

    A = grcar(n,k) 返回 n×n 托普利茨矩阵, 其中下对角线上的元素为 -1, 主对角线上的元素为 1, 主对角线上方的 k 个对角线上的元素为 1. k 必须为整数, 默认值为 k = 3. A 具有对扰动敏感的特征值.

    n,k — 输入,标量
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    def create_grcar_matrix(n, k=3):
        """
        生成一个n×n的Grcar矩阵。

        Grcar矩阵是一种具有特殊结构的测试矩阵,主对角线为1,下方第一条对角线为-1,
        上方k条对角线为1,其余位置为0。

        参数:
            n (int): 矩阵的维度。
            k (int, 可选): 主对角线上方的对角线数量,默认为3。

        返回:
            numpy.ndarray: 生成的Grcar矩阵。
        """
        # 创建n×n的零矩阵
        A = np.zeros((n, n), dtype=int)

        # 设置主对角线为1
        np.fill_diagonal(A, 1)

        # 设置下方第一条对角线为-1
        # A[1:]表示从第二行开始的所有行,填充其主对角线(即原矩阵的下第一条对角线)
        np.fill_diagonal(A[1:], -1)

        # 设置主对角线上方的k条对角线为1
        for diag in range(1, k + 1):
            # 对每行,从第diag列开始,填充其主对角线(即原矩阵右上方的第diag条对角线)
            np.fill_diagonal(A[:, diag:], 1)

        return A


    def grcar_matrix(input_str):
        """
        根据输入字符串生成Grcar矩阵。

        输入可以是单个数字n(如"5")或元组(n, k)(如"(5, 3)")。

        参数:
            input_str (str): 描述矩阵参数的字符串。

        返回:
            sympy.Matrix or str: 生成的矩阵或错误信息。
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            if isinstance(expr, tuple):
                # 处理元组输入,例如"(5, 3)"
                if len(expr) != 2:
                    error = True
                else:
                    n = int(expr[0])
                    k = int(expr[1])
                    result = create_grcar_matrix(n, k)
            elif expr.is_number:
                # 处理单个数字输入,例如"5"
                n = int(expr)
                result = create_grcar_matrix(n)
            else:
                error = True

            if error:
                return f"输入格式错误: {input_str}"
            else:
                return sp.Matrix(result)
        except Exception as e:
            return f"错误: {e}"


    # 示例代码
    if __name__ == "__main__":
        # 示例1:生成5x5,k=3的Grcar矩阵
        print("示例1:n=5, k=3")
        print(grcar_matrix("5"))
        # Matrix([[1, 1, 1, 1, 0],
        #         [-1, 1, 1, 1, 1],
        #         [0, -1, 1, 1, 1],
        #         [0, 0, -1, 1, 1],
        #         [0, 0, 0, -1, 1]])

        # 示例2:生成5x5,k=2的Grcar矩阵
        print("\n示例2:n=5, k=2")
        print(grcar_matrix("(5, 2)"))
        # Matrix([[1, 1, 1, 0, 0],
        #         [-1, 1, 1, 1, 0],
        #         [0, -1, 1, 1, 1],
        #         [0, 0, -1, 1, 1],
        #         [0, 0, 0, -1, 1]])
    
    
    广义奇异值分解

    [U,V,S] = gsvd(A,B) 执行矩阵A和B的广义奇异值分解,并返回酉矩阵U和V以及非负对角矩阵S

    A, B — 输入矩阵(以单独参量指定),矩阵
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    from scipy.linalg import qr, svd


    def generalized_singular_value_decomposition(input_str):
        """
        执行广义奇异值分解(GSVD),对标MATLAB的gsvd函数。

        参数:
        input_str: 输入字符串,表示两个矩阵的元组,例如 "([[1,2],[3,4]], [[5,6],[7,8]])"

        返回:
        返回包含U, V, X, C, S的元组(SymPy矩阵),或错误信息。
        """
        try:
            # 解析输入字符串为SymPy表达式
            expr = sp.sympify(input_str)
            if not isinstance(expr, tuple) or len(expr) != 2:
                return "输入错误:请输入包含两个矩阵的元组。"

            if any(isinstance(e, list) is False for e in expr):
                return "输入错误:无法解析为两个有效矩阵。"

            # 转换为NumPy数组
            A_np = np.array(expr[0], dtype=float)
            B_np = np.array(expr[1], dtype=float)

            # 检查矩阵列数是否相同
            if A_np.shape[1] != B_np.shape[1]:
                return f"错误:矩阵A和B的列数必须相同。A的列数:{A_np.shape[1]}, B的列数:{B_np.shape[1]}"

            # 计算矩阵B的QR分解(经济模式)
            # B^T = Q_B * R_B → B = R_B^T @ Q_B^T
            Q_B, R_B = qr(B_np.T, mode='economic')
            R_B = R_B.T  # 调整后B = Q_B @ R_B

            # 计算A * Q_B^T
            AQ_B = A_np @ Q_B.T

            # 对AQ_B进行奇异值分解(SVD)
            U, D, Zt = svd(AQ_B, full_matrices=False)
            Z = Zt.T

            # 计算X矩阵:X = Q_B^T @ Z
            X = Q_B.T @ Z

            # 计算C和S的对角元素
            C_diag = D
            S_diag = np.sqrt(1 - D ** 2)

            # 构造对角矩阵C和S
            C = np.diag(C_diag)
            S = np.diag(S_diag)

            # 计算V矩阵:B = V @ S @ X^T → V = B @ X @ inv(S)
            # 由于B = Q_B @ R_B,代入得 Q_B @ R_B = V @ S @ X^T
            # 结合X = Q_B^T @ Z → Q_B = X @ Z^T
            V = (R_B @ Z) @ np.diag(1.0 / S_diag)

            # 转换为SymPy矩阵
            U_sp = sp.Matrix(U)
            V_sp = sp.Matrix(V)
            X_sp = sp.Matrix(X.T)  # X在分解式中转置
            C_sp = sp.Matrix(C)
            S_sp = sp.Matrix(S)

            return (U_sp, V_sp, X_sp, C_sp, S_sp)

        except Exception as e:
            return f"错误:{e}"


    # 示例使用
    input_str = "([[1,6,11],[2,7,12],[3,8,13],[4,9,14],[5,10,15]], [[8,1,6],[3,5,7],[4,9,2]])"
    result = generalized_singular_value_decomposition(input_str)

    if isinstance(result, tuple):
        U, V, X, C, S = result
        print("U =")
        print(U)
        # Matrix([[-0.354557057037681, 0.688686643768252, -0.100420070696462],
        #         [-0.398696369998832, 0.375554529395871, 0.401020580634150],
        #         [-0.442835682959984, 0.0624224150234908, -0.685649669614349],
        #         [-0.486974995921135, -0.250709699348890, 0.569917880112097],
        #         [-0.531114308882287, -0.563841813721270, -0.184868720435436]])

        print("\nV =")
        print(V)
        # Matrix([[nan, nan, 8.64112621464805],
        #         [nan, nan, 4.34326123905226],
        #         [nan, nan, 0.200526501807073]])

        print("\nX =")
        print(X)
        # Matrix([[-0.201664911192694, -0.516830501392304, -0.831996091591915],
        #         [-0.890317132783019, -0.257331626824051, 0.375653879134918],
        #         [0.408248290463863, -0.816496580927726, 0.408248290463863]])

        print("\nC =")
        print(C)
        # Matrix([[35.1272233335747, 0, 0],
        #         [0, 2.46539669691652, 0],
        #         [0, 0, 1.17309315627448e-15]])

        print("\nS =")
        print(S)
        # Matrix([[nan, 0, 0],
        #         [0, nan, 0],
        #         [0, 0, 1.00000000000000]])
    else:
        print(result)
    
    
    古德曼函数

    Y = Gudermannian(x)得到古德曼函数结果,将三角函数和双曲函数连系起来.

    x -- 输入,数值,符号函数,向量,矩阵.
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    def gudermannian_function(input_str):
        """
        计算输入表达式的 Gudermannian 函数值,支持标量、矩阵和符号表达式。

        Gudermannian 函数定义为:gd(x) = 2 * arctan(exp(x)) - π/2

        参数:
        input_str (str): 输入的数学表达式字符串,可以是标量、矩阵或符号。

        返回:
        计算结果 (SymPy 表达式/矩阵) 或错误信息字符串。
        """
        try:
            # 将输入字符串解析为 SymPy 表达式
            expr = sp.sympify(input_str)
            error = False
            result = None

            # 处理元组类型输入(通常为无效输入)
            if expr.free_symbols:
                # 符号表达式处理:返回符号表达式
                result = sp.simplify(2 * sp.atan(sp.exp(expr)) - sp.pi / 2)
            elif expr.is_number:
                z = complex(expr)
                result = np.arcsin(np.tanh(z))
            else:
                error = True

            return result if not error else f"输入错误: {input_str}"

        except Exception as e:
            return f"输入错误: {e}"


    # 示例用法
    if __name__ == "__main__":
        # 示例 1: 标量数值输入
        print("示例 1:")
        print(gudermannian_function("1+2j"))
        # (1.2304675059389543-0.6765532587260855j)

        # 示例 2: 符号输入
        print("\n示例 2:")
        x = sp.symbols('x')
        print(gudermannian_function("x"))
        # 2*atan(exp(x)) - pi/2