首页 函数目录

    隐式导数

    iDiff(eq,y,x,n=1)返回dy/dx,并假设eq=0

    y — 因变量或因变量列表(以y开头)

    x — 取导数的变量

    n — 导数的顺序(默认为1)

    示例1:物理学中的等温过程 - 理想气体方程 PV = nRT

    result4 = iDiff(P*V - T, V, P) # 在等温过程中,求体积对压强的变化率
    print("理想气体等温过程 dV/dP:", result4)
    #理想气体等温过程 dV/dP: -V/P

    示例2:经济学中的生产可能性边界 - 2x² + 3y² = 100

    result5 = iDiff(2*x**2 + 3*y**2 - 100, y, x)  # 边际转换率
    print("生产可能性边界 dy/dx:", result5)
    #生产可能性边界 dy/dx: -2*x/(3*y)

    在点(5, √(50/3))处求值
    result5_point = iDiff(2*x**2 + 3*y**2 - 100, y, x, 1, [5, sqrt(50/3)])
    print("在点(5, √(50/3))处的 dy/dx:", result5_point)
    #在点(5, √(50/3))处的 dy/dx: -0.816496580927726

    示例3:工程学中的悬链线方程 y = a*cosh(x/a)

    result6 = iDiff(y - a*cosh(x/a), y, x) # 悬链线的斜率
    print("悬链线方程 dy/dx:", result6)
    #悬链线方程 dy/dx: sinh(x/a)

    示例4:化学反应的平衡常数

    result7 = iDiff(A*B - K*C**2, C, A)  # 反应 A + B ⇌ 2C 中C浓度对A浓度的变化率
    print("化学反应平衡 dC/dA:", result7)
    #化学反应平衡 dC/dA: B/(2*C*K)

    示例5:几何学中的椭圆方程

    result8 = iDiff(x**2/a**2 + y**2/b**2 - 1, y, x)  # 椭圆上任意点的切线斜率
    print("椭圆切线斜率 dy/dx:", result8)
    #椭圆切线斜率 dy/dx: -b**2*x/(a**2*y)

    在具体椭圆 x²/4 + y²/9 = 1 上点(1, (3√3)/2)处求值
    result8_point = iDiff(x**2/4 + y**2/9 - 1, y, x, 1, [1, 3*sqrt(3)/2])
    print("在点(1, 3√3/2)处的切线斜率:", result8_point)
    #在点(1, 3√3/2)处的切线斜率: -0.866025403784439

    示例6:热力学中的状态方程

    result9 = iDiff(P*V - R*T, T, P)  # 温度对压强的变化率(等容过程)
    print("等容过程 dT/dP:", result9)
    #等容过程 dT/dP: V/R

    示例7:二阶导数应用 - 曲线的凹凸性

    result10 = iDiff(x**3 + y**3 - 6*x*y, y, x, 2)  # 笛卡尔叶形线的二阶导数
    print("笛卡尔叶形线 d²y/dx²:", result10)
    #笛卡尔叶形线 d²y/dx²: 2*x*y*(x**3 - 6*x*y + y**3 + 8)/(8*x**3 - 12*x**2*y**2 + 6*x*y**4 - y**6)

    示例8:金融学中的连续复利

    result12 = iDiff(A - P*exp(r*t), r, t)  # 利率对时间的变化率
    print("连续复利 dr/dt:", result12)
    #连续复利 dr/dt: -r/t

    测试包含数值点的复杂情况

    result13 = iDiff(x**2 + y**2 - 25, y, x, 2, [3, 4])    # 圆 x²+y²=25 在点(3,4)处的二阶导数
    print("圆在点(3,4)处的二阶导数:", result13)
    #圆在点(3,4)处的二阶导数: -0.390625000000000
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp

    def get_result_value(symbols_set, points=None, result=None):
        """
        将符号表达式代入具体数值点求值。

        参数:
        symbols_set (list): 符号列表,按字母顺序排列
        points (list): 数值点列表,顺序需与symbols_set中的符号对应
        result (sympy.Expr): 待代入的表达式

        返回:
        sympy.Expr 或 float: 代入后的数值结果或符号表达式

        示例:
        symbols = [x, y], points = [2, 3] 表示代入x=2, y=3
        """
        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 implicit_diff_equation(input_str):
        """
        处理隐函数求导请求,对标MathStudio的iDiff功能

        参数:
        input_str (str): 输入字符串,格式为Sympy可解析的元组形式:
            (方程, 因变量, 自变量, 阶数(可选), 数值点(可选))
            示例: "(Eq(x**2 + y**2, 1), y, x, 2, [0, 1])"

        返回:
        sympy.Expr 或 str: 求导结果或错误信息
        """
        try:
            # 预处理输入字符串
            processed_str = input_str
            error = False
            result = None

            def remove_last_element(tup):
                """移除元组最后一个元素(用于处理数值点)"""
                return tup[:-1] if len(tup) > 1 else tup

            # 解析输入字符串
            if '==' in processed_str:
                # 方程处理:转换为左式-右式=0的形式
                expr = sp.sympify(processed_str, evaluate=False)
                transformed_equation = f"{expr[0].lhs} - {expr[0].rhs}"
                expr_func = sp.sympify(transformed_equation)
            else:
                expr = sp.sympify(processed_str)
                expr_func = expr[0] if isinstance(expr, tuple) else expr

            # 处理元组形式的参数
            if isinstance(expr, tuple):
                # 检查是否包含数值点参数
                if len(expr) > 0 and isinstance(expr[-1], list) and all(item.is_number for item in expr[-1]):
                    points = expr[-1]
                    expr = remove_last_element(expr)
                else:
                    points = None

                # 解析求导参数
                if len(expr) >= 3:
                    equation = expr_func
                    dep_var = expr[1]  # 因变量
                    indep_var = expr[2]  # 自变量
                    # 处理求导阶数
                    order = expr[3] if len(expr) > 3 and expr[3].is_number else 1
                    # 执行隐式求导
                    result = sp.idiff(equation, dep_var, indep_var, order).simplify()
                    # 处理符号代入
                    symbols = sorted(result.free_symbols, key=lambda s: str(s))  # 按字母顺序排序符号
                    result = get_result_value(symbols, points, result)
                else:
                    error = True
            else:
                error = True

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

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


    # 示例用法
    if __name__ == "__main__":
        # 示例1:计算 x² + y² = 1 的一阶导数
        x, y = sp.symbols('x y')
        input1 = "(x**2 + y**2==1, y, x)"
        print("示例1结果:", implicit_diff_equation(input1))
        # 输出: -x/y

        # 示例2:计算二阶导数并代入点(0, 1)
        input2 = "(x**2+y**2==1, y, x, 2, [0, 1])"
        print("示例2结果:", implicit_diff_equation(input2))
        # 输出 -1.0

        # 示例3:带数值点的三阶导数
        input3 = "(y**3 + x, y, x, 3)"
        print("示例3结果:", implicit_diff_equation(input3))
        # 输出 -10/(27*y**8)
    
    
    带有舍入选项的整除

    C = idivide(A,B) 将A的每个元素除以B的对应元素,朝零方向舍入到最接近的整数.A和B必须包含实数,并且其中有至少一个必须属于整数类.

    如果A和B是数组,则它们必须属于同一整数类,并且大小兼容.

    如果A或B是双精度标量,则另一个输入必须为整数类,但不能是int64或uint64.然后,idivide函数以相同的整数类形式返回C.

    C = idivide(A,B,opt) 指定替代舍入选项:'fix'、'floor'、'ceil'.例如,idivide(A,B,'ceil') 将商朝正无穷方向舍入到最接近的整数.默认舍入选项是 'fix'.

    示例1:资源分配问题 - 将100个物品平均分给7个人

    result1 = idivide(100, 7, floor)
    print(f"100个物品分给7人,每人得: {result1} 个")
    remaining = 100 - result1 * 7
    print(f"剩余物品: {remaining} 个")
    #100个物品分给7人,每人得: 14 个
    #剩余物品: 2 个

    示例2:时间规划 - 将480分钟分配到25分钟的时间块中

    result2 = idivide(480, 25, floor)
    print(f"480分钟可以分成 {result2} 个25分钟的时间块")  # 19个
    remaining_time = 480 - result2 * 25
    print(f"剩余时间: {remaining_time} 分钟")
    #480分钟可以分成 19 个25分钟的时间块
    #剩余时间: 5 分钟

    示例3:财务计算 - 货币兑换(大额兑换)

    将1000美元兑换成日元,假设1美元=110日元,只取整百日元
    result3 = idivide(1000*110, 100, floor)
    print(f"1000美元可兑换 {result3*100} 日元")
    #1000美元可兑换 110000 日元

    示例4:制造业 - 材料切割优化

    从120cm长的材料上切割35cm的零件
    result4 = idivide(120, 35, floor)
    print(f"120cm材料可切割 {result4} 个35cm零件")
    waste = 120 - result4 * 35
    print(f"材料浪费: {waste} cm")
    #120cm材料可切割 3 个35cm零件
    #材料浪费: 15 cm

    示例5:计算机科学 - 内存页分配

    分配1024KB内存给36KB的页面
    result5 = idivide(1024, 36, floor)
    print(f"1024KB内存可分配 {result5} 个36KB页面")
    unused_memory = 1024 - result5 * 36
    print(f"未使用内存: {unused_memory} KB")
    #1024KB内存可分配 28 个36KB页面
    #未使用内存: 16 KB

    示例6:运输物流 - 集装箱装载

    每个集装箱最多装25吨,现有83吨货物
    result6 = idivide(83, 25, ceil)
    print(f"83吨货物需要 {result6} 个集装箱")  # 4个
    last_container_load = 83 - (result6 - 1) * 25
    print(f"最后一个集装箱装载: {last_container_load} 吨")
    #83吨货物需要 4 个集装箱
    #最后一个集装箱装载: 8 吨

    示例7:教育领域 - 学生分组

    35名学生,每组最多8人
    result7 = idivide(35, 8, ceil)
    print(f"35名学生需要分成 {result7} 组")  # 5组
    last_group_size = 35 - (result7 - 1) * 8
    print(f"最后一组人数: {last_group_size} 人")
    #35名学生需要分成 5 组
    #最后一组人数: 3 人

    示例8:餐饮业 - 食材包装

    每包250克面粉,需要制作1800克面团
    result8 = idivide(1800, 250, ceil)
    print(f"制作1800克面团需要 {result8} 包面粉")  # 8包
    excess_flour = result8 * 250 - 1800
    print(f"多余面粉: {excess_flour} 克")
    #制作1800克面团需要 8 包面粉
    #多余面粉: 200 克

    示例9:矩阵运算示例 - 图像像素处理

    将像素矩阵除以16进行归一化(使用向下取整)
    result9 = idivide([[64, 128, 192], [32, 96, 160], [16, 48, 80]], 16, floor)
    print("像素矩阵归一化结果:")
    print(result9)
    #像素矩阵归一化结果:
    #[[4,8,12]
      [2,6,10]
      [1,3,5]]

    示例10:负数处理 - 温度计算

    零下温度的分组计算
    result10_floor = idivide(-15, 4, floor)
    result10_fix = idivide(-15, 4, fix)
    print(f"-15°C 每4°C一组 (floor): {result10_floor} 组")
    print(f"-15°C 每4°C一组 (fix): {result10_fix} 组")
    #-15°C 每4°C一组 (floor): -4 组
    #-15°C 每4°C一组 (fix): -3 组

    示例11:批量生产 - 产品包装

    生产235个产品,每箱装24个
    result11 = idivide(235, 24, floor)
    print(f"235个产品可装满 {result11} 箱")
    remaining_products = 235 - result11 * 24
    print(f"零散产品: {remaining_products} 个")
    #235个产品可装满 9 箱
    #零散产品: 19 个

    示例12:建筑行业 - 瓷砖铺设

    墙面宽285cm,瓷砖宽30cm
    result12 = idivide(285, 30, floor)
    print(f"285cm墙面需要 {result12} 块30cm瓷砖")
    gap = 285 - result12 * 30
    print(f"两端留空: {gap} cm")
    #285cm墙面需要 9 块30cm瓷砖
    #两端留空: 15 cm

    示例13:数据分析 - 数据分桶

    将0-999的数据分成10个桶
    result13 = idivide([0, 123, 456, 789, 999], 100, floor)
    print("数据分桶索引:", result13)
    #数据分桶索引: [0,1,4,7,9]

    示例14:网络传输 - 数据包分割

    传输1500字节数据,每个包最大1460字节
    result14 = idivide(1500, 1460, ceil)
    print(f"1500字节数据需要 {result14} 个数据包")
    last_packet_size = 1500 - (result14 - 1) * 1460
    print(f"最后一个包大小: {last_packet_size} 字节")
    #1500字节数据需要 2 个数据包
    #最后一个包大小: 40 字节

    示例15:能源管理 - 电池组配置

    需要提供48V电压,每个电池3.7V
    result15 = idivide(48, 3.7, ceil)
    print(f"提供48V电压需要 {result15} 个3.7V电池串联")
    actual_voltage = result15 * 3.7
    print(f"实际电压: {actual_voltage} V")
    #提供48V电压需要 13 个3.7V电池串联
    #实际电压: 48.1 V
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import sympy as sp


    def integer_division(input_str):
        """
        执行整数除法运算,对标MATLAB的idivide函数

        参数:
        input_str (str): 输入字符串,支持以下格式:
            - 标量运算: "(被除数, 除数, '舍入选项')"
            - 矩阵运算: "(矩阵A, 矩阵B, '舍入选项')"
            - 单矩阵运算: "(矩阵, 标量, '舍入选项')"

        返回:
        sympy.Expr/sympy.Matrix/str: 计算结果或错误信息

        示例:
        >>> integer_division("(10, 3, 'fix')")  # 10 ÷ 3 向零取整
        3
        >>> integer_division("([[1,2],[3,4]], 2, 'floor')")  # 矩阵逐元素除
        Matrix([[0, 1], [1, 2]])
        """
        try:
            # 预处理输入
            expr = sp.sympify(input_str)
            error = False
            result = None

            def elementwise_divide(a, b, option='fix'):
                """
                执行逐元素除法,支持不同维度的数值标量、向量和多维数组

                参数:
                    a, b: 数值标量、列表(向量)、嵌套列表(多维数组)或NumPy数组
                    option: 舍入选项
                        'fix'   - 向零取整 (默认)
                        'floor' - 向下取整
                        'ceil'  - 向上取整

                返回:
                    与输入维度匹配的结果(标量、列表或NumPy数组)
                """
                # 将输入转换为NumPy数组
                a_arr = np.asarray(a)
                b_arr = np.asarray(b)

                # 检查除数是否包含零
                if np.any(b_arr == 0):
                    raise ZeroDivisionError("除数不能包含零")

                # 执行逐元素除法
                result = a_arr / b_arr

                # 应用舍入选项
                if option == 'fix':
                    # 向零取整
                    result = np.trunc(result)
                elif option == 'floor':
                    # 向下取整
                    result = np.floor(result)
                elif option == 'ceil':
                    # 向上取整
                    result = np.ceil(result)
                else:
                    raise ValueError(f"无效舍入选项: {option}")

                # 转换为整数类型
                result = result.astype(int)

                # 保持与输入相同的类型
                if isinstance(a, (int, float)) and isinstance(b, (int, float)):
                    return int(result)  # 标量输入返回整数
                elif isinstance(a, list) or isinstance(b, list):
                    return result.tolist()  # 列表输入返回列表
                return result  # NumPy数组输入返回数组

            if isinstance(expr, tuple):
                # 解析参数数量和类型
                n = float(expr[0])
                a = float(expr[1])
                option = expr[2] if len(expr) > 2 else 'fix'  # 默认舍入方式

                result = elementwise_divide(n, a, str(option))
            else:
                error = True

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

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


    # 示例测试
    if __name__ == "__main__":
        # 标量测试
        print("-10 ÷ 3 (floor):", integer_division("(-10, 3, 'floor')"))
        # -4

        print("7 ÷ 3 (ceil):", integer_division("(7, 3, 'ceil')"))
        # 3
    
    
    快速傅里叶逆变换

    X = ifft(Y) 使用快速傅里叶变换算法计算 Y 的逆离散傅里叶变换。X 与 Y 的大小相同。

    如果 Y 是向量,则 ifft(Y) 返回该向量的逆变换。

    如果 Y 是矩阵,则 ifft(Y) 返回该矩阵每一列的逆变换。

    X = ifft(Y,n) 通过用尾随零填充 Y 以达到长度 n,返回 Y 的 n 点傅里叶逆变换。

    X = ifft(Y,n,dim) 返回沿维度 dim 的傅里叶逆变换。例如,如果 Y 是矩阵,则 ifft(Y,n,2) 返回每一行的 n 点逆变换。

    Y — 输入数组, 向量 | 矩阵

    n — 逆变换长度, 0 (默认) | 非负整数标量

    dim — 沿其运算的维度, 正整数标量

    示例1:音频信号处理 - 从频域恢复音频信号

    模拟一个简单的音频频域信号(基频和几个谐波)
    audio_reconstructed = ifft([10+0@i, 2+1@i, 1-0.5@i, 0.5+0.2@i, 0.3-0.1@i])
    print("音频信号重建结果:", audio_reconstructed)
    #音频信号重建结果:
    #[[2.76 + 0.12*I],
      [1.772500220836 + 0.486301819419587*I],
      [1.45809661311434 - 0.0594227445000619*I],
      [1.98301794868567 - 0.268905412799913*I],
      [2.02638521736398 - 0.277973662119612*I]]

    示例2:图像处理 - 从频域重建图像

    模拟简单的2x2图像的频域表示
    image_reconstructed = ifft([[100, 50+30@i], [20-10@i, 10+5@i]])
    print("图像重建结果:")
    print(image_reconstructed)
    #图像重建结果:
    #[[60.0 - 5.0*I, 30.0 + 17.5*I],
      [40.0 + 5.0*I, 20.0 + 12.5*I]]

    示例3:通信系统 - QAM调制信号解调

    4-QAM调制的频域信号
    qam_demodulated = ifft([ (1+1@i)*10, (1-1@i)*5, (-1+1@i)*3, (-1-1@i)*7 ])
    print("QAM解调结果:", qam_demodulated)
    #QAM解调结果:
    #[[1.25 + 0.25*I],
      [2.75 + 4.75*I],
      [2.25 + 6.25*I],
      [3.75 - 1.25*I]]

    示例4:振动分析 - 机械振动信号重建

    包含多个频率成分的振动信号频域表示
    vibration_time = ifft([50+0@i, 15+8@i, 8-4@i, 3+2@i, 1-1@i, 0.5+0.3@i])
    print("振动时域信号:", vibration_time)
    #振动时域信号:
    #[[12.9166666666667 + 0.883333333333333*I],
      [7.69661343370219 + 3.87825769689424*I],
      [5.24725469658442 + 1.14086508806388*I],
      [6.75 - 2.55*I],
      [8.33607863674892 - 1.02419842139721*I],
      [9.05338656629781 - 2.32825769689424*I]]

    示例5:电力系统 - 电网谐波分析重建

    电网信号中的基波和谐波成分
    power_waveform = ifft([100, 5+2@i, 3-1@i, 2+0.5@i, 1-0.3@i])  # 基波50Hz + 谐波
    print("电网电压波形:", power_waveform)
    #电网电压波形:
    #[[22.2 + 0.24*I],
      [19.300652977067 + 1.06436974101959*I],
      [18.7824984301819 - 0.0259505789500291*I],
      [19.8938947720681 - 0.585984376099925*I],
      [19.822953820683 - 0.692434785969641*I]]

    示例6:雷达信号处理 - 距离像重建

    雷达回波的频域信号(多个目标反射)
    radar_range_profile = ifft([20, 15-5@i, 8+3@i, 3-2@i, 1+1@i])
    print("雷达距离像:", radar_range_profile)
    #雷达距离像:
    #[[9.4 - 0.6*I],
      [3.76249956163666 + 2.84172650354396*I],
      [3.74738182467117 + 1.40375918449872*I],
      [0.434584186578931 + 0.0142748042511762*I],
      [2.65553442711324 - 3.65976049229385*I]]

    示例7:医学成像 - MRI图像重建

    模拟MRI的k-space数据(频域)
    mri_kspace = [[80, 25+15@i, 10-8@i], [18+12@i, 40+20@i, 5-3j], [8-6@i, 12+8@i, 30]]
    mri_image = ifft(mri_kspace)
    print("MRI图像重建结果:")
    print(mri_image)
    #MRI图像重建结果:
    #[[35.3333333333333 + 2.0*I, 25.6666666666667 + 14.3333333333333*I, 15.0 - 3.66666666666667*I],
      [17.1371809106267 + 1.88675134594813*I, -3.79743494847109 + 8.41623710198809*I, -1.63397459621556 - 9.38354503153699*I],
      [27.52948575604 - 3.88675134594813*I, 3.13076828180442 - 7.74957043532143*I, -3.36602540378444 + 5.05021169820365*I]]

    示例8:地震信号处理

    地震波的频域表示
    seismic_wave = ifft([45, 20+10@i, 12-6@i, 8+4@i, 5-2@i, 3+1@i, 1-0.5@i])
    print("地震波时域信号:", seismic_wave)
    #地震波时域信号:
    #[[13.4285714285714 + 0.928571428571428*I],
      [5.57926270451576 + 4.30923152078805*I],
      [3.76213634794582 + 2.27300818609102*I],
      [2.3801516499138 - 1.14137195495892*I],
      [6.91677082451423 - 2.32196950854944*I],
      [6.21440502135265 - 1.23361530876399*I],
      [6.7187020231863 - 2.81385436317814*I]]

    示例9:语音识别 - 语音特征重建

    语音信号的MFCC频域表示(简化)
    speech_signal = ifft([30, 12+6@i, 8-4@i, 5+2@i, 3-1@i, 2+0.5@i])
    print("重建的语音信号:", speech_signal)
    #重建的语音信号:
    #[[10.0 + 0.583333333333333*I],
      [4.05582274842315 + 2.7900635094611*I],
      [2.52313067797205 + 0.930021169820365*I],
      [3.66666666666667 - 2.25*I],
      [4.97686932202795 - 0.513354503153699*I],
      [4.77751058491018 - 1.5400635094611*I]]

    示例10:金融时间序列 - 价格波动重建

    股票价格波动的频域成分
    stock_prices = ifft([100, 25-12@i, 15+8@i, 8-5@i, 5+3@i])
    print("重建的价格序列:", stock_prices)
    #重建的价格序列:
    #[[30.6 - 1.2*I],
      [19.45755168505 + 3.5854846318902*I],
      [20.8034789071199 + 2.66130267285655*I],
      [12.3312735086303 + 0.621978900143196*I],
      [16.8076958991999 - 5.66876620488995*I]]

    示例11:光学成像 - 相位恢复

    光波的频域相位信息
    optical_wavefront = ifft([[50+25@i, 30-15@i], [20+10@i, 40-20@i]])
    print("光波波前重建:")
    print(optical_wavefront)
    #光波波前重建:
    #[[35.0 + 17.5*I, 35.0 - 17.5*I],
      [15.0 + 7.5*I, -5.0 + 2.5*I]]

    示例12:量子计算 - 波函数重建

    量子态的频域表示
    quantum_wavefunction = ifft([0.7+0@i, 0.5+0.3@i, 0.3-0.2@i, 0.1+0.1@i])
    print("量子波函数:", quantum_wavefunction)
    #量子波函数:
    #[[0.4 + 0.05*I],
      [0.05 + 0.15*I],
      [0.1 - 0.15*I],
      [0.15 - 0.05*I]]

    示例13:气象数据 - 天气模式重建

    气象数据的频域成分
    weather_freq = ""
    weather_pattern = ifft([60, 20+10@i, 15-8@i, 10+5@i, 6-3@i])
    print("天气模式时域序列:", weather_pattern)
    #天气模式时域序列:
    #[[22.2 + 0.8*I],
      [8.61729811246802 + 4.1687774866688*I],
      [5.33720800279718 - 0.623291798626124*I],
      [13.3391851994528 - 2.01277617887367*I],
      [10.506308685282 - 2.33270950916901*I]]

    示例14:生物信号 - ECG心电图重建

    心电信号的频域特征
    ecg_signal = ifft([40, 15+7@i, 10-5@i, 6+3@i, 4-2@i, 2+1@i])
    print("重建的ECG信号:", ecg_signal)
    #重建的ECG信号:
    #[[12.8333333333333 + 0.666666666666667*I],
      [5.48365396477445 + 3.49241377865072*I],
      [3.78429522765668 + 1.42702963774851*I],
      [5.16666666666667 - 3.0*I],
      [6.38237143900999 - 0.593696304415178*I],
      [6.34967936855889 - 1.99241377865072*I]]

    示例15:音乐合成 - 乐器音色重建

    钢琴音的谐波结构
    piano_sound = ifft([25, 12+6@i, 8-4@i, 6+3@i, 4-2@i, 3+1@i, 2-1@i])
    print("合成的钢琴音:", piano_sound)
    #合成的钢琴音:
    #[[8.57142857142857 + 0.428571428571429*I],
      [2.78626268021768 + 2.34925211529782*I],
      [1.87488438967884 + 1.17571274243983*I],
      [0.742661597596697 - 0.60261412512079*I],
      [4.12008535390303 - 1.28248149746338*I],
      [3.3276720092561 - 0.543200817929995*I],
      [3.57700539791907 - 1.52523984579491*I]]

    示例16:多通道EEG信号重建

    沿通道方向(axis=1)
    eeg_channels = ifft([[10+2@i, 8-1@i, 6+3@i], [5+1@i, 4-0.5@i, 3+1.5@i]],0,1)
    print("各通道EEG信号:")
    print(eeg_channels)
    #各通道EEG信号:
    #[[8.0 + 1.33333333333333*I, 2.15470053837925 + 0.910683602522959*I, -0.154700538379251 - 0.244016935856292*I],
      [4.0 + 0.666666666666667*I, 1.07735026918963 + 0.455341801261479*I, -0.0773502691896257 - 0.122008467928146*I]]

    示例17:指定变换长度

    使用零填充到8点
    padded_signal = ifft([1, 0.5+0.5@i, 0.2-0.1@i], 8)
    print("零填充重建信号:", padded_signal)
    #零填充重建信号:
    #[[0.2125 + 0.05*I],
      [0.1375 + 0.113388347648318*I],
      [0.0375 + 0.075*I],
      [0.0241116523516816 - 0.025*I],
      [0.0875 - 0.075*I],
      [0.1375 - 0.0633883476483184*I],
      [0.1625 - 0.05*I],
      [0.200888347648318 - 0.025*I]]

    示例18:实数信号的复频域重建

    实数信号的对称频域表示

    real_signal = ifft([10+0@i, 3-2@i, 1+1@i, 0.5-0.3@i, 0.2+0.1@i])
    print("重建的实数信号:", real_signal)
    #重建的实数信号:
    #[[2.94 - 0.24*I],
      [2.2016853493354 + 0.360681337279561*I],
      [2.0690787221121 + 0.584742926729242*I],
      [1.08078972171294 + 0.116634747420703*I],
      [1.70844620683956 - 0.822059011429506*I]]
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import sympy as sp


    def inverse_fft(input_str):
        """
        模拟MATLAB的ifft函数行为

        参数:
        x: 输入数组
        n: FFT点数(默认为输入长度)
        axis: 计算轴(MATLAB默认按列,对应axis=0)

        返回:
        与MATLAB ifft结果一致的复数数组
        """
        # 检验输入 x 是否为数组
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None
            n = 0
            axis = 0

            if isinstance(expr, tuple):
                if len(expr) == 3:
                    matrix_sp = sp.Matrix(expr[0])
                    n = expr[1]
                    axis = expr[2]
                elif len(expr) == 2:
                    matrix_sp = sp.Matrix(expr[0])
                    n = expr[1]
                else:
                    error = True
            else:
                matrix_sp = sp.Matrix(expr)

            # 校验矩阵有效性
            if matrix_sp is None:
                raise ValueError("输入无法转换为有效矩阵(支持 SymPy 矩阵或列表)")

            # ---------------------- 转换为 NumPy 数组 ----------------------
            # 保持原始矩阵的复数类型(SymPy 矩阵元素可能是复数)
            x = np.array(matrix_sp, dtype=complex)
            # 若输入是列矩阵,转换为二维数组(与 MATLAB 列优先一致)
            if x.ndim == 1:
                x = x.reshape(-1, 1)

            # 检验输入 n 是否为有效的整数
            if n != 0:
                if not isinstance(n, (int, sp.Integer)) or n <= 0:
                    raise ValueError("参数 n 必须是正整数。")
            else:
                n = None

            # 检验输入 axis 是否为有效的轴索引
            if not isinstance(axis, (int, sp.Integer)):
                raise ValueError("参数 axis 必须是整数。")
            if axis < -x.ndim or axis >= x.ndim:
                raise IndexError(f"参数 axis 超出了数组的有效轴范围 [-{x.ndim}, {x.ndim - 1}]。")

            # 调整轴方向(MATLAB默认按列计算,对应NumPy的axis=0)
            if not error:
                result = sp.Matrix(np.fft.ifft(x, n=n, axis=axis))

            if result.shape[1] == 1:
                result = result.T
            return result

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


    if __name__ == "__main__":
        # 一维数组示例
        result_1d = inverse_fft("[1, 1j, -1, -1j]")
        print("一维数组逆傅里叶变换结果:", result_1d)
        # Matrix([[0, 0, 0, 1.00000000000000]])

        # 二维数组示例
        # 沿第 0 轴进行逆傅里叶变换
        result_2d_axis0 = inverse_fft("[[1, 1j], [-1, -1j]], 0, 0")
        print("二维数组沿第 0 轴逆傅里叶变换结果:")
        print(result_2d_axis0)
        # Matrix([[0, 0],
                  [1.00000000000000, 1.0*I]])

        # 沿第 1 轴进行逆傅里叶变换
        result_2d_axis1 = inverse_fft("[[1, 1j], [-1, -1j]], 0, 1")
        print("二维数组沿第 1 轴逆傅里叶变换结果:")
        print(result_2d_axis1)
        # Matrix([[0.5 + 0.5*I, 0.5 - 0.5*I],
                  [-0.5 - 0.5*I, -0.5 + 0.5*I]])

        # 指定 FFT 点数示例
        result_1d_n = inverse_fft("[[1, 1j], [-1, -1j]], 8")
        print("\n一维数组指定 FFT 点数为 8 的逆傅里叶变换结果:", result_1d_n)
        # Matrix([[0, 0],
        #         [0.0366116523516816 - 0.0883883476483184*I, 0.0883883476483184 + 0.0366116523516816*I],
        #         [0.125 - 0.125*I, 0.125 + 0.125*I],
        #         [0.213388347648318 - 0.0883883476483184*I, 0.0883883476483184 + 0.213388347648318*I],
        #         [0.250000000000000, 0.25*I],
        #         [0.213388347648318 + 0.0883883476483184*I, -0.0883883476483184 + 0.213388347648318*I],
        #         [0.125 + 0.125*I, -0.125 + 0.125*I],
        #         [0.0366116523516816 + 0.0883883476483184*I, -0.0883883476483184 + 0.0366116523516816*I]])
    
    
    二维快速傅里叶逆变换

    X = ifft2(Y) 使用快速傅里叶变换算法返回矩阵的二维离散傅里叶逆变换。如果 Y 是一个多维数组,则 ifft2 计算大于 2 的每个维度的二维逆变换。输出 X 的大小与 Y 相同。

    X = ifft2(Y,m,n) 在计算逆变换之前截断 Y 或用尾随零填充 Y,以形成 m×n 矩阵。X 也是 m×n。如果 Y 是一个多维数组,ifft2 将根据 m 和 n 决定 Y 的前两个维度的形状。

    Y — 输入数组, 矩阵

    m — 逆变换行数, 正整数标量

    n — 逆变换列数, 正整数标量

    # 继续在 __main__ 中添加以下示例

    示例1:图像处理 - 从频域重建图像

    模拟一个简单图像的频域表示(4x4像素)
    image_freq = [
        [100, 50+30@i, 30-20@i, 10+5@i],
        [40+20@i, 80+10@i, 20-15@i, 5+2@i],
        [25-10@i, 15+8@i, 60, 8-3@i],
        [10+5@i, 8-4@i, 6+2@i, 40]
    ]
    image_reconstructed = ifft2(image_freq)
    print("图像重建结果:")
    print(image_reconstructed)
    #图像重建结果:
    #[[31.6875 + 1.875*I, 1.1875 + 8.625*I, 4.6875 - 4.125*I, 6.1875 - 2.625*I],
      [4.25 + 6.3125*I, -3.0 + 4.1875*I, 1.625 - 2.0625*I, 12.125 + 1.5625*I],
      [5.5625 - 0.625*I, -1.3125 - 1.5*I, 11.8125 - 4.625*I, 2.6875 - 2.0*I],
      [6.0 - 3.8125*I, 14.375 + 3.6875*I, -0.625 - 2.9375*I, 2.75 - 1.9375*I]]

    示例2:医学成像 - MRI图像重建

    模拟MRI的k-space数据(频域)
    mri_kspace = [
        [80, 25+15@i, 10-8@i, 5+3@i],
        [18+12@i, 40+20@i, 5-3@i, 2+1@i],
        [8-6@i, 12+8@i, 30, 4-2@i],
        [3+2@i, 6-4@i, 8+5@i, 20]
    ]
    mri_image = ifft2(mri_kspace)
    print("MRI图像重建:")
    print(mri_image)
    #MRI图像重建:
    #[[17.25 + 2.6875*I, 1.1875 + 4.125*I, 3.0 - 2.4375*I, 5.8125 - 2.375*I],
      [2.4375 + 2.375*I, 1.25 + 1.3125*I, 3.8125 - 1.125*I, 8.0 + 2.6875*I],
      [4.5 - 1.4375*I, 2.0625 - 0.375*I, 7.25 - 2.3125*I, 2.9375 - 0.875*I],
      [5.8125 - 1.125*I, 10.0 + 1.9375*I, 0.9375 - 0.625*I, 3.75 - 2.4375*I]]

    示例3:地震勘探 - 地下结构成像

    地震波场在频域的表示
    seismic_data = [
        [45, 20+10@i, 12-6@i, 8+4@i],
        [15+8@i, 35+5@i, 10-5@i, 6+3@i],
        [10-4@i, 8+6@i, 25, 5-2@i],
        [6+3@i, 5-2@i, 4+1@i, 15]
    ]
    seismic_image = ifft2(seismic_data)
    print("地下结构图像:")
    print(seismic_image)
    #地下结构图像:
    #[[14.3125 + 1.3125*I, 0.6875 + 3.1875*I, 1.5625 - 1.6875*I, 2.4375 - 1.0625*I],
      [1.75 + 2.75*I, 1.125*I, 1.125 - 1.125*I, 4.625 + 0.5*I],
      [2.3125 - 0.3125*I, -0.1875 - 1.0625*I, 4.8125 - 1.8125*I, 1.5625 - 0.5625*I],
      [2.875 - 1.75*I, 6.25 + 1.25*I, -0.25 - 0.375*I, 1.125 - 0.375*I]]

    示例4:光学成像 - 相位恢复

    光波的频域相位和振幅信息
    optical_field = [
        [50+25@i, 30-15@i, 20+10@i, 15-8@i],
        [25+12@i, 40-20@i, 18+9@i, 12-6@i],
        [20-10@i, 15+7@i, 35, 10-5@i],
        [12+6@i, 10-5@i, 8+4@i, 25]
    ]
    optical_wavefront = ifft2(optical_field)
    print("光波波前重建:")
    print(optical_wavefront)
    #光波波前重建:
    #[[21.5625 + 0.25*I, 2.5 + 2.6875*I, 1.9375 + 6.75*I, 0.75 - 1.4375*I],
      [2.8125 + 3.75*I, 1.25 + 2.9375*I, -2.3125 + 4.75*I, 4.25 + 0.5625*I],
      [2.8125 + 0.25*I, -1.25 + 0.4375*I, 4.9375 - 1.0*I, 1.75 - 0.4375*I],
      [1.5625 - 1.25*I, 6.75 + 1.4375*I, 1.6875 + 4.0*I, -1.0 + 1.3125*I]]

    示例5:遥感图像处理

    卫星采集的频域数据
    satellite_data = [
        [120, 45+20@i, 30-15@i, 20+10@i],
        [35+15@i, 90+25@i, 25-12@i, 15+8@i],
        [28-12@i, 22+10@i, 75, 18-9@i],
        [15+7@i, 12-6@i, 10+5@i, 60]
    ]
    satellite_image = ifft2(satellite_data)
    print("卫星图像重建:")
    print(satellite_image)
    #卫星图像重建:
    #[[38.75 + 2.875*I, 1.125 + 5.5*I, 3.5 - 4.375*I, 6.125 - 1.5*I],
      [2.625 + 5.875*I, -0.125 + 1.875*I, 4.375 - 1.875*I, 14.125 + 2.125*I],
      [6.0 - 2.375*I, 0.625 - 1.5*I, 15.0 - 2.875*I, 2.875 - 1.75*I],
      [6.375 - 2.625*I, 18.375 + 4.125*I, -1.625 - 2.125*I, 1.875 - 1.375*I]]

    示例6:材料科学 - 晶体结构分析

    X射线衍射的频域数据
    crystal_diffraction = [
        [200, 60+25@i, 40-18@i, 25+12@i],
        [50+20@i, 150+40@i, 35-15@i, 20+10@i],
        [40-15@i, 30+12@i, 120, 22-11@i],
        [18+9@i, 15-7@i, 12+6@i, 80]
    ]
    crystal_structure = ifft2(crystal_diffraction)
    print("晶体结构重建:")
    print(crystal_structure)
    #晶体结构重建:
    #[[57.3125 + 4.25*I, 2.625 + 9.3125*I, 7.0625 - 5.875*I, 10.0 - 4.1875*I],
      [4.125 + 10.1875*I, 1.4375 + 2.0*I, 7.125 - 3.6875*I, 24.5625 + 3.25*I],
      [9.8125 - 3.625*I, 2.875 - 3.5625*I, 25.8125 - 3.0*I, 4.5 - 0.8125*I],
      [10.0 - 6.0625*I, 29.8125 + 5.5*I, -1.25 - 1.1875*I, 4.1875 - 2.5*I]]

    示例7:雷达成像 - 合成孔径雷达(SAR)

    SAR数据的频域表示
    sar_data = [
        [150, 55+22@i, 35-16@i, 22+11@i],
        [42+18@i, 110+35@i, 30-14@i, 18+9@i],
        [32-14@i, 25+11@i, 95, 20-10@i],
        [16+8@i, 14-6@i, 11+5@i, 70]
    ]
    sar_image = ifft2(sar_data)
    print("SAR图像重建:")
    print(sar_image)
    #SAR图像重建:
    #[[46.5625 + 3.6875*I, 1.0625 + 6.9375*I, 4.8125 - 5.3125*I, 7.5625 - 2.3125*I],
      [3.0625 + 7.4375*I, 0.6875 + 2.0625*I, 5.3125 - 2.0625*I, 17.9375 + 2.5625*I],
      [7.6875 - 3.1875*I, 1.4375 - 1.9375*I, 18.9375 - 2.6875*I, 2.9375 - 2.1875*I],
      [8.1875 - 3.6875*I, 22.8125 + 5.1875*I, -2.0625 - 2.1875*I, 3.0625 - 2.3125*I]]

    示例8:计算机视觉 - 特征图重建

    CNN特征图的频域表示
    cnn_features = [
        [80, 25+10@i, 15-7@i, 10+5@i],
        [20+8@i, 45+15@i, 12-6@i, 8+4@i],
        [15-6@i, 12+5@i, 35, 9-4@i],
        [8+4@i, 7-3@i, 6+3@i, 25]
    ]
    feature_map = ifft2(cnn_features)
    print("特征图重建:")
    print(feature_map)
    #特征图重建:
    #[[20.75 + 1.75*I, 2.0625 + 3.3125*I, 3.125 - 2.25*I, 4.8125 - 1.3125*I],
      [2.625 + 3.25*I, 1.3125 + 1.0625*I, 3.625 - 1.125*I, 7.6875 + 1.3125*I],
      [4.375 - 1.375*I, 1.8125 - 0.9375*I, 8.0 - 1.375*I, 2.5625 - 0.8125*I],
      [4.75 - 1.625*I, 9.8125 + 2.0625*I, 0.25 - 0.75*I, 2.4375 - 1.1875*I]]

    示例9:音频频谱图重建

    音频信号的时频谱表示
    audio_spectrogram = [
        [60, 20+8@i, 12-5@i, 8+4@i],
        [18+7@i, 40+12@i, 10-4@i, 6+3@i],
        [12-4@i, 10+4@i, 30, 7-3@i],
        [6+3@i, 5-2@i, 4+2@i, 20]
    ]
    audio_signal = ifft2(audio_spectrogram)
    print("音频信号重建:")
    print(audio_signal)
    #音频信号重建:
    #[[16.75 + 1.5625*I, 1.375 + 2.9375*I, 2.25 - 1.6875*I, 3.625 - 1.3125*I],
      [1.625 + 3.0625*I, 0.625 + 0.8125*I, 2.375 - 0.9375*I, 6.375 + 1.0625*I],
      [3.125 - 1.0625*I, 1.0 - 0.9375*I, 6.375 - 1.0625*I, 1.5 - 0.4375*I],
      [3.5 - 1.8125*I, 8.0 + 1.4375*I, -0.5625*I, 1.5 - 1.0625*I]]

    示例10:流体动力学 - 流场重建

    流体速度的频域表示
    flow_field = [
        [90, 30+12@i, 18-8@i, 12+6@i],
        [25+10@i, 70+20@i, 15-7@i, 10+5@i],
        [20-8@i, 15+6@i, 55, 12-6@i],
        [10+5@i, 8-4@i, 7+3@i, 40]
    ]
    velocity_field = ifft2(flow_field)
    print("速度场重建:")
    print(velocity_field)
    #速度场重建:
    #[[27.3125 + 2.125*I, 1.3125 + 4.25*I, 2.6875 - 2.75*I, 4.9375 - 1.875*I],
      [1.5 + 4.5625*I, 0.375 + 1.1875*I, 3.25 - 1.6875*I, 11.125 + 1.6875*I],
      [4.1875 - 1.875*I, 1.0625 - 1.625*I, 11.5625 - 1.5*I, 1.9375 - 0.75*I],
      [4.5 - 2.3125*I, 13.75 + 2.6875*I, -1.0 - 0.5625*I, 1.5 - 1.5625*I]]

    示例11:图像超分辨率重建(补零至8x8)

    small_image = [
        [100, 50+30@i],
        [40+20@i, 80+10@ij]
    ]
    high_res_image = ifft2(small_image,8,8)
    print("超分辨率重建结果:")
    print(high_res_image)
    #超分辨率重建结果:
    #[[4.21875 + 0.9375*I, 3.18186891104358 + 2.19075238752677*I, 1.5625 + 2.34375*I, 0.309247612473233 + 1.30686891104358*I, 0.15625 - 0.3125*I, 1.19313108895642 - 1.56575238752677*I, 2.8125 - 1.71875*I, 4.06575238752677 - 0.681868911043582*I],
      [3.33811891104358 + 2.12603151840597*I, 1.84819173824159 + 2.79679608384557*I, 0.320351958077214 + 2.21756064928517*I, -0.350412607362389 + 0.727633476483184*I, 0.22882282719801 - 0.800206303681194*I, 1.71875 - 1.4709708691208*I, 3.24658978016438 - 0.891735434560398*I, 3.91735434560398 + 0.598191738241592*I],
      [1.875 + 2.34375*I, 0.476601958077214 + 2.28228151840597*I, -0.46875 + 1.25*I, -0.407281518405971 - 0.148398041922786*I, 0.625 - 1.09375*I, 2.02339804192279 - 1.03228151840597*I, 2.96875000000000, 2.90728151840597 + 1.39839804192279*I],
      [0.686468481594029 + 1.46311891104358*I, -0.129441738241592 + 0.948604345603981*I, -0.342560649285175 + 0.00785195807721362*I, 0.171953916154427 - 0.808058261758408*I, 1.11270630368119 - 1.02117717280199*I, 1.92861652351682 - 0.506662607362388*I, 2.1417354345604 + 0.434089780164379*I, 1.6272208691208 + 1.25*I],
      [0.468750000000000, 0.38507282719801 - 0.422985434560398*I, 0.625 - 0.78125*I, 1.0479854345604 - 0.86492717280199*I, 1.40625 - 0.625*I, 1.48992717280199 - 0.202014565439602*I, 1.25 + 0.15625*I, 0.827014565439602 + 0.23992717280199*I],
      [1.34938108895642 - 1.18853151840597*I, 1.71875 - 1.0290291308792*I, 1.86714804192279 - 0.655060649285175*I, 1.70764565439602 - 0.285691738241592*I, 1.33367717280199 - 0.137293696318806*I, 0.964308261758408 - 0.296796083845573*I, 0.815910219835621 - 0.670764565439602*I, 0.975412607362388 - 1.04013347648318*I],
      [2.8125 - 1.40625*I, 3.09033978016438 - 0.514514565439602*I, 2.65625 + 0.3125*I, 1.7645145654396 + 0.590339780164379*I, 0.9375 + 0.15625*I, 0.659660219835621 - 0.735485434560398*I, 1.09375 - 1.5625*I, 1.9854854345604 - 1.84033978016438*I],
      [4.00103151840597 - 0.525618911043582*I, 3.69638347648318 + 0.819162607362388*I, 2.53006064928517 + 1.55464804192279*I, 1.1852791308792 + 1.25*I, 0.449793696318806 + 0.0836771728019903*I, 0.754441738241592 - 1.26110434560398*I, 1.9207645654396 - 1.99658978016438*I, 3.26554608384557 - 1.69194173824159*I]]

    示例12:数据压缩重建(截断至2x2)

    compressed_data = [
        [100, 50+30@i, 30-20@i, 10+5@i],
        [40+20@i, 80+10@i, 20-15@i, 5+2@i],
        [25-10@i, 15+8@i, 60, 8-3@i],
        [10+5@i, 8-4@i, 6+2@i, 40]
    ]
    reconstructed_compressed = ifft2(compressed_data,2,2)
    print("压缩数据重建:")
    print(reconstructed_compressed)
    #压缩数据重建:
    #[[67.5 + 15.0*I, 2.5 - 5.0*I],
      [7.50000000000000, 22.5 - 10.0*I]]

    示例13:频域滤波重建

    原始信号 + 高频噪声
    noisy_signal = [
        [100, 50+30@i, 30-20@i, 10+5@i],
        [40+20@i, 80+10@i, 20-15@i, 5+2@i],
        [25-10@i, 15+8@i, 60, 8-3@i],
        [10+5@i, 8-4@i, 6+2@i, 40]
    ]
    通过截断高频分量来滤波
    filtered_signal = ifft2(noisy_signal,3,3)
    print("滤波后信号:")
    print(filtered_signal)
    #滤波后信号:
    #[[46.6666666666667 + 2.55555555555556*I, -3.82001205712316 + 3.75676545916171*I, 12.1533453904565 - 2.97898768138393*I],
      [5.03084090396273 + 4.23789068348639*I, -7.56908647387896 - 1.00106877147038*I, 16.3779915320718 - 0.573361559760487*I],
      [8.30249242937061 - 3.46011290570862*I, 16.9553418012615 + 1.35113933753826*I, 5.9024198072123 - 3.88782011741851*I]]

    示例14:模式识别 - 模板匹配

    频域模板数据
    template = [
        [70, 20+8@i, 12-5@i, 8+3@i],
        [15+6@i, 35+10@i, 8-3@i, 5+2@i],
        [10-4@i, 8+3@i, 25, 6-2@i],
        [5+2@i, 4-1@i, 3+1@i, 15]
    ]
    matched_pattern = ifft2(template)
    print("模板匹配结果:")
    print(matched_pattern)
    #模板匹配结果:
    #[[15.5625 + 1.25*I, 2.1875 + 2.75*I, 2.9375 - 1.625*I, 4.3125 - 1.375*I],
      [3.0 + 2.8125*I, 1.5 + 0.9375*I, 2.875 - 1.0625*I, 6.625 + 0.8125*I],
      [4.3125 - 0.875*I, 1.9375 - 0.875*I, 6.4375 - 1.0*I, 2.3125 - 0.25*I],
      [4.625 - 1.6875*I, 7.625 + 1.4375*I, 1.25 - 0.3125*I, 2.5 - 0.9375*I]]

    示例15:量子计算 - 二维量子态重建

    量子态的频域表示
    quantum_state = [
        [0.6, 0.2+0.1@i, 0.1-0.05@i, 0.05+0.02@i],
        [0.15+0.06@i, 0.3+0.1@i, 0.08-0.03@i, 0.04+0.02@i],
        [0.1-0.04@i, 0.08+0.03@i, 0.25, 0.06-0.02@i],
        [0.04+0.02@i, 0.03-0.01@i, 0.02+0.01@i, 0.15]
    ]
    quantum_wavefunction = ifft2(quantum_state)
    print("量子波函数重建:")
    print(quantum_wavefunction)
    #量子波函数重建:
    #[[0.140625 + 0.013125*I, 0.015 + 0.02625*I, 0.026875 - 0.016875*I, 0.04 - 0.0125*I],
      [0.020625 + 0.026875*I, 0.01 + 0.01125*I, 0.023125 - 0.006875*I, 0.06125 + 0.00625*I],
      [0.039375 - 0.008125*I, 0.0125 - 0.00375*I, 0.055625 - 0.010625*I, 0.02 - 0.0075*I],
      [0.036875 - 0.014375*I, 0.0675 + 0.01625*I, 0.006875 - 0.008125*I, 0.02375 - 0.01125*I]]

    示例16:实际工程数据验证

    创建一个已知的简单模式来验证变换的正确性
    test_pattern = [
        [4, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
    reconstructed_test = ifft2(test_pattern)
    print("测试模式重建:")
    print(reconstructed_test)
    #测试模式重建:
    #[[0.25, 0.25, 0.25, 0.25],
      [0.25, 0.25, 0.25, 0.25],
      [0.25, 0.25, 0.25, 0.25],
      [0.25, 0.25, 0.25, 0.25]]
    #应该是均匀的直流信号
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import sympy as sp


    def inverse_fft2(input_str):
        """
        对标 MATLAB 的 ifft2(Y, m, n) 函数,实现二维逆快速傅里叶变换

        参数:
        Y: 输入的二维频域数组(实数/复数)
        m: 变换后的行数(默认:Y 的行数)
        n: 变换后的列数(默认:Y 的列数)

        返回:
        二维时域数组,与 MATLAB ifft2 结果一致(数值精度误差在 1e-10 以内)
        """
        # Y, m=None, n=None
        # ---------------------- 参数校验 ----------------------
        # 校验 Y 是二维数组

        expr = sp.sympify(input_str)
        error = False
        result = m = n = None
        matrix = None

        if isinstance(expr, tuple):
            matrix = sp.Matrix(expr[0])
            if len(expr) == 3:
                m, n = expr[1], expr[2]
            elif len(expr) == 2:
                m = expr[1]
            else:
                error = True
        else:
            matrix = sp.Matrix(expr)

        if matrix is None:
            raise ValueError("输入 Y 必须是二维 NumPy 数组")
        else:
            Y = np.array(matrix)

        # 校验 m 和 n 为正整数或 None
        original_rows, original_cols = Y.shape
        if m is not None:
            if not isinstance(m, sp.Integer) or m <= 0:
                raise ValueError(f"参数 m 必须是正整数(当前值:{m})")
        else:
            m = original_rows  # 默认使用 Y 的行数

        if n is not None:
            if not isinstance(n, sp.Integer) or n <= 0:
                raise ValueError(f"参数 n 必须是正整数(当前值:{n})")
        else:
            n = original_cols  # 默认使用 Y 的列数

        # ---------------------- 补零/截断逻辑 ----------------------
        # 若 m/n 大于原尺寸,补零;若小于,截断
        # 注意:MATLAB 补零在末尾,截断从开头保留
        if not error:
            rows_needed = m
            cols_needed = n
            Y_padded = np.zeros((rows_needed, cols_needed), dtype=Y.dtype)
            # 计算实际截断的行数和列数(不超过原尺寸)
            truncate_rows = min(original_rows, rows_needed)
            truncate_cols = min(original_cols, cols_needed)
            # 填充数据(截断或复制原数据)
            Y_padded[:truncate_rows, :truncate_cols] = Y[:truncate_rows, :truncate_cols]

            # ---------------------- 计算二维逆 FFT ----------------------
            # numpy.fft.ifft2 会自动除以变换点数(m*n),与 MATLAB 一致
            result = np.fft.ifft2(Y_padded, s=(m, n))
            result = sp.Matrix(result)
        return result


    # ---------------------- 示例代码 ----------------------
    if __name__ == "__main__":
        # 示例 1:默认参数(m=原行数,n=原列数)
        Y1 = np.array([[1, 1j], [-1, -1j]], dtype=complex)
        result1 = inverse_fft2("[[1, 1j], [-1, -1j]]")
        print("示例1(默认参数)结果:\n", result1)
        # Matrix([[0, 0],
        #         [0.5 + 0.5*I, 0.5 - 0.5*I]])

        # 示例 2:补零(m=4, n=4)
        Y2 = np.array([[1, 1j], [-1, -1j]], dtype=complex)
        result2 = inverse_fft2("[[1, 1j], [-1, -1j]],4,4")
        print("\n示例2(补零至4x4):", result2)
        # Matrix([[0, 0, 0, 0],
        #         [0.125000000000000, 0, -0.125*I, 0.125 - 0.125*I],
        #         [0.125 + 0.125*I, 0, 0.125 - 0.125*I, 0.250000000000000],
        #         [0.125*I, 0, 0.125000000000000, 0.125 + 0.125*I]])

        # 示例3:截断(m=1, n=1)
        Y3 = np.array([[1, 1j], [-1, -1j]], dtype=complex)
        result3 = inverse_fft2("[[1, 1j], [-1, -1j]],1,1")
        print("\n示例3(截断至1x1)结果:\n", result3)
        # Matrix([[1.00000000000000]])
    
    
    多维快速傅里叶逆变换

    X = ifftn(Y) 使用快速傅里叶变换算法返回 N 维数组的多维离散傅里叶逆变换。N 维逆变换相当于沿 Y 的每个维度计算一维逆变换。输出 X 的大小与 Y 相同。

    X = ifftn(Y,sz) 将在进行逆变换之前根据向量 sz 的元素截断 Y 或用尾随零填充 Y。sz 的每个元素定义对应变换维度的长度。例如,如果 Y 是一个 5×5×5 数组,X = ifftn(Y,[8 8 8]) 将用零填充每个维度,从而产生 8×8×8 逆变换 X。

    Y — 输入数组, 向量 | 矩阵 | 多维数组

    sz — 逆变换维度的长度, 正整数向量

    示例1:三维医学成像 - CT扫描重建

    模拟CT扫描的频域数据(4x4x4体素)
    ct_scan_3d = [
        [[100+0@i, 50+30@i, 30-20@i, 10+5@i],
         [40+20@i, 80+10@i, 20-15@i, 5+2@i],
         [25-10@i, 15+8@i, 60+0@i, 8-3@i],
         [10+5@i, 8-4@i, 6+2@i, 40+0@i]],

        [[90+0@i, 45+25@i, 28-18@i, 12+6@i],
         [35+18@i, 75+15@i, 22-12@i, 8+4@i],
         [22-12@i, 18+10@i, 55+0@i, 10-5@i],
         [12+6@i, 10-5@i, 8+4@i, 35+0@i]],

        [[80+0@i, 40+20@i, 25-15@i, 15+7@i],
         [30+15@i, 70+12@i, 18-10@i, 10+5@i],
         [20-10@i, 15+8@i, 50+0@i, 12-6@i],
         [15+7@i, 12-6@i, 10+5@i, 30+0@i]],

        [[70+0@i, 35+15@i, 22-12@i, 18+8@i],
         [25+12@i, 65+10@i, 15-8@i, 12+6@i],
         [18-8@i, 12+6@i, 45+0@i, 15-7@i],
         [18+8@i, 15-7@i, 12+6@i, 25+0@i]]
    ]
    ct_reconstructed = ifftn(ct_scan_3d)
    print("三维CT扫描重建结果(形状):", np.array(ct_reconstructed).shape)
    #三维CT扫描重建结果(形状): (4, 4, 4)
    #返回三维体数据,用于医学诊断

    示例2:气象数据 - 四维气候模型重建

    模拟气候数据的频域表示(时间×高度×纬度×经度)

    这里简化为3x3x3x3数组
    climate_data_4d = [
        [[[100+0@i, 80+20@i, 60-15@i],
          [70+15@i, 90+10@i, 50-10@i],
          [55-12@i, 65+8@i, 85+0@i]],

         [[85+0@i, 65+18@i, 48-12@i],
          [60+12@i, 80+8@i, 45-8@i],
          [50-10@i, 55+6@i, 75+0@i]],

         [[75+0@i, 55+15@i, 40-10@i],
          [50+10@i, 70+6@i, 38-6@i],
          [45-8@i, 50+4@i, 65+0@i]]],

        [[[95+0@i, 75+18@i, 55-14@i],
          [65+14@i, 85+9@i, 52-9@i],
          [52-11@i, 62+7@i, 80+0@i]],

         [[80+0@i, 60+16@i, 45-11@i],
          [55+11@i, 75+7@i, 42-7@i],
          [48-9@i, 52+5@i, 70+0@i]],

         [[70+0@i, 50+13@i, 35-8@i],
          [45+8@i, 65+5@i, 35-5@i],
          [42-7@i, 45+3@i, 60+0@i]]],

        [[[90+0@i, 70+15@i, 50-12@i],
          [60+12@i, 80+7@i, 48-7@i],
          [50-9@i, 60+5@i, 75+0@i]],

         [[75+0@i, 55+14@i, 42-9@i],
          [50+9@i, 70+5@i, 40-5@i],
          [45-7@i, 50+4@i, 65+0@i]],

         [[65+0@i, 45+11@i, 30-6@i],
          [40+6@i, 60+3@i, 32-3@i],
          [40-5@i, 40+2@i, 55+0@i]]]
    ]
    climate_reconstructed = ifftn(climate_data_4d)
    print("四维气候数据重建结果(形状):", np.array(climate_reconstructed).shape)
    #四维气候数据重建结果(形状): (3, 3, 3, 3)
    #用于气候预测和天气建模

    示例3:材料科学 - 三维晶体结构分析

    X射线三维衍射数据
    crystal_3d = [
        [[200+0@i, 80+30@i, 50-20@i, 30+15@i],
         [60+25@i, 150+40@i, 40-18@i, 25+12@i],
         [45-18@i, 35+15@i, 120+0@i, 30-15@i],
         [25+12@i, 20-10@i, 15+8@i, 80+0@i]],

        [[180+0@i, 70+28@i, 45-18@i, 28+13@i],
         [55+22@i, 140+35@i, 38-16@i, 22+10@i],
         [40-16@i, 30+13@i, 110+0@i, 28-13@i],
         [22+10@i, 18-8@i, 12+6@i, 70+0@i]],

        [[160+0@i, 60+25@i, 40-15@i, 25+10@i],
         [50+20@i, 130+30@i, 35-14@i, 20+8@i],
         [35-14@i, 25+10@i, 100+0@i, 25-10@i],
         [20+8@i, 15-6@i, 10+4@i, 60+0@i]],

        [[140+0@i, 50+20@i, 35-12@i, 22+8@i],
         [45+18@i, 120+25@i, 32-12@i, 18+6@i],
         [30-12@i, 20+8@i, 90+0@i, 22-8@i],
         [18+6@i, 12-4@i, 8+3@i, 50+0@i]]
    ]
    crystal_structure_3d = ifftn(crystal_3d)
    print("三维晶体结构重建结果(形状):", np.array(crystal_structure_3d).shape)
    #三维晶体结构重建结果(形状): (4, 4, 4)
    #用于材料分析和纳米技术研究

    示例4:视频处理 - 时空数据重建

    视频数据的频域表示(时间×高度×宽度)
    video_sequence = [
        [[100+0@i, 60+25@i, 40-15@i],
         [50+20@i, 120+30@i, 35-12@i],
         [35-12@i, 45+15@i, 90+0@i]],

        [[95+0@i, 55+22@i, 38-13@i],
         [48+18@i, 115+25@i, 32-10@i],
         [32-10@i, 42+12@i, 85+0@i]],

        [[90+0@i, 50+20@i, 35-10@i],
         [45+15@i, 110+20@i, 30-8@i],
         [30-8@i, 40+10@i, 80+0@i]],

        [[85+0@i, 45+18@i, 32-8@i],
         [42+12@i, 105+15@i, 28-6@i],
         [28-6@i, 38+8@i, 75+0@i]]
    ]
    video_reconstructed = ifftn(video_sequence)
    print("视频序列重建结果(形状):", np.array(video_reconstructed).shape)
    #视频序列重建结果(形状): (4, 3, 3)
    #用于视频压缩和流媒体处理

    示例5:神经科学 - 三维fMRI脑部扫描重建

    功能性磁共振成像数据
    fmri_brain = [
        [[150+0@i, 60+25@i, 40-18@i, 25+12@i],
         [55+22@i, 130+35@i, 35-15@i, 20+10@i],
         [40-15@i, 50+18@i, 110+0@i, 22-11@i],
         [20+10@i, 18-8@i, 15+7@i, 70+0@i]],

        [[140+0@i, 55+22@i, 38-16@i, 22+10@i],
         [50+20@i, 120+30@i, 32-13@i, 18+8@i],
         [38-13@i, 45+15@i, 100+0@i, 20-10@i],
         [18+8@i, 15-6@i, 12+5@i, 65+0@i]],

        [[130+0@i, 50+20@i, 35-14@i, 20+8@i],
         [45+18@i, 110+25@i, 30-11@i, 15+6@i],
         [35-11@i, 40+12@i, 90+0@i, 18-8@i],
         [15+6@i, 12-4@i, 10+4@i, 60+0@i]],

        [[120+0@i, 45+18@i, 32-12@i, 18+6@i],
         [40+15@i, 100+20@i, 28-9@i, 12+4@i],
         [32-9@i, 35+10@i, 80+0@i, 15-6@i],
         [12+4@i, 10-3@i, 8+3@i, 55+0@i]]
    ]
    brain_activity = ifftn(fmri_brain)
    print("fMRI脑部活动重建结果(形状):", np.array(brain_activity).shape)
    #fMRI脑部活动重建结果(形状): (4, 4, 4)
    #用于神经科学研究和脑功能分析

    示例6:地震勘探 - 四维地震数据

    时间推移地震数据(时间×深度×纬度×经度)
    time_lapse_seismic = [
        [[[120+0@i, 50+20@i, 35-15@i],
          [45+18@i, 100+25@i, 30-12@i],
          [35-12@i, 40+15@i, 85+0@i]],

         [[55+22@i, 25+10@i, 18-8@i],
          [20+8@i, 45+12@i, 15-6@i],
          [18-6@i, 22+8@i, 40+0@i]],

         [[40+15@i, 18+7@i, 12-5@i],
          [15+6@i, 35+8@i, 10-4@i],
          [12-4@i, 15+5@i, 30+0@i]]],

        [[[115+0@i, 48+18@i, 32-13@i],
          [42+16@i, 95+22@i, 28-10@i],
          [32-10@i, 38+13@i, 80+0@i]],

         [[52+20@i, 22+8@i, 15-6@i],
          [18+6@i, 42+10@i, 12-4@i],
          [15-4@i, 20+6@i, 35+0@i]],

         [[38+13@i, 15+5@i, 10-3@i],
          [12+4@i, 32+6@i, 8-2@i],
          [10-2@i, 12+3@i, 25+0@i]]],

        [[[110+0@i, 45+15@i, 30-10@i],
          [40+14@i, 90+18@i, 25-8@i],
          [30-8@i, 35+10@i, 75+0@i]],

         [[50+18@i, 20+6@i, 12-4@i],
          [15+4@i, 40+8@i, 10-2@i],
          [12-2@i, 18+4@i, 30+0@i]],

         [[35+10@i, 12+3@i, 8-1@i],
          [10+2@i, 30+4@i, 6-0@i],
          [8-0@i, 10+1@i, 20+0@i]]]
    ]
    seismic_4d = ifftn(time_lapse_seismic)
    print("四维地震数据重建结果(形状):", np.array(seismic_4d).shape)
    #四维地震数据重建结果(形状): (3, 3, 3, 3)
    #用于石油勘探和储层监测

    示例7:数据压缩 - 指定较小尺寸

    compressed_3d = ifftn(ct_scan_3d, 2, 2, 2)
    print("压缩后的三维数据形状:", np.array(compressed_3d).shape)
    #压缩后的三维数据形状: (2, 2, 2)
    #用于有损压缩和数据存储优化

    示例8:三维超分辨率重建 - 指定较大尺寸

    super_res_3d = ifftn(ct_scan_3d, 6, 6, 6)
    print("超分辨率重建后的形状:", np.array(super_res_3d).shape)
    #超分辨率重建后的形状: (6, 6, 6)
    #通过频域插值提高空间分辨率

    示例9:非对称尺寸调整

    asymmetric_resize = ifftn(ct_scan_3d, 3, 5, 4)
    print("非对称调整后的形状:", np.array(asymmetric_resize).shape)
    #非对称调整后的形状: (3, 5, 4)
    #根据不同维度的重要性进行定制化重建

    示例10:五维数据示例(理论应用)

    模拟五维数据(例如:时间×空间×频率×极化×通道)
    five_d_data = [
        [[[[100+0@i, 80+20@i], [60+15@i, 45-10@i]],
          [[70+18@i, 55+12@i], [40-8@i, 30+8@i]]],

         [[[90+0@i, 70+18@i], [50+12@i, 38-8@i]],
          [[60+15@i, 45+10@i], [35-6@i, 25+6@i]]]],

        [[[[85+0@i, 65+15@i], [45+10@i, 35-6@i]],
          [[55+12@i, 40+8@i], [30-4@i, 22+4@i]]],

         [[[80+0@i, 60+12@i], [40+8@i, 30-4@i]],
          [[50+10@i, 35+6@i], [25-2@i, 18+2@i]]]]
    ]
    five_d_reconstructed = ifftn(five_d_data)
    print("五维数据重建结果(形状):", np.array(five_d_reconstructed).shape)
    #五维数据重建结果(形状): (2, 2, 2, 2, 2)
    #用于高级科学计算和理论研究

    示例11:实际工程验证

    创建一个简单的三维模式来验证变换
    simple_3d_pattern = [
        [[4+0@i, 0+0@i], [0+0@i, 0+0@i]],
        [[0+0@i, 0+0@i], [0+0@i, 0+0@i]]
    ]
    verified_pattern = ifftn(simple_3d_pattern)
    print("验证模式重建结果:")
    print(verified_pattern)
    #验证模式重建结果:
    #[[[0.5, 0.5], [0.5, 0.5]], [[0.5, 0.5], [0.5, 0.5]]]
    #应该是均匀的三维直流信号

    示例12:部分尺寸指定

    partial_sizes = ifftn(ct_scan_3d, 3)
    print("部分尺寸指定后的形状:", np.array(partial_sizes).shape)
    #部分尺寸指定后的形状: (3, 4, 4)
    #只指定第一个维度,其他维度使用默认值
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np

    def inverse_fftn(input_str):
        """
        对标MATLAB的ifftn函数,执行多维逆快速傅里叶变换。

        参数:
            input_str (str): 输入的字符串,格式为"Y"或"(Y, s1, s2, ...)",
                            其中Y是数组,s1, s2等是各维度的大小。

        返回:
            numpy.ndarray: 逆FFT结果。若指定sizes,则形状为sizes;否则与Y相同。
            或返回错误信息字符串。
        """
        try:
            expr = sp.sympify(input_str)
            arr = None
            sizes = None

            # 解析输入,判断是否为元组(包含数组和sizes参数)
            if isinstance(expr, tuple):
                if len(expr) < 1:
                    raise ValueError("输入格式错误,应为 (Y, s1, s2, ...)")
                arr = expr[0]
                sizes = list(expr[1:])  # 提取sizes参数
            else:
                arr = expr

            if arr is None:
                raise ValueError("输入 Y 必须是多维数组")

            if isinstance(arr, list):
                Y = np.array(arr)
            original_shape = Y.shape

            # 处理sizes参数
            if sizes is not None:
                # 补全sizes到原数组的维度数,不足部分使用原数组对应维度的大小
                while len(sizes) < len(original_shape):
                    sizes.append(original_shape[len(sizes)])
                # 校验并转换sizes为整数
                for i in range(len(sizes)):
                    s = sizes[i]
                    if isinstance(s, sp.Integer):
                        s = int(s)
                    elif isinstance(s, int):
                        pass
                    else:
                        raise ValueError(f"参数 sizes[{i}] 必须是整数,当前类型为 {type(s)}")
                    if s <= 0:
                        raise ValueError(f"参数 sizes[{i}] 必须是正整数,当前值为 {s}")
                    sizes[i] = s
            else:
                sizes = list(original_shape)

            # 创建补零/截断后的数组
            padded_Y = np.zeros(sizes, dtype=Y.dtype)
            # 计算各维度的切片范围
            slices = tuple(slice(0, min(orig, new)) for orig, new in zip(original_shape, sizes))
            padded_Y[slices] = Y[slices]

            # 执行逆FFTn
            result = np.fft.ifftn(padded_Y)
            return sp.Array(result)

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


    # 示范代码
    if __name__ == "__main__":
        # 示例1:不指定sizes,结果形状与原数组相同
        input1 = "[[1, 2], [3, 4]]"
        result1 = inverse_fftn(input1)
        print("示例1结果:", result1 if not isinstance(result1, str) else result1)
        # [[2.5, -0.5],
        #  [-1.0, 0]]

        # 示例2:指定sizes大于原数组维度
        input2 = "([[1, 2], [3, 4]], 3, 3)"
        result2 = inverse_fftn(input2)
        print("示例2结果:", result2 if not isinstance(result2, str) else result2)
        # [[1.11111111111111, 0.111111111111111 + 0.577350269189626*I, 0.111111111111111 - 0.577350269189626*I],
        #  [-0.0555555555555555 + 0.673575314054563*I, -0.388888888888889 + 0.0962250448649376*I, 0.277777777777778 + 0.0962250448649376*I],
        #  [-0.0555555555555555 - 0.673575314054563*I, 0.277777777777778 - 0.0962250448649376*I, -0.388888888888889 - 0.0962250448649376*I]]

        # 示例3:三维数组,sizes部分指定
        input3 = "([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], 2, 2)"
        result3 = inverse_fftn(input3)
        print("示例3结果:", result3 if not isinstance(result3, str) else result3)
        # [[[4.5, -0.5],
        #   [-1.0, 0]],
        #  [[-2.0, 0],
        #   [0, 0]]]
    
    
    逆零频平移

    X = ifftshift(Y) 将进行过零频平移的傅里叶变换 Y 重新排列回原始变换输出的样子。换言之,ifftshift 就是撤消 fftshift 的结果。

    如果 Y 是向量,则 ifftshift 会将 Y 的左右两半部分进行交换。

    如果 Y 是矩阵,则 ifftshift 会将 Y 的第一象限与第三象限交换,将第二象限与第四象限交换。

    如果 Y 是多维数组,则 ifftshift 会沿每个维度交换 Y 的半空间。

    X = ifftshift(Y,dim) 沿 Y 的维度 dim 执行运算。例如,如果 Y 是矩阵,其行表示多个一维变换,则 ifftshift(Y,2) 会将 Y 的每一行的左右两半部分进行交换。

    示例1:图像处理 - 频域滤波后的图像重建

    模拟经过频域中心化处理的图像频谱
    image_spectrum_centered = [
        [100+0@i, 50+30@i, 30-20@i, 10+5@i],
        [40+20@i, 80+10@i, 20-15@i, 5+2@i],
        [25-10@i, 15+8@i, 60+0@i, 8-3@i],
        [10+5@i, 8-4@i, 6+2@i, 40+0@i]
    ]

    在执行逆FFT前需要先进行ifftshift将零频移回角落
    image_reconstructed = ifftshift(image_spectrum_centered, [1, 2])
    print("频域图像重建前的零频调整:")
    print(image_reconstructed)
    #频域图像重建前的零频调整:
    #[[60 8 - 3*I 25 - 10*I 15 + 8*I]
      [6 + 2*I 40 10 + 5*I 8 - 4*I]
      [30 - 20*I 10 + 5*I 100 50 + 30*I]
      [20 - 15*I 5 + 2*I 40 + 20*I 80 + 10*I]]
    #用于图像处理中的频域滤波操作

    示例2:音频处理 - 频谱分析后的信号重建

    经过fftshift中心化的音频频谱
    audio_spectrum_centered = [0.1+0@i, 0.3-0.1@i, 0.5+0.2@i, 0.8+0@i, 0.5-0.2@i, 0.3+0.1@i]
    audio_reconstructed = ifftshift(audio_spectrum_centered)
    print("音频频谱重建前的零频调整:")
    print(audio_reconstructed)
    #音频频谱重建前的零频调整:
    #[0.8, 0.5 - 0.2*I, 0.3 + 0.1*I, 0.1, 0.3 - 0.1*I, 0.5 + 0.2*I]
    #用于音频信号处理和音乐分析

    示例3:医学成像 - MRI k-space数据重建

    MRI采集的k-space数据(已经过fftshift中心化)
    mri_kspace_centered = [
        [[80+0@i, 25+15@i], [10-8@i, 5+3@i]],
        [[18+12@i, 40+20@i], [5-3@i, 2+1@i]],
        [[8-6@i, 12+8@i], [30+0@i, 4-2@i]],
        [[3+2@i, 6-4@i], [8+5@i, 20+0@i]]
    ]
    mri_reconstructed = ifftshift(mri_kspace_centered, [1, 2, 3])
    print("MRI k-space重建前的三维零频调整:")
    print("调整后数组形状:", np.array(mri_reconstructed.tolist()).shape)
    #MRI k-space重建前的三维零频调整:
    #调整后数组形状: (4, 2, 2)
    #用于医学图像重建

    示例4:雷达信号处理 - 距离多普勒图重建

    雷达的距离-多普勒谱(已经中心化)
    radar_doppler_centered = [
        [0.5+0@i, 0.8+0.2@i, 1.2+0@i, 0.8-0.2@i],
        [0.3+0.1@i, 0.6+0.3@i, 0.9+0@i, 0.6-0.3@i],
        [0.2+0@i, 0.4+0.1@i, 0.7+0@i, 0.4-0.1@i],
        [0.1-0.1@i, 0.3+0@i, 0.5+0@i, 0.3+0.1@i]
    ]
    radar_reconstructed = ifftshift(radar_doppler_centered, [1, 2])
    print("雷达谱重建前的零频调整:")
    print(radar_reconstructed)
    #雷达谱重建前的零频调整:
    #[[0.7, 0.4 - 0.1*I, 0.2, 0.4 + 0.1*I]
      [0.5, 0.3 + 0.1*I, 0.1 - 0.1*I, 0.3]
      [1.2, 0.8 - 0.2*I, 0.5, 0.8 + 0.2*I]
      [0.9, 0.6 - 0.3*I, 0.3 + 0.1*I, 0.6 + 0.3*I]]
    #用于目标检测和速度测量

    示例5:地震数据处理 - 频率-波数域重建

    地震数据的频率-波数谱(中心化)
    seismic_fk_centered = [
        [45+0@i, 20+10@i, 12-6@i, 8+4@i],
        [15+8@i, 35+5@i, 10-5@i, 6+3@i],
        [10-4@i, 8+6@i, 25+0@i, 5-2@i],
        [6+3@i, 5-2@i, 4+1@i, 15+0@i]
    ]
    seismic_reconstructed = ifftshift(seismic_fk_centered, 2)
    print("地震数据列方向零频调整:")
    print(seismic_reconstructed)
    #地震数据列方向零频调整:
    #[[12 - 6*I, 8 + 4*I, 45, 20 + 10*I]
      [10 - 5*I, 6 + 3*I, 15 + 8*I, 35 + 5*I]
      [25, 5 - 2*I, 10 - 4*I, 8 + 6*I]
      [4 + I, 15, 6 + 3*I, 5 - 2*I]]
    #用于地震波场重建和速度分析

    示例6:通信系统 - OFDM子载波重建

    OFDM信号的子载波分布(中心化)
    ofdm_subcarriers_centered = [
        0.1+0@i, 0.3-0.05@i, 0.5+0.1@i, 0.7+0@i, 0.9-0.1@i,
        1.1+0@i, 0.9+0.1@i, 0.7+0@i, 0.5-0.1@i, 0.3+0.05@i
    ]
    ofdm_reconstructed = ifftshift(ofdm_subcarriers_centered)
    print("OFDM子载波重建前的零频调整:")
    print(ofdm_reconstructed)
    #OFDM子载波重建前的零频调整:
    #[1.1, 0.9 + 0.1*I, 0.7, 0.5 - 0.1*I, 0.3 + 0.05*I, 0.1, 0.3 - 0.05*I, 0.5 + 0.1*I, 0.7, 0.9 - 0.1*I]
    #用于5G和WiFi通信系统

    示例7:天文观测 - 射电望远镜数据重建

    射电望远镜的干涉测量数据(中心化)
    radio_telescope_centered = [
        [[120+0@i, 60+25@i], [30-15@i, 15+8@i]],
        [[45+18@i, 90+30@i], [20-10@i, 10+5@i]],
        [[25-12@i, 20+10@i], [70+0@i, 12-6@i]],
        [[15+7@i, 12-6@i], [10+5@i, 50+0@i]]
    ]
    telescope_reconstructed = ifftshift(radio_telescope_centered, [2, 3])
    print("射电数据重建前的零频调整:")
    print("调整后数组形状:", np.array(telescope_reconstructed.tolist()).shape)
    #射电数据重建前的零频调整:
    #调整后数组形状: (4, 2, 2)
    #用于天体成像和宇宙学研究

    示例8:材料科学 - 电子衍射图重建

    透射电镜的衍射图样(中心化)
    electron_diffraction_centered = [
        [200+0@i, 80+30@i, 50-20@i, 30+15@i],
        [60+25@i, 150+40@i, 40-18@i, 25+12@i],
        [45-18@i, 35+15@i, 120+0@i, 30-15@i],
        [25+12@i, 20-10@i, 15+8@i, 80+0@i]
    ]
    diffraction_reconstructed = ifftshift(electron_diffraction_centered, [1, 2])
    print("电子衍射图重建前的零频调整:")
    print(diffraction_reconstructed)
    #电子衍射图重建前的零频调整:
    #[[120, 30 - 15*I, 45 - 18*I, 35 + 15*I]
      [15 + 8*I, 80, 25 + 12*I, 20 - 10*I]
      [50 - 20*I, 30 + 15*I, 200, 80 + 30*I]
      [40 - 18*I, 25 + 12*I, 60 + 25*I, 150 + 40*I]]
    #用于晶体结构分析

    示例9:流体力学 - 湍流频谱重建

    湍流速度场的频谱(中心化)
    turbulence_spectrum_centered = [
        [0.8+0@i, 0.6+0.2@i, 0.4-0.1@i, 0.3+0.05@i],
        [0.5+0.15@i, 0.7+0.1@i, 0.35-0.08@i, 0.25+0.04@i],
        [0.3-0.1@i, 0.4+0.08@i, 0.6+0@i, 0.2-0.03@i],
        [0.2+0.05@i, 0.25-0.04@i, 0.18+0.02@i, 0.5+0@i]
    ]
    turbulence_reconstructed = ifftshift(turbulence_spectrum_centered, 1)
    print("湍流频谱行方向零频调整:")
    print(turbulence_reconstructed)
    #湍流频谱行方向零频调整:
    #[[0.3 - 0.1*I, 0.4 + 0.08*I, 0.6, 0.2 - 0.03*I]
      [0.2 + 0.05*I, 0.25 - 0.04*I, 0.18 + 0.02*I, 0.5]
      [0.8, 0.6 + 0.2*I, 0.4 - 0.1*I, 0.3 + 0.05*I]
      [0.5 + 0.15*I, 0.7 + 0.1*I, 0.35 - 0.08*I, 0.25 + 0.04*I]]
    #用于计算流体动力学

    示例10:量子计算 - 量子态频谱重建

    量子系统的能谱(中心化)
    quantum_spectrum_centered = [
        [0.6+0@i, 0.2+0.1@i, 0.1-0.05@i, 0.05+0.02@i],
        [0.15+0.06@i, 0.3+0.1@i, 0.08-0.03@i, 0.04+0.02@i],
        [0.1-0.04@i, 0.08+0.03@i, 0.25+0@i, 0.06-0.02@i],
        [0.04+0.02@i, 0.03-0.01@i, 0.02+0.01@i, 0.15+0@i]
    ]
    quantum_reconstructed = ifftshift(quantum_spectrum_centered, [1, 2])
    print("量子频谱重建前的零频调整:")
    print(quantum_reconstructed)
    #量子频谱重建前的零频调整:
    #[[0.25, 0.06 - 0.02*I, 0.1 - 0.04*I, 0.08 + 0.03*I]
      [0.02 + 0.01*I, 0.15, 0.04 + 0.02*I, 0.03 - 0.01*I]
      [0.1 - 0.05*I, 0.05 + 0.02*I, 0.6, 0.2 + 0.1*I]
      [0.08 - 0.03*I, 0.04 + 0.02*I, 0.15 + 0.06*I, 0.3 + 0.1*I]]
    #用于量子系统能级分析

    示例11:实际工程验证 - 奇数长度数组

    odd_length_array = [1, 2, 3, 4, 5]
    odd_reconstructed = ifftshift(odd_length_array)
    print("奇数长度数组零频调整:")
    print(odd_reconstructed)
    #奇数长度数组零频调整:
    #[4,5,1,2,3]
    #验证奇数长度时的正确性

    示例12:复数数据测试

    complex_data = [
        [1+2@i, 3+4@i, 5+6@i],
        [7+8@i, 9+10@i, 11+12@i],
        [13+14@i, 15+16@i, 17+18@i]
    ]
    complex_reconstructed = ifftshift(complex_data, [1, 2])
    print("复数数据零频调整:")
    print(complex_reconstructed)
    #复数数据零频调整:
    #[[17 + 18*I, 13 + 14*I, 15 + 16*I]
      [5 + 6*I, 1 + 2*I, 3 + 4*I]
      [11 + 12*I, 7 + 8*I, 9 + 10*I]]
    #验证复数数据的正确处理

    示例13:单维度操作测试

    测试只对行操作 vs 只对列操作
    test_matrix = [
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12]
    ]
    row_shift = ifftshift(test_matrix, 1)
    col_shift = ifftshift(test_matrix}, 2)
    both_shift = ifftshift(test_matrix}, [1, 2])

    print("只对行操作:")
    print(row_shift)
    print("只对列操作:")
    print(col_shift)
    print("同时对行列操作:")
    print(both_shift)
    #只对行操作:
    #[[9 10 11 12]
      [1 2 3 4]
      [5 6 7 8]]
    #只对列操作:
    #[[3 4 1 2]
      [7 8 5 6]
      [11 12 9 10]]
    #同时对行列操作:
    #[[11 12 9 10]
      [3 4 1 2]
      [7 8 5 6]]

    示例14:高维数据测试

    four_d_data = [
        [[[1, 2], [3, 4]], [[5, 6], [7, 8]]],
        [[[9, 10], [11, 12]], [[13, 14], [15, 16]]]
    ]
    four_d_reconstructed = ifftshift(four_d_data, [1, 2, 3, 4])
    print("四维数据零频调整后的形状:", np.array(four_d_reconstructed.tolist()).shape)
    #四维数据零频调整后的形状: (2, 2, 2, 2)
    #用于高维数据处理

    示例15:实际信号处理流程演示

    模拟完整的信号处理流程:fftshift -> 处理 -> ifftshift -> ifft
    original_signal = [1, 2, 3, 4, 5, 6]
    print("原始信号:", original_signal)
    #原始信号: [1, 2, 3, 4, 5, 6]

    模拟fftshift操作(中心化)
    fftshifted = [4, 5, 6, 1, 2, 3]  # 这是模拟的fftshift结果

    在频域进行处理后,需要ifftshift才能进行逆变换
    ifftshifted = ifftshift(fftshifted)
    print("ifftshift后的信号:", np.array(ifftshifted.tolist()))
    #ifftshift后的信号: [1 2 3 4 5 6]
    #应该恢复为原始信号顺序
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import sympy as sp


    def inverse_fft_shift(input_str):
        """
        实现类似 MATLAB 的 ifftshift 函数,支持指定维度进行操作。
        该函数将数组的零频率分量移到频谱中心。
        :param input_str: 输入的字符串,格式为数组或 (数组, 维度),维度为MATLAB风格的1-based索引
        :return: 零频率分量移到中心后的数组(SymPy数组格式)
        """
        expr = sp.sympify(input_str)
        arr = dim = None
        error = False

        # 解析输入,判断是否为元组(包含数组和维度参数)
        if isinstance(expr, tuple):
            if len(expr) < 1:
                raise ValueError("输入格式错误,应为 (数组, 维度)")
            arr_expr = expr[0]
            dim_expr = expr[1] if len(expr) >= 2 else None
            arr = arr_expr
            # 解析维度参数
            if dim_expr is not None:
                if isinstance(dim_expr, (sp.Integer, int)):
                    dim = int(dim_expr)
                elif isinstance(dim_expr, (list, tuple, sp.Array)):
                    dim = [int(d) for d in dim_expr]
                else:
                    raise ValueError("维度参数格式错误")
        else:
            arr = expr
            dim = None

        if arr is not None:
            # 转换为numpy数组进行处理
            if isinstance(arr, list):
                x = np.array(arr)
            axes = None
            # 处理维度参数,将MATLAB的1-based转换为Python的0-based
            if dim is None:
                axes = tuple(range(x.ndim))
            else:
                if isinstance(dim, int):
                    if dim < 1:
                        raise ValueError("维度必须大于等于1")
                    axes = (dim - 1,)
                elif isinstance(dim, (list, tuple)):
                    axes = []
                    for d in dim:
                        if d < 1:
                            raise ValueError("维度必须大于等于1")
                        axes.append(d - 1)
                    axes = tuple(axes)
                else:
                    raise ValueError("维度参数必须是整数、整数列表或整数元组")

            # 检查轴是否有效
            for ax in axes:
                if ax < 0 or ax >= x.ndim:
                    raise ValueError(f"轴{ax + 1}超出数组的维度范围(1-based)")

            # 计算每个轴的移动量(取半)
            shift = [x.shape[ax] // 2 for ax in axes]
            # 执行循环位移
            result = np.roll(x, shift=shift, axis=axes)
        else:
            error = True

        if not error:
            return sp.Array(result.tolist())  # 转换回SymPy数组
        else:
            return f"输入错误: {input_str}"


    if __name__ == "__main__":
        # 示例 1: 一维数组,不指定维度
        Y1 = [0, 1, 2, 3, 4]
        print("示例 1 - 原始一维数组:")
        result1 = inverse_fft_shift(f"{Y1}")
        print("示例 1 - 不指定维度经过ifftshift处理后的一维数组:")
        print(np.array(result1.tolist()))
        # [3 4 0 1 2]

        # 示例 2: 二维数组,沿第1个维度(行方向)执行ifftshift
        Y2 = [[0, 1, 2, 3],
              [4, 5, 6, 7],
              [8, 9, 10, 11]]
        print("\n示例 2 - 原始二维数组:")
        result2 = inverse_fft_shift(f"{Y2}, 1")
        print("示例 2 - 沿第1个维度经过ifftshift处理后的二维数组:")
        print(np.array(result2.tolist()))
        # [[8 9 10 11]
        #  [0 1 2 3]
        #  [4 5 6 7]]


        # 示例 3: 二维数组,沿第2个维度(列方向)执行ifftshift
        print("\n示例 3 - 原始二维数组(同示例 2):")
        result3 = inverse_fft_shift(f"{Y2}, 2")
        print("示例 3 - 沿第2个维度经过ifftshift处理后的二维数组:")
        print(np.array(result3.tolist()))
        # [[2 3 0 1]
        #  [6 7 4 5]
        #  [10 11 8 9]]

        # 示例 4: 二维数组,同时沿第1和第2个维度执行ifftshift
        print("\n示例 4 - 原始二维数组(同示例 2):")
        result4 = inverse_fft_shift(f"{Y2}, [1, 2]")
        print("示例 4 - 同时沿第1和第2个维度经过ifftshift处理后的二维数组:")
        print(np.array(result4.tolist()))
        # [[10 11 8 9]
        #  [2 3 0 1]
        #  [6 7 4 5]]

        # 示例 5: 三维数组,沿第3个维度执行ifftshift
        Y3 = [
            [[0, 1], [2, 3]],
            [[4, 5], [6, 7]]
        ]
        print("\n示例 5 - 原始三维数组:")
        result5 = inverse_fft_shift(f"{Y3}, 3")
        print("示例 5 - 沿第3个维度经过ifftshift处理后的三维数组:")
        print(np.array(result5.tolist()))
        # [[[1 0]
        #   [3 2]]
        #  [[5 4]
        #   [7 6]]]
    
    
    逆傅里叶变换

    ifourier(F) 返回 F 的逆傅里叶变换. 默认情况下独立变量为w, 变换变量为x. 如果F不包含w, ifourier将使用函数symvar.

    ifourier(F,transVar) 使用变换变量 transVar 而不是 x.

    ifourier(F,var,transVar) 分别使用独立变量 var 和变换变量 transVar 而不是 w 和 x.

    F — 输入,符号表达式,符号函数,符号向量,符号矩阵

    var — 自变量,x(默认)| 符号变量

    自变量,指定为符号变量。此变量通常称为“频率变量”。如果您未指定变量,则 ifourier 使用 w。如果 F 不包含 w,则 ifourier 使用函数 symvar 来确定自变量。

    transVar — 转换变量, x(默认), t | 符号变量 | 符号表达式 | 符号向量 | 符号矩阵

    变换变量,指定为符号变量、表达式、向量或矩阵。它通常被称为“时间变量”或“空间变量”。默认情况下,ifourier 使用 x。如果 x 是 F 的独立变量,则 ifourier 使用 t。

    示例1:矩形函数的逆傅里叶变换(信号处理中的理想低通滤波器)

    矩形函数 rect(w) 的逆傅里叶变换是 sinc(x) 函数
    result4 = ifourier(Piecewise((1, Abs(w) < 1), (0, True)))
    print(result4)
    #sin(x)/(pi*x)

    示例2:狄拉克delta函数的逆傅里叶变换

    δ(w-w0) 的逆傅里叶变换是复指数 e^(iw0x)/(2π)
    result5 = ifourier(DiracDelta(w - 2))
    print(result5)
    #exp(2*I*x)/(2*pi)

    示例3:复指数函数的逆傅里叶变换

    e^(i2w) 的逆傅里叶变换是 δ(x-2)
    result7 = ifourier(exp(I*2*w))
    print(result7)
    #Piecewise((0, (Abs(arg(x + 2) - pi/2) < pi/2) & (Abs(arg(x + 2) + pi/2) < pi/2)),
               (Integral(exp(I*w*(x + 2)), (w, -oo, oo)), True))/(2*pi)

    示例4:符号函数的逆傅里叶变换

    sign(w) 的逆傅里叶变换是 1/(iπx)
    result8 = ifourier(sign(w))
    print(result8)
    #I/(pi*x)

    示例5:阶跃函数的逆傅里叶变换

    u(w) 的逆傅里叶变换包含狄拉克delta和柯西主值
    result9 = ifourier(Heaviside(w))
    print(result9)
    #I/(2*pi*x)

    示例6:矩阵输入的逆傅里叶变换

    matrix_expr = [[exp(-w**2), 1/(1+w**2)], [DiracDelta(w-1), w*exp(-w**2)]]
    result10 = ifourier(matrix_expr)
    print(result10)
    #[[exp(-x**2/4)/(2*sqrt(pi)), exp(-x)/2],
      [exp(I*x)/(2*pi), I*x*exp(-x**2/4)/(4*sqrt(pi))]]

    示例7:带参数的高斯函数

    exp(-a*w^2) 的逆傅里叶变换是高斯函数
    result11 = ifourier(exp(-a*w**2))
    print(result11)
    #exp(-x**2/(4*a))/(2*sqrt(pi)*sqrt(a))

    示例8:洛伦兹分布的逆傅里叶变换

    1/(1+w^2) 的逆傅里叶变换是指数衰减函数
    result12 = ifourier(1/(1+w**2))
    print(result12)
    #exp(-x)/2
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def inverse_fourier_transform(input_str):
        """
        执行逆傅里叶变换,对标MATLAB的ifourier函数

        参数:
        input_str (str): 输入字符串,支持以下格式:
            - 单参数: "F"
            - 双参数: "(F, transVar)"
            - 三参数: "(F, var, transVar)"

        返回:
        sympy.Expr/sympy.Matrix/str: 计算结果或错误信息

        示例:
        >>> inverse_fourier_transform("exp(-w**2)")  # 默认w→x变换
        sqrt(pi)*exp(-x**2/4)/(2*sqrt(pi))

        >>> inverse_fourier_transform("(exp(-s**2), t)")  # 指定转换变量
        sqrt(pi)*exp(-t**2/4)/(2*sqrt(pi))
        """
        try:
            # 预处理输入字符串
            expr = sp.sympify(input_str)
            error = False
            result = None

            def elementwise_ifourier(f_val, var_val=None, transVar_val=None):
                # 确定变量
                if var_val is None:
                    # 查找符号变量,优先使用w,否则取第一个
                    symbols_in_f = f_val.free_symbols
                    if not symbols_in_f:
                        raise ValueError("无符号变量")
                    var_val = sp.symbols('w') if sp.symbols('w') in symbols_in_f else next(iter(symbols_in_f))
                if transVar_val is None:
                    # 转换变量默认为x,如果输入变量是x则用t
                    transVar_val = sp.symbols('x') if var_val != sp.symbols('x') else sp.symbols('t')

                # 按照MATLAB的定义计算逆傅里叶变换: (1/(2π)) ∫ F(ω) e^{iωt} dω
                integral_expr = f_val * sp.exp(sp.I * var_val * transVar_val)
                result = (1 / (2 * sp.pi)) * sp.integrate(integral_expr, (var_val, -sp.oo, sp.oo))
                simplified_result = result.simplify()
                # 如果结果是分段函数,遍历分支找第一个非零项
                if isinstance(simplified_result, sp.Piecewise):
                    for arg in simplified_result.args:  # arg结构: (表达式, 条件)
                        expr, _ = arg
                        simplified_expr = expr.simplify()

                        # 检查表达式是否明确非零(考虑符号计算的不确定性)
                        if simplified_expr.is_zero is not True:  # 允许None(无法判断时默认保留)
                            return simplified_expr

                    # 所有分支都明确为零时返回0
                    return sp.S.Zero
                else:
                    return simplified_result

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

                result = elementwise_ifourier(n, a, x)
            else:
                result = elementwise_ifourier(expr)

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

        except sp.SympifyError:
            return "错误: 输入表达式解析失败"
        except IndexError:
            return "错误: 未找到有效符号变量"
        except Exception as e:
            return f"错误: {str(e)}"


    # 示例测试
    if __name__ == "__main__":
        # 示例1:基本用法 (exp(-w^2) → 高斯函数)
        print("示例1:")
        print(inverse_fourier_transform("exp(-w**2/4)"))
        # exp(-x**2)/sqrt(pi)

        # 示例2:指定转换变量 (s→t)
        print("\n示例2:")
        print(inverse_fourier_transform("(exp(-s**2), t)"))
        # exp(-t**2/4)/(2*sqrt(pi))

        # 示例3:符号表达式保留
        print("\n示例3:")
        print(inverse_fourier_transform("F(w)"))
        # Integral(F(w)*exp(I*w*x), (w, -oo, oo))/(2*pi)
    
    
    逆希尔伯特变换

    f = ihtrans(H) 返回符号函数H的逆希尔伯特变换. 默认情况下, 独立变量为x, 变换变量为t.

    H — 输入, 符号表达式, 符号函数

    示例1:调幅信号的包络提取

    t_vals, H_am = ihtrans((1 + 0.5*cos(2*t)) * cos(10*t))
    plt.figure(figsize=(12, 4))
    plt.subplot(1, 2, 1)
    plt.plot(t_vals, (1 + 0.5*np.cos(2*t_vals)) * np.cos(10*t_vals), 'b-', alpha=0.7, label='AM信号')
    plt.plot(t_vals, 1 + 0.5*np.cos(2*t_vals), 'r--', label='理论包络')
    plt.plot(t_vals, np.abs(H_am), 'g-', label='希尔伯特包络')
    plt.title('AM信号包络检测')
    plt.legend()

    示例2:频率调制信号的瞬时频率提取

    t_vals, H_fm = ihtrans(cos(10*t + 2*sin(0.5*t)))
    instantaneous_phase = np.unwrap(np.angle(signal.hilbert(H_fm)))
    instantaneous_freq = np.diff(instantaneous_phase) / (2*np.pi*(t_vals[1]-t_vals[0]))
    plt.subplot(1, 2, 2)
    plt.plot(t_vals[:-1], instantaneous_freq, 'r-', label='瞬时频率')
    plt.axhline(y=10/(2*np.pi), color='b', linestyle='--', label='载波频率')
    plt.title('FM信号瞬时频率提取')
    plt.legend()
    plt.tight_layout()
    plt.show()

    示例3:地震信号处理 - Ricker子波

    t_vals, H_ricker = ihtrans((1 - 2*(t**2)) * exp(-t**2))
    ricker_wavelet = (1 - 2*(t_vals**2)) * np.exp(-t_vals**2)
    plt.figure(figsize=(10, 4))
    plt.plot(t_vals, ricker_wavelet, 'b-', label='Ricker子波')
    plt.plot(t_vals, H_ricker, 'r--', label='解析信号虚部')
    plt.plot(t_vals, np.sqrt(ricker_wavelet**2 + H_ricker**2), 'g-', label='瞬时振幅')
    plt.title('地震信号Ricker子波的解析表示')
    plt.legend()
    plt.show()

    示例4:通信中的单边带调制

    基带信号
    baseband = np.cos(2*t_vals)

    通过希尔伯特变换实现单边带调制
    t_vals, H_ssb = ihtrans(cos(2*t) * cos(20*t) - sin(2*t) * sin(20*t))
    ssb_signal = baseband * np.cos(20*t_vals) - H_ssb * np.sin(20*t_vals)

    plt.figure(figsize=(10, 4))
    plt.subplot(1, 2, 1)
    plt.plot(t_vals, baseband, 'b-', label='基带信号')
    plt.title('基带信号')
    plt.subplot(1, 2, 2)
    plt.plot(t_vals, ssb_signal, 'r-', label='SSB信号')
    plt.title('单边带调制信号')
    plt.tight_layout()
    plt.show()

    示例5:机械振动分析

    模拟衰减振动信号
    t_vals, H_vib = ihtrans(exp(-0.2*t) * cos(8*t + 0.5*sin(0.5*t)))
    vibration = np.exp(-0.2*t_vals) * np.cos(8*t_vals + 0.5*np.sin(0.5*t_vals))

    plt.figure(figsize=(10, 4))
    plt.plot(t_vals, vibration, 'b-', alpha=0.7, label='振动信号')
    plt.plot(t_vals, np.abs(H_vib), 'r-', label='包络线(衰减趋势)')
    plt.plot(t_vals, -np.abs(H_vib), 'r-')
    plt.title('机械振动信号包络分析')
    plt.legend()
    plt.show()

    示例6:生物医学信号 - ECG分析

    模拟ECG信号
    ecg_signal = (np.exp(-0.5*(t_vals-1)**2/0.1) +
                  0.6*np.exp(-0.5*(t_vals-3)**2/0.05) +
                  0.3*np.exp(-0.5*(t_vals-5)**2/0.08))
    t_vals, H_ecg = ihtrans(exp(-0.5*(t-1)**2/0.1) + 0.6*exp(-0.5*(t-3)**2/0.05) + 0.3*exp(-0.5*(t-5)**2/0.08))

    plt.figure(figsize=(10, 4))
    plt.plot(t_vals, ecg_signal, 'b-', label='模拟ECG信号')
    plt.plot(t_vals, np.abs(H_ecg), 'r--', label='瞬时振幅')
    plt.title('ECG信号的希尔伯特分析')
    plt.legend()
    plt.show()

    示例7:音频信号的基频检测

    合成元音信号(多个谐波)
    vowel = (np.sin(2*np.pi*100*t_vals) + 0.5*np.sin(2*np.pi*200*t_vals) +
             0.3*np.sin(2*np.pi*300*t_vals) + 0.1*np.sin(2*np.pi*400*t_vals))
    t_vals, H_vowel = ihtrans(sin(2*pi*100*t) + 0.5*sin(2*pi*200*t) + 0.3*sin(2*pi*300*t) + 0.1*sin(2*pi*400*t))

    instantaneous_phase_vowel = np.unwrap(np.angle(signal.hilbert(H_vowel)))
    fundamental_freq = np.diff(instantaneous_phase_vowel) / (2*np.pi*(t_vals[1]-t_vals[0]))

    plt.figure(figsize=(12, 4))
    plt.subplot(1, 2, 1)
    plt.plot(t_vals, vowel, 'b-', label='元音信号')
    plt.title('合成元音信号')
    plt.subplot(1, 2, 2)
    plt.plot(t_vals[:-1], fundamental_freq, 'r-', label='基频估计')
    plt.axhline(y=100, color='g', linestyle='--', label='理论基频(100Hz)')
    plt.title('基频检测')
    plt.legend()
    plt.tight_layout()
    plt.show()
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    import scipy.signal as signal
    import matplotlib.pyplot as plt


    def inverse_hilbert_transform(input_str):
        """
        计算给定符号表达式的逆希尔伯特变换,与MATLAB的ihtrans对齐

        参数:
            input_str (str): 输入的时间域符号表达式,变量为t

        返回:
            tuple: (时间数组, 逆希尔伯特变换结果) 或错误信息字符串
        """
        try:
            expr = sp.sympify(input_str)
            t = sp.symbols('t')

            # 检查变量合法性
            if not expr.has(t):
                return "错误: 表达式必须包含变量t"
            if len(expr.free_symbols - {t}) > 0:
                print("警告: 检测到额外符号,已自动替换为1")

            # 符号替换与数值化
            substituted = expr.subs({s: 1 for s in expr.free_symbols - {t}})
            y_func = sp.lambdify(t, substituted, 'numpy')

            # 生成优化时间轴 (避免端点奇点)
            t_vals = np.linspace(-np.pi, 3 * np.pi, 3000)[500:2500]  # 取中间稳定段
            y = y_func(t_vals)

            # 使用镜像延拓处理边界效应
            y_padded = np.concatenate((-y[::-1], y, -y[::-1]))
            analytic = signal.hilbert(y_padded)
            H = -np.imag(analytic)[len(y):2 * len(y)]  # 取中间有效段

            return (t_vals, H)

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


    # 测试案例1: H(sin(t)) = -cos(t) => iH(-cos(t))应得sin(t)
    t, H = inverse_hilbert_transform("-cos(t)")
    plt.figure(figsize=(10, 4))
    plt.plot(t, H, label='数值解')
    plt.plot(t, np.sin(t), 'r--', lw=1, label='理论解')
    plt.title('案例1: iH(-cos(t)) vs sin(t)')
    plt.legend()
    plt.show()

    # 测试案例2: H^{-1}(sin(t)) = cos(t) (验证逆变换特性)
    t, H = inverse_hilbert_transform("sinc(t)")
    plt.figure(figsize=(10, 4))
    plt.plot(t, H, label='数值解')
    plt.plot(t, np.cos(t), 'g--', lw=1, label='理论解')
    plt.title('案例2: iH(sin(t)) vs cos(t)')
    plt.legend()
    plt.show()

    # 精度验证 (检查最大相对误差)
    rel_error = np.max(np.abs(H - np.cos(t))) / np.max(np.abs(np.cos(t)))
    print(f"最大相对误差: {rel_error:.2e}")
    
    
    拉普拉斯函数逆变换

    f=ilaplace(F)返回f的拉普拉斯逆变换. 默认情况下,自变量为s,变换变量为t.如果f不包含s,ilaplace使用函数symvar.

    f=ilaplace(F,transVar)使用转换变量transVar而不是t.

    f=ilaplace(F,var,transVar)分别使用自变量var和变换变量transVar代替s和t.

    F —— 输入,符号表达式,符号函数

    var —— 自变量,s(默认), 符号变量. 自变量, 指定为符号变量,表达式,向量或矩阵. 此变量通常称为“复频率变量”. 如果您未指定变量, 则 ilaplace 使用s 如果 F 不包含 s,则 ilaplace 使用函数 symvar 来确定自变量.

    transVar —— 变换变量,t(默认值),变换变量,指定为符号变量,表达式,向量或矩阵.它通常被称为“时间变量”或“空间变量”.默认情况下, ilaplace使用t. 如果t是F的独立变量, 则ilaplace使用x.

    示例1: 电路分析

    RC电路的阶跃响应
    print("RC电路响应:", ilaplace(1/(s*(R*C*s + 1))))
    #RC电路响应: 1 - exp(-t/(C*R))

    RLC电路的冲击响应
    print("RLC电路:", ilaplace(1/(L*s^2 + R*s + 1/C)))
    #RLC电路: 2*exp(-R*t/(2*L))*sin(t*sqrt((-R**2/L + 4/C)/L)/2)/(L*sqrt((-R**2/L + 4/C)/L))

    示例2: 机械系统

    弹簧-质量-阻尼系统
    print("质量-弹簧系统:", ilaplace(1/(m*s^2 + c*s + k)))
    #质量-弹簧系统: 2*exp(-c*t/(2*m))*sin(t*sqrt((-c**2 + 4*k*m)/m**2)/2)/(m*sqrt((-c**2 + 4*k*m)/m**2))

    简谐振动
    print("简谐振动:", ilaplace(s/(s^2 + omega^2)))
    #简谐振动: cos(omega*t)

    示例3: 控制系统

    一阶系统响应
    print("一阶系统:", ilaplace(K/(tau*s + 1)))
    #一阶系统: K*exp(-t/tau)/tau

    PID控制器输出
    print("PID控制:", ilaplace("Kp + Ki/s + Kd*s"))
    #PID控制: Ki

    示例4: 热传导

    热传导方程的解
    print("热传导:", ilaplace(exp(-x*sqrt(s/alpha))/s))
    #热传导: InverseLaplaceTransform(exp(-x*sqrt(s/alpha))/s, s, t, _None)

    示例5: 信号处理

    低通滤波器
    print("低通滤波:", ilaplace(omega_c/(s + omega_c)))
    #低通滤波: omega_c*exp(-omega_c*t)

    延迟系统
    print("时间延迟:", ilaplace("exp(-tau*s)/s"))
    #时间延迟: InverseLaplaceTransform(exp(-s*tau)/s, s, t, _None)

    示例6: 复杂函数变换

    带有复极点的系统
    print("复极点系统:", ilaplace(1/((s+a)^2 + b^2)))
    #复极点系统: exp(-a*t)*sin(t*sqrt(b**2))/sqrt(b**2)

    重极点情况
    print("重极点:", ilaplace("1/(s+a)^3"))
    #重极点: t**2*exp(-a*t)/2

    示例7: 特殊函数

    贝塞尔函数相关
    print("贝塞尔相关:", ilaplace(1/sqrt(s^2 + 1)))
    #贝塞尔相关: besselj(0, t)

    误差函数相关
    print("误差函数:", ilaplace(1/sqrt(s)))
    #误差函数: 1/(sqrt(pi)*sqrt(t))

    示例8: 矩阵变换

    状态空间系统的逆变换
    matrix_expr = [[1/(s+1), 1/(s+2)], [1/s, 1/(s-1)]]
    result = ilaplace(matrix_expr)
    print("矩阵系统:")
    print(result)
    #矩阵系统:
    #[[exp(-t), exp(-2*t)],
      [1, exp(t)]]

    示例9: 电机速度控制

    print("直流电机模型:", ilaplace(K/((J*s + b)*(L*s + R) + K^2)))
    #直流电机模型:
    #2*K*exp(-t*(J*R + L*b)/(2*J*L))*sin(t*sqrt(-R**2/L**2 + 4*K**2/(J*L) + 2*R*b/(J*L) - b**2/J**2)/2)/(J*L*sqrt(-R**2/L**2 + 4*K**2/(J*L) + 2*R*b/(J*L) - b**2/J**2))

    示例10: 化学浓度控制

    print("反应器浓度:", ilaplace(C0/(s + k)))
    #反应器浓度: C0*exp(-k*t)

    示例11: 经济学模型

    print("经济增长:", ilaplace(1/(s - r)))
    #经济增长: exp(r*t)
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def inverse_laplace_transform(input_str):
        """
        对标 MATLAB 的 ilaplace 函数,实现逆拉普拉斯变换

        参数:
        input_str: 输入参数字符串,支持以下格式:
                   "F"                -> 自动识别变量
                   "F, s"            -> 指定原域变量
                   "F, s, t"          -> 指定原域变量和时域变量
                   "F, t"             -> 直接使用时域变量

        返回:
         逆变换结果,形式与输入一致(标量、矩阵或符号表达式)。错误时返回错误信息

        示例:
        >>> inverse_laplace_transform("1/s")
        Heaviside(t)
        >>> inverse_laplace_transform("1/(s^2 + a^2), s, t")
        sin(a*t)*Heaviside(t)/a
        """
        try:
            # 将输入字符串转换为 sympy 表达式
            expr = sp.sympify(input_str)
            # 初始化错误标志
            error = False
            # 初始化结果变量
            result = None

            def eval_inverse_laplace(f_val, var_val=None, transVar_val=None):
                """
                计算逆拉普拉斯变换的辅助函数

                参数:
                f_val: 待变换的表达式
                var_val: 原域变量,默认为 None
                transVar_val: 时域变量,默认为 None

                返回:
                逆拉普拉斯变换的结果
                """
                # 定义默认的原域变量 s
                s = sp.symbols('s')
                # 如果 var_val 未提供
                if var_val is None:
                    # 若表达式中包含 s,则使用 s 作为原域变量,否则使用表达式中的第一个自由符号
                    var_val = s if f_val.has(s) else tuple(f_val.free_symbols)[0]

                # 如果 transVar_val 未提供
                if transVar_val is None:
                    # 如果原域变量不是 t,则使用 t 作为时域变量,否则使用 x
                    default_symbol = 't' if var_val != sp.symbols('t') else 'x'
                    # 创建正实数的时域变量
                    transVar_val = sp.symbols(default_symbol, positive=True)
                else:
                    # 将输入的时域变量转换为正实数的符号
                    transVar_val = sp.Symbol(str(transVar_val), positive=True)

                # 调用 sympy 的逆拉普拉斯变换函数进行计算
                return sp.inverse_laplace_transform(f_val, var_val, transVar_val)

            # 如果输入表达式是元组
            if isinstance(expr, tuple):
                if len(expr) == 3:
                    # 分别提取表达式、原域变量和时域变量
                    n = expr[0]
                    a = expr[1]
                    x = expr[2]
                elif len(expr) == 2:
                    # 提取表达式和时域变量,原域变量设为 None
                    n = expr[0]
                    a = None
                    x = expr[1]
                else:
                    # 输入格式错误,设置错误标志
                    error = True

                # 逆拉普拉斯变换
                result = eval_inverse_laplace(n, a, x)

            # 如果输入表达式是数字或者包含自由符号
            elif expr.is_number or expr.free_symbols:
                # 直接进行逆拉普拉斯变换
                result = eval_inverse_laplace(expr)
            else:
                # 输入格式错误,设置错误标志
                error = True

            # 如果没有错误,返回结果,否则返回错误信息
            return result if not error else f"输入错误: {input_str}"

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


    # 示例测试
    if __name__ == "__main__":
        # 标量测试
        print(inverse_laplace_transform("1/s"))
        # 1

        print(inverse_laplace_transform("exp(-a*s)/s"))
        # InverseLaplaceTransform(exp(-a*s)/s, s, t, _None)

        print(inverse_laplace_transform("1/(s-a)**2, x"))
        # x*exp(a*x)
    
    
    热图

    ImagescPlot(C, coloroption)将阵列C中的数据显示为使用颜色图中的全部颜色范围的图像.C的每个元素指定图像的一个像素的颜色.所得到的图像是像素的m×n网格,其中m是C中的行数,n是列数.元素的行和列索引确定相应像素的中心.

    C - 数值矩阵

    coloroption:

    内置默认序列:

        'viridis'(默认)、'plasma'、'inferno'、'magma'、'cividis'(这些是基于科学可视化的优化配色)
        'Greys'、'YlGnBu'、'Greens'、'YlOrRd'、'Bluered'、'RdBu' 等(经典渐变色)

    分类配色:

        单色系:'Greys'、'Reds'、'Blues'、'Oranges' 等(名称均为复数形式)
        双色对比:'RdBu'(红 - 蓝)、'PuOr'(紫 - 橙)、'BrBG'(棕 - 蓝绿)等

    温度分布图(气象学):

    红色区域为高温区(沙漠),黄色区域为低温区(沿海)

    ImagescPlot([[22,24,26,28],  # 沿海区域
                 [28,30,32,34],  # 平原区域
                 [35,37,38,40]], # 内陆沙漠
                 YlOrRd)

    基因表达热图(生物信息学):

    高表达基因呈黄色(如基因B在样本3),低表达呈紫色

    ImagescPlot([[0.1,1.2,0.5],   # 基因A
                 [2.8,0.3,4.1],   # 基因B
                 [1.5,3.0,0.7]],  # 基因C
                 viridis)

    用户行为分析(网页点击热图):

    深蓝色块为高点击区域(主内容区左侧)

    ImagescPlot([[5,20,3],    # 顶部导航栏
                 [50,2,10],   # 主内容区
                 [1,4,30]],   # 侧边广告
                 Blues)

    金融相关性矩阵(量化分析):

    红色表示正相关(A与B),蓝色表示负相关(A与C)

    ImagescPlot([[1.0,0.7,-0.2],   # 股票A
                 [0.7,1.0,0.1],    # 股票B
                 [-0.2,0.1,1.0]],  # 股票C
                 RdBu)
    
    二维隐式函数图

    ImplicitPlot(f(x,y)) 绘制由隐式方程(即未解出因变量的方程)定义的函数关系的图像, 隐式函数图 必须包含两个变量,因为描述二维平面中的曲线, 展示变量间的相互约束, 实际系统常涉及多变量交互.

    天体轨道(开普勒定律): 航天器轨道计算、深空探测路径规划

    ImplicitPlot(x^2/4+y^2=1,x=[-15,15],y=[-15,15])

    电磁场分布(麦克斯韦方程): 两个同号点电荷的等势线分布, 高压输电线周围的电场强度梯度

    ImplicitPlot(x^2-y^2=1,x=[-@pi,@pi],y=[-@pi,@pi])

    医学成像(CT重建): 描述人体器官的断层扫描轮廓, 肿瘤边缘检测(灰度突变边界)

    ImplicitPlot(x^2+y^2-exp(-(x^2+y^2))=0,x=[-3,3],y=[-3,3])

    化学反应平衡: 氨合成反应

    ImplicitPlot((x^2)*y=0.5,x=[0,1], y=[0,2])

    声波干涉: 噪声消除耳机中的反相声波叠加, 音乐会厅声学设计

    ImplicitPlot(cos(x)+cos(y)=0,x=[-2@pi,2@pi], y=[-2@pi,2@pi])

    神经网络决策边界: 猫狗分类示例

    ImplicitPlot(1/(1+exp(-(0.8x-0.5y+0.1)))= 0.5,x=[-5,5], y=[-5,5])

    流体力学(伯努利方程): 机翼表面压力分布

    ImplicitPlot(0.5*1.225*x^2+P=101350,x=[0,300], P=[80000,120000])

    生态学种群竞争:

    参数赋值(澳洲野猫(y) vs 袋鼠(x)):

    a=0.3(野猫捕食强度系数)

    ImplicitPlot(x*(1-x-0.3y)=0,x=[0,2],y=[0,4])
    
    三维隐式函数图

    ImplicitPlot(f(x,y,z)) 表示的是一个由方程 F(x, y, z) = 0 定义的曲面(或点集)。

    它不像显式函数 z = f(x, y) 那样直接解出 z,而是通过检查空间中每个点 (x, y, z) 是否满足方程来确定该点是否在曲面上。

    这种表示方法非常强大,可以描述极其复杂的拓扑结构和光滑曲面,尤其是在几何建模、科学计算可视化(如等值面)、物理(如势能面)和数学研究中应用广泛。

    球体 (最基础): 最基本的等距曲面。

    表示天体(理想化)、粒子模型、约束条件(如分子动力学中的范德华半径约束的简化)、各向同性场(如点电荷的等势面)。

    ImplicitPlot3D(x^2+y^2+z^2-1=0,x=[-1.5,1.5],y=[-1.5,1.5],z=[-1.5,1.5])

    圆柱面: 表示无限长圆柱体的一部分。

    应用:管道、杆件、轴、激光束的理想化模型、旋转对称结构。

    ImplicitPlot3D(x^2+y^2-0.64=0,x=[-2,2],y=[-2,2],z=[-2,2])

    环面 (甜甜圈): 拓扑学基本曲面(亏格1)。

    应用:轮胎、环形线圈(电感器、托卡马克核聚变装置)、环形分子结构、DNA环、某些建筑结构。

    ImplicitPlot3D((x^2+y^2+z^2+0.91)^2-4(x^2+y^2),x=[-1.5,1.5],y=[-1.5,1.5],z=[-0.5,0.5])

    圆锥面: 表示锥形结构。

    应用:喇叭口、光线锥(几何光学)、某些结晶习性、应力集中区域(断裂力学)、声波或冲击波传播的理想化模型(特征线)。

    ImplicitPlot3D(x^1+y^2-z^2,x=[-1,1],y=[-1,1],z=[-1,1])

    双曲面 (单叶): 具有负高斯曲率的直纹曲面。

    应用:冷却塔(经典的双曲面结构,强度高且自然通风效果好)、核反应堆安全壳、某些现代建筑、齿轮几何、天体轨道(双曲线轨道是平面上的双曲线,但双曲面是其空间推广)。

    ImplicitPlot3D(x^1+y^2-z^2-0.25=0,x=[-2,2],y=[-2,2],z=[-2,2])

    Goursat 曲面 (复杂拓扑): 一类高亏格的代数曲面(亏格>1)。

    应用:复杂的拓扑结构研究、几何建模中的复杂形状原型、数学可视化(展示高亏格曲面)、某些多孔材料或泡沫的理想化模型。

    ImplicitPlot3D(x^4+y^4+z^4-(x^2*y^2+y^2*z^2+z^2*x^2)+0.1=0,x=[-1.5,1.5],y=[-1.5,1.5],z=[-1.5,1.5])

    球形变形: 高次曲面

    ImplicitPlot3D(x^4+y^4+z^4-x^2-y^2-z^2+0.3=0,x=[-2,2],y=[-2,2],z=[-2,2])
    
    脉冲响应图

    impulseplot(sys)描述了一个线性时不变系统(LTI)在输入为单位脉冲信号(Dirac Delta 函数)时的输出响应。

    它直观展示了系统的动态特性(如稳定性、振荡频率、衰减速度等)。数学上,它是传递函数 H(s)H(s) 的拉普拉斯逆变换。

        电路系统(RLC 电路): 二阶低通滤波器

        衰减振荡(因复数极点 -1±2j)。

        电容电压在瞬时电流脉冲下的响应,振荡频率 2 rad/s,衰减率由实部 -1 决定。

        impulseplot(1,s^2+2s+5)

        机械系统(悬架减震): 车辆悬架模型

        初始快速上升(分子零点影响),后衰减振荡。

        车轮受瞬时冲击(如过路障)时车身的位移响应,振荡频率反映系统固有特性。

        impulseplot(0.5s+1,s^2+1.2s+4)

        控制系统(无人机姿态调整): 俯仰角控制器

        快速上升至峰值,后衰减振荡至 0。

        无人机受瞬时阵风扰动后的俯仰角恢复过程,超调量和调整时间反映控制器性能。

        impulseplot(10*(s+0.5),s^2+3s+10)

        地震工程(建筑结构抗震): 3层建筑简化模型

        初期剧烈振荡 → 结构受冲击时的晃动

        后期指数衰减 → 阻尼材料消耗能量

        模拟地震瞬间(脉冲输入)后各楼层的位移响应,衰减速度反映结构耗能能力。

        impulseplot(0.02s+0.1,s^2+0.8s+4)

        金融系统(市场冲击分析): 股票指数对突发事件的响应

        初始骤降 → 恐慌性抛售(如黑天鹅事件)

        振荡恢复 → 市场自我修正过程

        稳态归零 → 冲击被完全消化

        2020年疫情爆发时美股熔断的脉冲响应拟合。

        impulseplot(0.3s-2,s^2+1.5s+0.8)

        机器人学(机械臂关节控制): 谐波减速器关节

        初始超调(20%)→ 关节柔性导致的过冲

        高频衰减振荡(8Hz)→ 结构共振频率

        2秒内收敛 → 控制系统带宽足够

        通过调整响应曲线降低超调,避免精密操作时抖动。

        impulseplot(8s+16,s^2+4s+64)

        神经科学(神经元电信号传导)

        1ms内产生尖峰 → 动作电位激发

        负向波动 → 钾离子外流导致的超极化

        长尾衰减(10ms)→ 不应期恢复过程

        解释癫痫患者为何对连续刺激更敏感(脉冲响应叠加效应)。

        impulseplot(100,s^2+20s+100)

        低通滤波器(平滑噪声)

        响应呈5个等高的矩形脉冲(长度=5),表明系统对输入进行短期平均,快速衰减高频噪声。

        温度传感器数据去噪,消除瞬时干扰。

        impulseplot([1],[0.2,0.2,0.2,0.2,0.2])

        弹簧-阻尼系统(机械振动)

        响应呈衰减振荡(如 [1.0, 1.2, 0.64, -0.128, ...]),振幅逐渐减小。

        分析悬架对路面冲击的减震效果,振荡频率和衰减速率决定舒适性。

        impulseplot([1],[1,-1.2,0.8])

        经济预测模型(时间序列分析)

        指数衰减序列(如 [0.6, 0.48, 0.384, ...]),反映冲击的持久影响。

        评估经济政策冲击的持续时间(如加息对通胀的影响)。

        impulseplot([0.6],[1,-0.8])

        数字通信系统(码间干扰分析)

        主峰两侧有对称拖尾(如 [0.4, 1.0, 0.4]),主峰后出现非零值。

        设计均衡器消除码间干扰(ISI),提升数据传输可靠性。

        impulseplot([1],[0.4,1.0,0.4])

        生态模型(种群动态)

        振荡持续但缓慢衰减(如初始响应 [1, 0.8, 0.46, ...])。

        预测物种数量对突发事件的恢复能力(如疾病或食物短缺)。

        impulseplot([1,0.3],[1,-0.5,-0.2])

    叠加脉冲响应图

    impulseplot([sys1],[sys2]...[sysN])

    叠加脉冲响应图是在同一坐标系中绘制多个系统的脉冲响应曲线,用于直观比较不同系统的动态特性(如响应速度、稳定性、振荡行为等)。

        悬架系统设计对比

        H1:单调上升后平缓衰减 → 基础减震效果

        H2:初始快速响应(0.2s达峰)→ 主动控制优势

        H2使豪华SUV过减速带的冲击加速度降低45%

        impulseplot([2.5s+8,s^2+1.8s+16],    #  系统1: 传统弹簧减震器
                    [3.2s^2+12s+40,s^3+4.5s^2+22s+60])  #  系统2: 磁流变智能悬架

        医疗输液泵控制算法

        H1超调量≈0%(阶跃响应验证)→ 适合化疗药物输送

        H2上升时间快40% → 急救时快速补液

        H2在休克抢救中使血压达标时间缩短至1.8分钟

        impulseplot([12,s^2+4s+12],      # 系统1: PID控制器
                    [8s+30,s^2+2.5s+25]) # 系统2: 模糊自适应控制器

        无人机抗风性能

        H2在6级风中姿态稳定性提升至H1的2.3倍

        impulseplot([15*(s+2),s^2+5s+50],   #  系统1: 标准PID控制器
                    [25*(s+3),s^2+8s+100])  #  系统2: 神经网络补偿控制器

        声学降噪耳机

        H1:单纯指数衰减 → 物理隔音

        H2:初始负向响应 → 主动声波抵消

        impulseplot([10,s+15],   #  系统1: 被动降噪
                    [-6s-50,s^2+20s+400])  #  系统2: 主动降噪

    
    定积分和不定积分

    F=int(expr)计算expr的不定积分. int使用由symvar(expr,1)确定的默认积分变量.如果expr是一个常数,那么默认的积分变量是x.

    F=int(expr,var)计算expr相对于符号标量变量var的不定积分.

    F=int(expr,a,b)计算expr从a到b的定积分.int使用由symvar(expr,1)确定的默认积分变量.如果expr是一个常数,那么默认的积分变量是x.

    F=int(expr,var,a,b)计算expr相对于符号标量变量var从a到b的定积分.

    expr — 整数,符号表达式,符号函数,符号向量,符号矩阵,符号数

    var — 积分变量,符号变量

    a —— 下限,数字,符号数,符号变量,符号表达式,符号函数

    b —— 上限,数字,符号数,符号变量,符号表达式,符号函数

    示例1: 力学中的积分

    计算物体运动的位移(速度积分)
    print("匀速运动位移:", int(v, t, 0, T))
    #匀速运动位移: T*v

    print("匀加速运动位移:", int(v0 + a*t, t, 0, T))
    #匀加速运动位移: T*(T*a + 2*v0)/2

    计算变力做功
    print("弹簧做功:", int(k*x, x, 0, X))
    #弹簧做功: X**2*k/2

    print("重力做功:", int(m*g, h, 0, H))
    #重力做功: H*g*m

    示例2: 电路分析

    计算电容电荷量
    print("电容电荷:", int(i, t, 0, T))
    #电容电荷: T*i

    print("RC电路响应:", int(I0*exp(-t/(R*C)), t, 0, T))
    #RC电路响应: C*I0*R - C*I0*R*exp(-T/(C*R))

    计算交流电路功率
    print("正弦波功率:", int(V0*I0*sin(omega*t)**2, t, 0, 2*pi/omega))
    #正弦波功率: Piecewise((pi*I0*V0/omega, ((omega > -oo) | (omega > 0)) & ((omega > -oo) | (omega < oo)) & ((omega > 0) | (omega < 0)) & ((omega < 0) | (omega < oo))), (0, True))

    示例3: 经济分析

    计算总收益(边际收益积分)
    print("总收益函数:", int(a - b*x, x))
    #总收益函数: x*(2*a - b*x)/2

    计算消费者剩余
    print("消费者剩余:", int((P0 - (a - b*x)), x, 0, Q0))
    #消费者剩余: Q0*(P0 + Q0*b/2 - a)

    计算资本积累
    print("资本积累:", int(I0*exp(r*t), t, 0, T))
    #资本积累: Piecewise((I0*(exp(T*r) - 1)/r, ((r > -oo) | (r > 0)) & ((r > -oo) | (r < oo)) & ((r > 0) | (r < 0)) & ((r < 0) | (r < oo))), (I0*T, True))

    示例4: 面积和体积计算

    计算曲线下面积
    print("抛物线面积:", int(x**2, x, 0, 1))
    #抛物线面积: 1/3

    计算旋转体体积
    print("旋转体体积:", int(pi*(f(x))**2, x, a, b))
    #旋转体体积: pi*Integral(f(x)**2, (x, a, b))

    示例5: 概率密度函数

    正态分布的归一化验证
    print("正态分布积分:", int(exp(-x**2/2)/sqrt(2*pi), x, -oo, oo))
    #正态分布积分: 1

    示例6: 热力学过程

    计算理想气体做功
    print("等温膨胀功:", int(P, V, V1, V2))
    #等温膨胀功: P*(-V1 + V2)

    print("多方过程功:", int(C/V**n, V, V1, V2))
    #多方过程功: Piecewise((C*(V1**(1 - n) - V2**(1 - n))/(n - 1), ((n > -oo) | (n > 1)) & ((n > -oo) | (n < oo)) & ((n > 1) | (n < 1)) & ((n < 1) | (n < oo))),
                         (C*(-log(V1) + log(V2)), True))

    计算熵变
    print("熵变计算:", int(C/T, T, T1, T2))
    #熵变计算: C*(-log(T1) + log(T2))

    示例7: 矩阵积分应用

    应力-应变关系
    print("应力张量积分:", int([[sigma_xx, sigma_xy], [sigma_yx, sigma_yy]]))
    #应力张量积分:
    #[[sigma_xx**2/2, sigma_xy**2/2],
      [sigma_yx**2/2, sigma_yy**2/2]]

    多变量系统
    multivariable_system = [[x*y, x**2], [y**2, x+y]]
    result = int(multivariable_system)
    print("多变量系统积分:")
    print(result)
    #多变量系统积分:
    #[[x**2*y/2, x**3/3],
      [y**3/3, x*(x + 2*y)/2]]

    示例8: 高级应用

    傅里叶分析
    print("傅里叶系数:", int(f(x)*cos(n*pi*x/L), x, -L, L))
    #傅里叶系数: Integral(f(x)*cos(pi*n*x/L), (x, -L, L))

    微分方程求解
    print("微分方程解:", int(exp(-k*x)*g(x), x))
    #微分方程解: Integral(g(x)*exp(-k*x), x)

    路径积分
    print("线积分:", int(F_x(x,y) + F_y(x,y), x))
    #线积分: Integral(F_x(x, y) + F_y(x, y), x)
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def integrate_equation(input_str):
        """
        对标MATLAB int函数,支持定积分、不定积分和矩阵积分

        参数:
            input_str: 字符串形式的数学表达式,支持以下格式:
                - 不定积分: "x**2", "sin(y)"
                - 定积分: "(x**2, x, 0, 1)", "(f, (x, a, b))"
                - 矩阵积分: "[[x, x**2], [sin(x), cos(x)]]"

        返回:
            SymPy表达式或矩阵,若出错返回错误信息字符串
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            def element_integrate(ele):
                if ele.free_symbols:
                    sym_var = tuple(ele.free_symbols)[0]  # 注意:可能因符号顺序导致问题
                    return sp.integrate(ele, sym_var).doit()
                elif ele.is_number:
                    sym_var = sp.symbols('x')
                    return sp.integrate(ele, sym_var).doit()
                else:
                    return sp.nan

            # 处理四元组定积分形式 (被积函数, 积分变量, 下限, 上限)
            if isinstance(expr, tuple) and len(expr) == 4:
                if expr[0].free_symbols and expr[1].free_symbols:  # 标量积分
                    result = sp.integrate(expr[0], (expr[1], expr[2], expr[3])).doit()
                else:
                    error = True

            # 处理三元组形式 (被积函数, 下限, 上限) 自动提取积分变量
            elif isinstance(expr, tuple) and len(expr) == 3:
                sym_var = tuple(expr[0].free_symbols)[0]  # 提取第一个符号作为积分变量
                if expr[0].free_symbols:  # 标量积分
                    result = sp.integrate(expr[0], (sym_var, expr[1], expr[2])).doit()
                else:
                    error = True

            # 处理二元组形式 (被积函数, 积分变量) 不定积分
            elif isinstance(expr, tuple) and len(expr) == 2:
                if all(e.free_symbols for e in expr):
                    result = sp.integrate(*expr).doit()
                else:
                    error = True

            # 处理单个表达式不定积分(自动提取变量)
            elif expr.free_symbols or expr.is_number:
                result = element_integrate(expr)
            else:
                error = True

            return sp.simplify(result) if not error else f"输入错误: {input_str}"
        except Exception as e:
            return f"错误:{e}"


    # 示范代码
    if __name__ == "__main__":
        # 示例1: 不定积分
        print("--- 不定积分示例 ---")
        print("∫x² dx =", integrate_equation("x**2"))
        # x**3/3

        # 示例2: 定积分 (显式指定变量)
        print("\n--- 定积分示例(四元组形式)---")
        print("∫₀¹ x² dx =", integrate_equation("(x**2, x, 0, 1)"))
        # 1/3

        # 示例3: 定积分 (自动提取变量)
        print("\n--- 定积分示例(三元组形式)---")
        print("∫₀^π sin(x) dx =", integrate_equation("(sin(x), 0, pi)"))
        # 2
    
    
    数值积分

    q = integral(fun,xmin,xmax) 使用全局自适应积分和默认误差容限在 xmin 至 xmax 间以数值形式为函数 fun 求积分.

    fun — 被积函数,函数句柄

    xmin — x 的下限,实数,复数

    xmax — x 的上限,实数,复数

    示例1: 力学中的数值积分

    计算非匀变速运动的位移
    print("变加速运动位移:", integral(5*t + 2*t**2, t, 0, 10))
    #变加速运动位移: 916.666666666667

    计算空气阻力下的抛射体运动
    print("空气阻力功:", integral(0.1*v**2, v, 0, 20))
    #空气阻力功: 266.666666666667

    计算弹簧非线性系统的能量
    print("非线性弹簧能量:", integral(2*x + 0.5*x**3, x, 0, 5))
    #非线性弹簧能量: 103.125000000000

    示例2: 电路数值分析

    计算交流电路的有效值
    print("正弦波有效值:", integral(sin(2*pi*50*t)**2, t, 0, 0.02))
    #正弦波有效值: 0.01

    计算非线性元件的能量损耗
    print("非线性电阻能耗:", integral(0.1*i + 0.05*i**3, i, 0, 10))
    #非线性电阻能耗: 130.0

    计算瞬态响应积分
    print("RC瞬态响应:", integral(exp(-t/0.001), t, 0, 0.01))
    #RC瞬态响应: 0.000999954600070238

    示例3: 经济数值分析

    计算连续复利的现值
    print("连续复利现值:", integral(1000*exp(-0.05*t), t, 0, 10))
    #连续复利现值: 7869.38680574733

    计算需求曲线下的消费者剩余
    print("消费者剩余:", integral((50 - 2*x) - 10, x, 0, 15))
    #消费者剩余: 375.0

    计算经济增长的累积效应
    print("经济增长累积:", integral(100*exp(0.03*t), t, 0, 20))
    #经济增长累积: 2740.39600130170

    示例4: 概率密度数值积分

    正态分布概率计算
    print("正态分布[0,1]概率:", integral(exp(-x**2/2)/sqrt(2*pi), x, 0, 1))
    #正态分布[0,1]概率: 0.341344746068543

    指数分布期望值
    print("指数分布期望:", integral(x*0.5*exp(-0.5*x), x, 0, 100))
    #指数分布期望: 2.0

    计算分布的方差
    print("均匀分布方差:", integral((x-0.5)**2, x, 0, 1))
    #均匀分布方差: 0.0833333333333333

    示例5: 工程数值计算

    计算梁的弯矩分布
    print("梁的弯矩:", integral(10*x - 5*x**2, x, 0, 2))
    #梁的弯矩: 6.66666666666667

    计算流体力学中的流量
    print("管道流量:", integral(2*pi*x*(1 - (x/0.5)**2), x, 0, 0.5))
    #管道流量: 0.392699081698724

    计算热传导能量
    print("热传导能量:", integral(100*exp(-0.1*x), x, 0, 10))
    #热传导能量: 632.120558828558

    示例6: 信号处理应用

    计算信号能量
    print("正弦信号能量:", integral(sin(2*pi*1000*t)**2, t, 0, 0.001))
    #正弦信号能量: 0.0005

    计算滤波器响应
    print("低通滤波器响应:", integral(exp(-t/0.001)*sin(2*pi*1000*t), t, 0, 0.01))
    #低通滤波器响应: 0.000155216049016986

    计算自相关函数
    print("自相关积分:", integral(sin(t)*sin(t+0.1), t, 0, 2*pi))
    #自相关积分: 3.12589777592869

    示例7: 复杂函数数值积分

    振荡函数的积分
    print("振荡函数积分:", integral(sin(10*x)/(1+x**2), x, 0, 5))
    #振荡函数积分: 0.0986904887813441

    奇异函数的积分
    print("带奇点积分:", integral(1/sqrt(x), x, 0.0001, 1))
    #带奇点积分: 1.98

    快速振荡函数
    print("快速振荡:", integral(cos(100*x)*exp(-x), x, 0, 10))
    #快速振荡: 0.000100362813252240

    示例8: 药物在体内的浓度-时间曲线下面积(AUC)

    print("药物AUC:", integral(100*exp(-0.2*t), t, 0, 24))
    #药物AUC: 495.885126475490

    示例9: 环境科学中的污染物总量

    print("污染物总量:", integral(50*exp(-0.05*t), t, 0, 100))
    #污染物总量: 993.262053000915

    示例10: 金融中的期权定价

    print("期权期望收益:", integral(max(x-100, 0)*exp(-x**2/2)/sqrt(2*pi), x, 80, 120))
    #期权期望收益: 7.06080568821696e-2511
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp

    def integrate_numerical_equation(input_str):
        """
        对标MATLAB的integral函数,进行数值积分计算

        参数:
            input_str: 输入的字符串,表示积分表达式和积分区间

        返回:
            积分结果 或 错误信息
        """
        try:
            # 将输入的字符串转换为SymPy表达式
            expr = sp.sympify(input_str)
            error = False
            result = None

            # 处理输入为元组且长度为3的情况,例如 (x**2, 0, 1)
            if isinstance(expr, tuple) and len(expr) == 3:
                # 找到被积函数中的自由符号作为积分变量
                x = list(expr[0].free_symbols)[0]
                # 构建积分表达式并计算数值积分
                result = sp.Integral(expr[0], (x, expr[1], expr[2])).evalf()
            # 处理输入为元组且长度大于3的情况,例如 (x**2, x, 0, 1)
            elif isinstance(expr, tuple) and len(expr) > 3:
                # 构建积分表达式并计算数值积分
                result = sp.Integral(expr[0], (expr[1], expr[2], expr[3])).evalf()
            else:
                # 若输入格式不符合要求,标记为错误
                error = True

            # 如果没有错误,返回积分结果;否则返回错误信息
            return result if not error else f"输入错误: {input_str}"

        except Exception as e:
            # 若计算过程中出现错误,返回错误信息
            return f"错误:{e}"


    # 示范代码
    # 示例1:计算 x**2 在 [0, 1] 上的积分
    input_str1 = "(x**2, 0, 1)"
    result1 = integrate_numerical_equation(input_str1)
    print(f"示例1结果: {result1}")
    # 0.333333333333333
    
    
    对二重积分进行数值计算

    q = integral2(fun,xmin,xmax,ymin,ymax) 在平面区域 xmin ≤ x ≤ xmax 和 ymin(x) ≤ y ≤ ymax(x) 上逼近函数 z = fun(x,y) 的积分

    q = integral2(fun,xmin,xmax,ymin,ymax,Name,Value) 使用一个或多个 Name,Value 对组参量指定其他选项

    fun — 被积函数,函数句柄

    xmin — x 的下限,实数,复数

    xmax — x 的上限,实数,复数

    ymin — y 的下限,实数,复数

    ymax — y 的上限,实数,复数

    示例1: 矩形区域上的二重积分 - 计算薄板质量

    假设密度函数为 ρ(x,y) = x² + y²,在矩形区域 [0,1]×[0,2] 上

    print("密度函数: ρ(x,y) = x² + y², 区域: [0,1]×[0,2]")
    result, error = integral2(x^2 + y^2, 0, 1, 0, 2)
    print(f"薄板质量: {result:.6f}, 误差估计: {error:.2e}")
    #密度函数: ρ(x,y) = x² + y², 区域: [0,1]×[0,2]
    #薄板质量: 3.333333, 误差估计: 5.17e-14

    示例2: 非矩形区域 - 计算扇形区域面积

    积分区域: x从0到1, y从0到sqrt(1-x²) (单位圆的第一象限)

    result, error = integral2(1, 0, 1, 0, sqrt(1-x^2))
    print(f"单位圆第一象限面积: {result:.6f}, 误差估计: {error:.2e}")
    #单位圆第一象限面积: 0.785398, 误差估计: 8.83e-11

    示例3: 概率计算 - 二维正态分布的联合概率

    在区域 [0,1]×[0,1] 上计算 exp(-(x²+y²)/2) 的积分

    result, error = integral2(exp(-(x**2 + y**2)/2), 0, 1, 0, 1)
    print(f"联合概率密度积分: {result:.6f}, 误差估计: {error:.2e}")
    #联合概率密度积分: 0.732093, 误差估计: 9.50e-15

    示例4: 物理学应用 - 计算转动惯量

    对于矩形薄板 [0,a]×[0,b],绕z轴的转动惯量 ∫∫(x²+y²)ρ dxdy

    result, error = integral2(x**2 + y**2, 0, 2, 0, 1)
    print(f"转动惯量: {result:.6f}, 误差估计: {error:.2e}")
    #转动惯量: 3.333333, 误差估计: 4.79e-14

    示例5: 工程应用 - 计算弯曲力矩

    载荷分布函数 p(x,y) = x*y,在三角形区域上积分

    result, error = integral2(x*y, 0, 1, 0, 1-x)
    print(f"总弯曲力矩: {result:.6f}, 误差估计: {error:.2e}")
    #总弯曲力矩: 0.041667, 误差估计: 8.20e-16

    示例6: 经济学应用 - 计算总收益

    需求函数 D(x,y) = 100 - x - y,在价格区域上积分

    result, error = integral2(100 - x - y, 0, 50, 0, 50)
    print(f"潜在总收益: {result:.6f}, 误差估计: {error:.2e}\n")
    #潜在总收益: 125000.000000, 误差估计: 1.39e-09
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    from scipy.integrate import dblquad, nquad
    import sympy as sp


    def integral2(integrand, x_low, x_high, y_low, y_high, **kwargs):
        """
        对标MATLAB integral2函数的二重数值积分实现

        参数:
        integrand: 被积函数,接受两个参数f(x,y)
        x_low, x_high: x的积分下限和上限(可以是常数或函数)
        y_low, y_high: y的积分下限和上限(可以是常数或函数,y_low和y_high可以是x的函数)
        **kwargs: 传递给scipy积分函数的参数

        返回:
        积分结果和误差估计
        """
        try:
            # 处理积分限为函数的情况
            if callable(x_low):
                x_low_func = x_low
            else:
                x_low_func = lambda x, y: x_low

            if callable(x_high):
                x_high_func = x_high
            else:
                x_high_func = lambda x, y: x_high

            if callable(y_low):
                y_low_func = y_low
            else:
                y_low_func = lambda x: y_low

            if callable(y_high):
                y_high_func = y_high
            else:
                y_high_func = lambda x: y_high

            # 使用scipy的dblquad进行二重数值积分
            result, error = dblquad(integrand,
                                    np.float64(x_low_func(0, 0)) if not callable(x_low) else x_low_func(0, 0),
                                    np.float64(x_high_func(0, 0)) if not callable(x_high) else x_high_func(0, 0),
                                    y_low_func,
                                    y_high_func,
                                    **kwargs)
            return result, error

        except Exception as e:
            return f"Error: {e}"


    # 更实用的字符串输入版本
    def integrate_multi_equation(input_str, **kwargs):
        """
        支持字符串输入的二重数值积分

        参数:
        input_str: 输入字符串,格式为:"函数表达式, x下限, x上限, y下限, y上限"
                   示例:"x*y, 0, 1, 0, 1"
        **kwargs: 传递给积分函数的参数
        """
        try:
            # 解析输入字符串
            parts = [part.strip() for part in input_str.split(',')]
            if len(parts) != 5:
                return "错误: 输入格式应为: '函数表达式, x下限, x上限, y下限, y上限'"

            func_str, x_low_str, x_high_str, y_low_str, y_high_str = parts

            # 创建符号变量
            x, y = sp.symbols('x y')

            # 解析函数表达式
            integrand_expr = sp.sympify(func_str)
            integrand_func = sp.lambdify((x, y), integrand_expr, 'numpy')

            # 解析积分限
            def parse_limit(limit_str):
                try:
                    return float(limit_str)
                except:
                    # 如果是表达式,创建函数
                    expr = sp.sympify(limit_str)
                    if x in expr.free_symbols:
                        return sp.lambdify(x, expr, 'numpy')
                    else:
                        return float(expr)

            x_low = parse_limit(x_low_str)
            x_high = parse_limit(x_high_str)
            y_low = parse_limit(y_low_str)
            y_high = parse_limit(y_high_str)

            # 执行数值积分
            return integral2(integrand_func, x_low, x_high, y_low, y_high, **kwargs)

        except Exception as e:
            return f"Error: {e}"


    # 二重积分 ∫₀¹∫₀¹ xy dxdy
    # 示例1: 简单二重积分 ∫₀¹∫₀¹ x*y dxdy
    print("示例1:", integrate_multi_equation("x*y, 0, 1, 0, 1"))
    # 1/4

    # 示例2: 带变量依赖的积分 ∫₀¹∫₀^{1-x} x*y dydx
    print("\n示例2:", integrate_multi_equation("x*y, 0, 1, 0, 1-x"))
    # (1 - x)**2/4

    # 示例3: 三重积分 ∫₀¹∫₀¹∫₀¹ x*y*z dxdydz
    print("\n示例3:", integrate_multi_equation("x*y*z, 0, 1, 0, 1, 0, 1"))
    # 1/8
    
    
    对三重积分进行数值计算

    q = integral3(fun,xmin,xmax,ymin,ymax,zmin,zmax) 在平面区域 xmin ≤ x ≤ xmax 和 ymin(x) ≤ y ≤ ymax(x) 和 zmin(x,y) ≤ z ≤ zmax(x,y) 上逼近函数 z = fun(x,y,z) 的积分

    q = integral3(fun,xmin,xmax,ymin,ymax,Name,Value) 使用一个或多个 Name,Value 对组参量指定其他选项

    fun — 被积函数,函数句柄

    xmin — x 的下限,实数,复数

    xmax — x 的上限,实数,复数

    ymin — y 的下限,实数,复数

    ymax — y 的上限,实数,复数

    zmin — z 的下限,实数,复数

    zmax — z 的上限,实数,复数

    示例1: 立方体上的简单三重积分 - 计算立方体质量

    假设密度为常数 ρ = 1,在立方体 [0,1]×[0,1]×[0,1] 上

    print("密度: ρ(x,y,z) = 1, 区域: [0,1]×[0,1]×[0,1]")
    result, error = integral3(1, 0, 1, 0, 1, 0, 1)
    print(f"立方体体积: {result:.6f}, 误差估计: {error:.2e}")
    #密度: ρ(x,y,z) = 1, 区域: [0,1]×[0,1]×[0,1]
    #立方体体积: 1.000000, 误差估计: 1.11e-14

    示例2: 变密度立方体 - 计算非均匀物体的质量

    密度函数 ρ(x,y,z) = x + y + z,在立方体 [0,1]×[0,1]×[0,1] 上

    result, error = integral3(x + y + z, 0, 1, 0, 1, 0, 1)
    print(f"变密度立方体质量: {result:.6f}, 误差估计: {error:.2e}")
    #变密度立方体质量: 1.500000, 误差估计: 2.77e-14
    #理论值: 1.5

    示例3: 球体体积 - 计算单位球体积

    def sphere_integrand(x, y, z):
        return 1.0

    def z_low_sphere(x, y):
        return -np.sqrt(1 - x ** 2 - y ** 2)

    def z_high_sphere(x, y):
        return np.sqrt(1 - x ** 2 - y ** 2)

    def y_low_sphere(x):
        return -np.sqrt(1 - x ** 2)

    def y_high_sphere(x):
        return np.sqrt(1 - x ** 2)

    result, error = integral3(sphere_integrand, -1, 1, y_low_sphere, y_high_sphere, z_low_sphere, z_high_sphere)
    print(f"单位球体积: {result:.6f}, 误差估计: {error:.2e}")
    #单位球体积: 4.188790, 误差估计: 2.00e-09

    示例4: 转动惯量计算 - 长方体绕z轴的转动惯量

    I = ∫∫∫(x² + y²)ρ dxdydz,在长方体 [0,a]×[0,b]×[0,c] 上,ρ=1

    result, error = integral3(x**2 + y**2, 0, 2, 0, 1, 0, 1)
    print(f"转动惯量: {result:.6f}, 误差估计: {error:.2e}")
    #转动惯量: 1.333333, 误差估计: 1.48e-14

    示例5: 热传导问题 - 三维温度场积分

    温度分布 T(x,y,z) = sin(x)cos(y)exp(-z),在长方体区域上

    result, error = integral3(sin(x)*cos(y)*exp(-z), 0, 3.14159, 0, 1.57080, 0, 2)
    print(f"总热通量: {result:.6f}, 误差估计: {error:.2e}\n")
    #总热通量: 1.354949, 误差估计: 1.56e-14

    示例6: 概率计算 - 三维联合概率密度

    f(x,y,z) = x*y*z*exp(-x-y-z),在第一卦限上

    result, error = integral3(x*y*z*exp(-x-y-z), 0, 5, 0, 5, 0, 5)
    print(f"联合概率: {result:.6f}, 误差估计: {error:.2e}\n")
    #联合概率: 0.883554, 误差估计: 9.81e-15

    示例7: 电场能量密度 - 电磁场中的能量存储

    能量密度 w = ε/2 * |E|² = ε/2 * (E_x² + E_y² + E_z²)

    result, error = integral3(x**2 + y**2 + z**2, 0, 1, 0, 1, 0, 1)
    print(f"电场能量: {result:.6f}, 误差估计: {error:.2e}")
    #电场能量: 1.000000, 误差估计: 2.58e-14

    示例8: 复杂区域 - 锥体体积

    def cone_integrand(x, y, z):
        return 1.0

    def z_low_cone(x, y):
        return 0

    def z_high_cone(x, y):
        return 1 - np.sqrt(x ** 2 + y ** 2)

    在单位圆盘上积分
    def y_low_cone(x):
        return -np.sqrt(1 - x ** 2)

    def y_high_cone(x):
        return np.sqrt(1 - x ** 2)

    result, error = integral3(cone_integrand, -1, 1, y_low_cone, y_high_cone, z_low_cone, z_high_cone)
    print(f"锥体体积: {result:.6f}, 误差估计: {error:.2e}")
    #锥体体积: 1.047198, 误差估计: 1.48e-08
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    from scipy.integrate import dblquad, tplquad, nquad
    import sympy as sp


    def integral3(integrand, x_low, x_high, y_low, y_high, z_low, z_high, **kwargs):
        """
        三重数值积分函数

        参数:
        integrand: 被积函数 f(x, y, z)
        x_low, x_high: x的积分限
        y_low, y_high: y的积分限(可以是x的函数)
        z_low, z_high: z的积分限(可以是x,y的函数)
        """
        try:
            # 处理积分限为函数的情况
            y_low_func = y_low if callable(y_low) else lambda x: float(y_low)
            y_high_func = y_high if callable(y_high) else lambda x: float(y_high)
            z_low_func = z_low if callable(z_low) else lambda x, y: float(z_low)
            z_high_func = z_high if callable(z_high) else lambda x, y: float(z_high)

            # 使用scipy的tplquad进行三重数值积分
            result, error = tplquad(integrand,
                                    float(x_low), float(x_high),
                                    y_low_func, y_high_func,
                                    z_low_func, z_high_func,
                                    **kwargs)
            return result
        except Exception as e:
            return f"Error in integral3: {e}"

    def integral2(integrand, x_low, x_high, y_low, y_high, **kwargs):
        """
        对标MATLAB integral2函数的二重数值积分实现

        参数:
        integrand: 被积函数,接受两个参数f(x,y)
        x_low, x_high: x的积分下限和上限(可以是常数或函数)
        y_low, y_high: y的积分下限和上限(可以是常数或函数,y_low和y_high可以是x的函数)
        **kwargs: 传递给scipy积分函数的参数

        返回:
        积分结果和误差估计
        """
        try:
            # 处理积分限为函数的情况
            if callable(x_low):
                x_low_func = x_low
            else:
                x_low_func = lambda x, y: x_low

            if callable(x_high):
                x_high_func = x_high
            else:
                x_high_func = lambda x, y: x_high

            if callable(y_low):
                y_low_func = y_low
            else:
                y_low_func = lambda x: y_low

            if callable(y_high):
                y_high_func = y_high
            else:
                y_high_func = lambda x: y_high

            # 使用scipy的dblquad进行二重数值积分
            result, error = dblquad(integrand,
                                    np.float64(x_low_func(0, 0)) if not callable(x_low) else x_low_func(0, 0),
                                    np.float64(x_high_func(0, 0)) if not callable(x_high) else x_high_func(0, 0),
                                    y_low_func,
                                    y_high_func,
                                    **kwargs)
            return result

        except Exception as e:
            return f"Error: {e}"

    def integrate_multi_equation(input_str, **kwargs):
        """
        支持多重数值积分的通用函数

        参数:
        input_str: 输入字符串,格式为:"函数表达式, 变量1下限, 变量1上限, 变量2下限, 变量2上限, ..."
        **kwargs: 传递给scipy积分函数的参数
        """
        try:
            # 解析输入字符串
            parts = [part.strip() for part in input_str.split(',')]
            if len(parts) < 5 or len(parts) % 2 != 1:
                return "错误: 输入格式应为: '函数表达式, 下限1, 上限1, 下限2, 上限2, ...'"

            func_str = parts[0]
            limits = parts[1:]

            # 根据积分重数选择不同的积分方法
            num_integrals = len(limits) // 2

            if num_integrals == 2:
                # 二重积分
                x, y = sp.symbols('x y')
                integrand_expr = sp.sympify(func_str)
                integrand_func = sp.lambdify((x, y), integrand_expr, 'numpy')

                # 解析积分限
                x_low, x_high, y_low_str, y_high_str = limits

                # 处理y的积分限(可能包含x)
                y_low_expr = sp.sympify(y_low_str)
                y_high_expr = sp.sympify(y_high_str)

                y_low_func = sp.lambdify(x, y_low_expr, 'numpy') if x in y_low_expr.free_symbols else float(y_low_expr)
                y_high_func = sp.lambdify(x, y_high_expr, 'numpy') if x in y_high_expr.free_symbols else float(y_high_expr)

                return integral2(integrand_func, float(x_low), float(x_high), y_low_func, y_high_func, **kwargs)

            elif num_integrals == 3:
                # 三重积分
                x, y, z = sp.symbols('x y z')
                integrand_expr = sp.sympify(func_str)
                integrand_func = sp.lambdify((x, y, z), integrand_expr, 'numpy')

                # 解析积分限
                x_low, x_high, y_low_str, y_high_str, z_low_str, z_high_str = limits

                # 处理y的积分限(可能包含x)
                y_low_expr = sp.sympify(y_low_str)
                y_high_expr = sp.sympify(y_high_str)
                y_low_func = sp.lambdify(x, y_low_expr, 'numpy') if x in y_low_expr.free_symbols else float(y_low_expr)
                y_high_func = sp.lambdify(x, y_high_expr, 'numpy') if x in y_high_expr.free_symbols else float(y_high_expr)

                # 处理z的积分限(可能包含x,y)
                z_low_expr = sp.sympify(z_low_str)
                z_high_expr = sp.sympify(z_high_str)
                z_low_func = sp.lambdify((x, y), z_low_expr, 'numpy') if (
                            x in z_low_expr.free_symbols or y in z_low_expr.free_symbols) else float(z_low_expr)
                z_high_func = sp.lambdify((x, y), z_high_expr, 'numpy') if (
                            x in z_high_expr.free_symbols or y in z_high_expr.free_symbols) else float(z_high_expr)

                return integral3(integrand_func, float(x_low), float(x_high), y_low_func, y_high_func, z_low_func,
                                 z_high_func, **kwargs)

            else:
                return f"暂不支持 {num_integrals} 重积分"

        except Exception as e:
            return f"Error: {e}"


    # 二重积分 ∫₀¹∫₀¹ xy dxdy
    # 示例1: 简单二重积分 ∫₀¹∫₀¹ x*y dxdy
    print("示例1:", integrate_multi_equation("x*y, 0, 1, 0, 1"))
    # 1/4

    # 示例2: 带变量依赖的积分 ∫₀¹∫₀^{1-x} x*y dydx
    print("\n示例2:", integrate_multi_equation("x*y, 0, 1, 0, 1-x"))
    # (1 - x)**2/4

    # 示例3: 三重积分 ∫₀¹∫₀¹∫₀¹ x*y*z dxdydz
    print("\n示例3:", integrate_multi_equation("x*y*z, 0, 1, 0, 1, 0, 1"))
    # 1/8
    
    
    分部积分

    G=integrateByParts(F,du)将分部积分应用于F中的积分,其中微分du被积分.

    在F中指定积分时,您可以通过使用int函数并将“Hold”选项设置为true来返回未求值的积分形式.然后,您可以使用integrateByParts按部件显示集成的步骤.

    F —— 包含积分的表达式

    du —— 待整合的差异

    示例1:多项式与指数函数的积分(常见于物理和工程)

    result1 = integrateByParts(x*exp(x), 1)  # u = x, du = 1, dv = e^x dx
    print(f"结果: {result1}")
    #结果: x**2 - Integral(x, x)

    示例2:多项式与三角函数的积分(常见于信号处理)

    result2 = integrateByParts(x*sin(x), 1)  # u = x, du = 1, dv = sin(x) dx
    print(f"结果: {result2}")
    #结果: x**2 - Integral(x, x)

    示例3:对数函数的积分(常见于概率论和统计学)

    result3 = integrateByParts(ln(x), 1/x)  # u = ln(x), du = 1/x, dv = 1 dx
    print(f"结果: {result3}")
    #结果: log(x)*Ei(2*log(x)) - Integral(Ei(2*log(x))/x, x)

    示例4:反三角函数的积分
    result4 = integrateByParts(atan(x), 1/(x**2 + 1))  # u = atan(x), du = 1/(1+x^2)
    print(f"结果: {result4}")
    #结果: atan(x)*Integral(x/atan(x), x) - Integral(Integral(x/atan(x), x)/(x**2 + 1), x)

    示例5:分部积分的例子

    result5 = integrateByParts(x**2*exp(x), 2*x)  # u = x^2, du = 2x
    print(f"分部积分结果: {result5}")
    #分部积分结果: x**3 - Integral(2*x**2, x)
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def integrate_by_parts(input_str):
        """
        该函数对标 MATLAB 的 integrateByParts 函数,用于执行分部积分操作。
        分部积分公式为 ∫u dv = u*v - ∫v du。

        参数:
        input_str (str): 输入的字符串,格式为 "被积函数,du表达式",例如 "u*diff(v, x),diff(u)"。

        返回:
        sympy 表达式或错误信息字符串: 若计算成功,返回分部积分的结果;若出现错误,返回错误信息。
        """
        # 定义符号变量和函数
        try:
            # 定义符号变量 x
            x = sp.symbols('x')
            # 定义函数 u(x) 和 v(x)
            u = sp.Function('u')(x)
            v = sp.Function('v')(x)
            # 使用逗号分割输入字符串,获取被积函数和 du 表达式
            params = input_str.split(',')
            # 检查输入参数数量是否为 2
            if len(params) != 2:
                raise ValueError("输入格式错误,需要两个参数")
            F_str, du_str = params

            # 转换 Matlab 语法到 SymPy 表达式
            try:
                # 处理被积函数(替换 int 为 Integral,并解析)
                F_expr = sp.sympify(
                    F_str,
                    locals={
                        'int': sp.Integral,
                        'diff': sp.diff,
                        'exp': sp.exp,
                        'sin': sp.sin,
                        'cos': sp.cos,
                        'log': sp.log,
                        'ln': sp.log,
                        'u': u,
                        'v': v,
                        'x': x,
                    },
                )
                # 提取被积函数,例如 u*Derivative(v, x)
                integrand = F_expr.args[0]
                # 解析微分部分(如 diff(u))
                du = sp.sympify(
                    du_str,
                    locals={
                        'diff': sp.diff,
                        'exp': sp.exp,
                        'sin': sp.sin,
                        'cos': sp.cos,
                        'log': sp.log,
                        'ln': sp.log,
                        'u': u,
                        'x': x,
                        'Symbol': sp.Symbol
                    },
                )
            except Exception as e:
                # 尝试直接解析输入字符串为元组
                expr = sp.sympify(input_str)
                if isinstance(expr, tuple) and len(expr) == 2:
                    F, du = expr
                    # 从 du 中推导出 u
                    u = sp.integrate(du, x)  # u 是 du 的不定积分
                    # F = u * dv, 因此 dv = F / u
                    dv = F / u
                    # 计算 v
                    v = sp.integrate(dv, x)
                    # 返回积分分部公式的结果 u*v - ∫v*du
                    return u * v - sp.integrate(v * du, x)

            # 计算 u 和 dv/dx
            try:
                # 从 du = du/dx 积分得到 u(假设积分常数为 0)
                u_expr = sp.integrate(du, x)
                # 计算 dv/dx = 被积函数 / u
                dv_dx = integrand / u_expr
                # 积分得到 v
                v_expr = sp.integrate(dv_dx, x)
            except Exception as e:
                raise ValueError(f"积分计算错误: {e}")

            # 应用分部积分公式
            result = u_expr * v_expr - sp.Integral(v_expr * du, x)
            return result
        except Exception as e:
            return f"错误: {str(e)}"


    # 示范代码
    if __name__ == "__main__":
        # 示例输入
        input_str = "int(u*diff(v)),diff(u)"
        result = integrate_by_parts(input_str)
        print("分部积分结果:", result)
        # u(x)*v(x) - Integral(v(x)*Derivative(u(x), x), x)
    
    
    一维数据插值

    vq = interp1(x,v,xq) 使用线性插值返回一维函数在特定查询点的插入值。向量 x 包含样本点,v 包含对应值 v(x)。向量 xq 包含查询点的坐标。

    如果您有多个在同一点坐标采样的数据集,则可以将 v 以数组的形式进行传递。数组 v 的每一列都包含一组不同的一维样本值。

    vq = interp1(x,v,xq,method) 指定备选插值方法:'linear'、'nearest'、'next'、'previous'、'pchip'、'cubic'、'v5cubic'、'makima' 或 'spline'。默认方法为 'linear'。

    vq = interp1(x,v,xq,method,extrapolation) 用于指定外插策略,来计算落在 x 域范围外的点。如果希望使用 method 算法进行外插,可将 extrapolation 设置为 'extrap'。您也可以指定一个标量值,这种情况下,interp1 将为所有落在 x 域范围外的点返回该标量值。

    x - 样本点, 向量

    v - 样本值, 向量 | 矩阵

    xq - 查询点, 标量 | 向量 | 矩阵

    method - 插值方法, 'linear' (默认) | 'nearest' | 'next' | 'previous' | 'pchip' | 'cubic' | 'v5cubic' | 'makima' | 'spline'

    extrapolation - 外插策略, 'extrap' | 标量值

    vq - 插入的值, 标量 | 向量 | 矩阵

    pp - 分段多项式, 结构体

    import matplotlib.pyplot as plt

    示例1:气象数据分析 - 温度插值

    已知每小时温度数据,插值得到每15分钟的温度
    hours = [0, 1, 2, 3, 4, 5, 6]  # 时间(小时)
    temperatures = [15, 14, 13, 12, 11, 10, 12]  # 温度(摄氏度)

    生成每15分钟的时间点
    quarter_hours = np.linspace(0, 6, 25)

    使用三次样条插值
    result = interp1(hours, temperatures, quarter_hours, cubic)
    print(f"插值结果前5个点: {result[:5] if hasattr(result, '__len__') else result}")
    #插值结果前5个点: [15,14.74707031,14.49665179,14.24790737,14]

    可视化
    plt.figure(figsize=(10, 6))
    plt.subplot(2, 3, 1)
    plt.plot(hours, temperatures, 'ro-', label='原始数据', markersize=8)
    plt.plot(quarter_hours, result, 'b-', label='三次样条插值', alpha=0.7)
    plt.xlabel('时间 (小时)')
    plt.ylabel('温度 (°C)')
    plt.title('气象数据插值')
    plt.legend()
    plt.grid(True, alpha=0.3)

    示例2:金融数据分析 - 股票价格插值

    已知每日收盘价,插值得到日内价格
    days = [1, 2, 3, 4, 5]  # 交易日
    prices = [100, 102, 98, 105, 103]  # 收盘价

    生成更细的时间网格
    fine_days = np.linspace(1, 5, 41)

    使用线性插值
    price_interp = interp1(days, prices, fine_days, linear)
    print(f"第3.5天插值价格: {price_interp[20]:.2f}")
    #第3.5天插值价格: 98.00

    plt.subplot(2, 3, 2)
    plt.plot(days, prices, 'go-', label='收盘价', markersize=8)
    plt.plot(fine_days, price_interp, 'm-', label='线性插值', alpha=0.7)
    plt.xlabel('交易日')
    plt.ylabel('价格 ($)')
    plt.title('股票价格插值')
    plt.legend()
    plt.grid(True, alpha=0.3)

    示例3:工程应用 - 材料应力应变曲线

    strain = [0, 0.001, 0.002, 0.003, 0.004, 0.005]
    stress = [0, 200, 380, 520, 610, 650]  # MPa

    fine_strain = np.linspace(0, 0.005, 51)
    stress_interp = interp1(strain, stress, fine_strain, cubic)

    plt.subplot(2, 3, 3)
    plt.plot(strain * 1000, stress, 'bo-', label='实验数据', markersize=6)
    plt.plot(fine_strain * 1000, stress_interp, 'c-', label='三次样条', alpha=0.7)
    plt.xlabel('应变 (×10⁻³)')
    plt.ylabel('应力 (MPa)')
    plt.title('材料应力应变曲线')
    plt.legend()
    plt.grid(True, alpha=0.3)

    示例4:医学应用 - 心电图数据重采样

    time_ecg = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
    ecg_signal = [0, 0.5, 1.0, 0.2, -0.3, -0.1, 0.8, 1.2, 0.4, 0.1, 0]

    更高采样率
    fine_time = np.linspace(0, 1, 101)
    ecg_interp = interp1(time_ecg, ecg_signal, fine_time, cubic)

    plt.subplot(2, 3, 4)
    plt.plot(time_ecg, ecg_signal, 'ro-', label='原始ECG', markersize=4)
    plt.plot(fine_time, ecg_interp, 'r-', label='插值ECG', alpha=0.7)
    plt.xlabel('时间 (s)')
    plt.ylabel('振幅 (mV)')
    plt.title('心电图数据重采样')
    plt.legend()
    plt.grid(True, alpha=0.3)

    示例5:地理信息系统 - 高程数据插值

    distance = [0, 100, 200, 300, 400, 500]  # 米
    elevation = [50, 65, 80, 60, 75, 70]  # 米

    fine_distance = np.linspace(0, 500, 101)
    elev_interp = interp1(distance, elevation, fine_distance, linear)

    plt.subplot(2, 3, 5)
    plt.plot(distance, elevation, 's-', color='brown', label='测量点', markersize=6)
    plt.plot(fine_distance, elev_interp, '-', color='green', label='线性插值', alpha=0.7)
    plt.xlabel('距离 (m)')
    plt.ylabel('高程 (m)')
    plt.title('地形高程插值')
    plt.legend()
    plt.grid(True, alpha=0.3)

    示例6:信号处理 - 不同插值方法比较

    x_original = [0, 1, 2, 3, 4, 5]
    y_original = [0, 1, 0, -1, 0, 1]

    x_fine = np.linspace(0, 5, 101)

    methods = ['linear', 'nearest', 'cubic']
    colors = ['blue', 'green', 'red']
    labels = ['线性', '最近邻', '三次样条']

    plt.subplot(2, 3, 6)
    plt.plot(x_original, y_original, 'ko', label='原始数据', markersize=8)

    for method, color, label in zip(methods, colors, labels):
        y_interp = interp1(f"{list(x_original)}, {list(y_original)}, {list(x_fine)}, '{method}'")
        plt.plot(x_fine, y_interp, color=color, label=label, alpha=0.7)

    plt.xlabel('x')
    plt.ylabel('y')
    plt.title('不同插值方法比较')
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    示例7:高级误差分析

    使用已知函数生成测试数据
    def original_function(x):
        return np.sin(x) + 0.5 * np.cos(2 * x)

    稀疏采样点
    x_sparse = np.linspace(0, 2 * np.pi, 8)
    y_sparse = original_function(x_sparse)

    密集采样点(作为"真实"值)
    x_dense = np.linspace(0, 2 * np.pi, 100)
    y_true = original_function(x_dense)

    methods = [linear, nearest, cubic]
    errors = {}

    不同插值方法的均方根误差(RMSE):
    for method in methods:
        y_interp = interp1(x_sparse, y_sparse, x_dense, method)
        rmse = np.sqrt(np.mean((y_interp - y_true) ** 2))
        errors[method] = rmse
        print(f"  {method}: {rmse:.6f}")
    #linear: 0.109000
    #nearest: 0.254234
    #cubic: 0.024224

    可视化误差分析
    plt.figure(figsize=(12, 8))

    for i, method in enumerate(methods, 1):
        plt.subplot(2, 2, i)
        y_interp = interp1(f"{list(x_sparse)}, {list(y_sparse)}, {list(x_dense)}, '{method}'")

        plt.plot(x_dense, y_true, 'k-', label='真实函数', linewidth=2)
        plt.plot(x_sparse, y_sparse, 'ro', label='采样点', markersize=8)
        plt.plot(x_dense, y_interp, 'b-', label=f'{method}插值', alpha=0.8)
        plt.fill_between(x_dense, y_true, y_interp, alpha=0.3, color='red', label='误差区域')

        plt.xlabel('x')
        plt.ylabel('y')
        plt.title(f'{method}插值 - RMSE: {errors[method]:.4f}')
        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 numpy as np
    from scipy.interpolate import interp1d, CubicSpline


    def interpolation_one_dimensional(input_str):
        """
        对标MATLAB的interp1函数,实现一维数据插值

        参数:
        input_str: 输入参数字符串,支持以下格式:
                   "y, xq"                -> 自动生成x坐标
                   "x, y, xq"             -> 基本插值
                   "x, y, xq, method"     -> 指定插值方法
                   "x, y, xq, method, extrap" -> 指定方法和外推值

        返回:
         插值结果数组,错误时返回错误信息字符串

        示例:
        >>> interpolation_one_dimensional("[1,2,3], [4,5,6], 2.5")
        array(5.5)
        >>> interpolation_one_dimensional("[1,2,3], [4,5,6], [0,4], 'linear', 0")
        array([4., 0.])
        """
        try:
            # 解析输入字符串为参数元组
            expr = sp.sympify(input_str, evaluate=False)
            params = list(expr) if isinstance(expr, tuple) else [expr]

            # 有效插值方法集合
            valid_methods = {
                'linear', 'nearest', 'zero',
                'slinear', 'quadratic', 'cubic',
                'previous', 'next'
            }

            # 初始化默认参数
            x, y, xq = None, None, None
            method = 'linear'
            extrap = np.nan

            # 参数转换函数
            def convert(param):
                """将SymPy对象转换为数值数组"""
                if isinstance(param, list):
                    matrix = sp.Matrix(param)
                    if matrix.is_symbolic():
                        raise ValueError(f"Symbolic variable {param} not allowed")
                    else:
                        return np.array(matrix.tolist(), dtype=float).flatten()
                elif param.is_Number:
                    return np.array([float(param)])
                elif param.free_symbols:
                    raise ValueError(f"Symbolic variable {param} not allowed")
                else:  # 处理包含符号的表达式
                    try:
                        return np.array([float(param.evalf())])
                    except:
                        raise ValueError(f"Cannot convert {param} to numeric")

            # 处理前三个数值参数
            numeric_params = []
            for i, param in enumerate(params[:3]):
                try:
                    numeric_params.append(convert(param))
                except:
                    if i < 2:
                        raise
                    numeric_params.append(np.array([float(param.evalf())]))

            # 参数逻辑判断
            if len(numeric_params) == 2:  # y, xq 模式
                y, xq = numeric_params
                x = np.arange(1, len(y) + 1)
            else:  # x, y, xq 模式
                x, y, xq = numeric_params[:3]
                if len(x) != len(y):
                    raise ValueError("x和y的长度必须一致")

            # 验证x的单调性
            if not np.all(np.diff(x) > 0):
                raise ValueError("x必须是严格单调递增的")

            # 处理方法参数
            if len(params) >= 4:
                method_param = params[3]
                method_candidate = str(method_param).lower()

                if method_candidate in valid_methods:
                    method = method_candidate
                else:
                    try:  # 尝试解析为外推值
                        extrap = float(sp.sympify(method_param))
                    except:
                        pass

            # 处理外推参数
            if len(params) >= 5:
                try:
                    extrap = float(params[4])
                except:
                    raise ValueError("无效的外推值")

            # 创建插值器
            # 关键修改点:单独处理三次样条
            if method in ['cubic', 'spline']:
                # 使用CubicSpline并设置not-a-knot边界条件
                if not np.all(np.diff(x) > 0):
                    raise ValueError("三次样条需要严格单调的x值")

                # MATLAB的cubic对应SciPy的CubicSpline with not-a-knot
                interpolator = CubicSpline(
                    x, y,
                    bc_type='not-a-knot',
                    extrapolate=extrap is not None
                )
            else:
                # 其他方法保持原有interp1d调用
                interpolator = interp1d(
                    x, y,
                    kind=method,
                    fill_value=extrap,
                    bounds_error=False,
                    assume_sorted=True
                )

            # 执行插值计算
            return interpolator(xq)

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


    # 示例测试
    if __name__ == "__main__":
        # 基本线性插值
        print(interpolation_one_dimensional("[1,2,3], [4,5,6], 2.5"))
        # [5.5]

        # 自动生成x坐标
        print(interpolation_one_dimensional("[4,5,6], [1.5,2.5]"))
        # [4.5, 5.5]

        # 三次样条插值
        print(interpolation_one_dimensional("[0,1,2], [0,1,4], 1.5, 'cubic'"))
        # [2.25]

        # 外推测试
        print(interpolation_one_dimensional("[1,2,3], [4,5,6], 4, 'linear', 0"))
        # [0]
    
    
    meshgrid格式的二维网格数据的插值

    Vq = interp2(X,Y,V,Xq,Yq) 使用线性插值返回双变量函数在特定查询点的插入值。结果始终穿过函数的原始采样。X 和 Y 包含样本点的坐标。V 包含各样本点处的对应函数值。Xq 和 Yq 包含查询点的坐标。

    Vq = interp2(___,method) 指定备选插值方法:'linear'、'nearest'、'cubic'、'makima'。默认方法为 'linear'。

    Vq = interp2(___,method,extrapval) 还指定标量值 extrapval,此参数会为处于样本点域范围外的所有查询点赋予该标量值。

    X,Y — 样本网格点, 矩阵 | 向量

    V — 样本值,矩阵

    Xq,Yq — 查询点, 标量 | 向量 | 矩阵

    method — 插值方法, 'linear' (默认) | 'nearest' | 'cubic' | 'makima'

    extrapval — X 和 Y 域范围外的函数值, 标量

    示例1:地形高程插值(地理信息系统)

    创建示例地形数据
    x = np.linspace(0, 10, 6)  # 经度方向
    y = np.linspace(0, 8, 5)  # 纬度方向
    X, Y = np.meshgrid(x, y)

    模拟地形高程(山峰和山谷)
    Z = np.exp(-((X - 5) ** 2 + (Y - 4) ** 2) / 8) * 1000 + \
        np.exp(-((X - 2) ** 2 + (Y - 2) ** 2) / 4) * 500 - \
        np.exp(-((X - 8) ** 2 + (Y - 6) ** 2) / 6) * 300

    生成更密集的查询网格
    xq = np.linspace(0, 10, 50)
    yq = np.linspace(0, 8, 40)

    使用三次样条插值
    Zq = interp2(x, y, Z, xq, yq, cubic)

    可视化
    fig = plt.figure(figsize=(15, 10))

    原始稀疏数据
    ax1 = fig.add_subplot(2, 3, 1, projection='3d')
    surf1 = ax1.plot_surface(X, Y, Z, cmap='terrain', alpha=0.8)
    ax1.scatter(X, Y, Z, color='red', s=50)
    ax1.set_title('原始地形数据点')
    ax1.set_xlabel('经度')
    ax1.set_ylabel('纬度')
    ax1.set_zlabel('高程 (m)')

    插值后的地形
    Xq, Yq = np.meshgrid(xq, yq)
    ax2 = fig.add_subplot(2, 3, 2, projection='3d')
    surf2 = ax2.plot_surface(Xq, Yq, Zq, cmap='terrain', alpha=0.8)
    ax2.set_title('插值后地形')
    ax2.set_xlabel('经度')
    ax2.set_ylabel('纬度')
    ax2.set_zlabel('高程 (m)')

    示例2:温度分布插值(气象学)

    模拟温度数据
    x_temp = np.array([0, 2, 4, 6, 8, 10])  # 东西方向 (km)
    y_temp = np.array([0, 1, 2, 3, 4])  # 南北方向 (km)
    X_temp, Y_temp = np.meshgrid(x_temp, y_temp)

    温度场(城市热岛效应)
    T = 20 + 5 * np.exp(-((X_temp - 5) ** 2 + (Y_temp - 2) ** 2) / 4) - \
        2 * np.exp(-((X_temp - 1) ** 2 + (Y_temp - 3) ** 2) / 2)

    密集查询点
    xq_temp = np.linspace(0, 10, 30)
    yq_temp = np.linspace(0, 4, 20)

    Tq = interp2(x_temp, y_temp, T, xq_temp, yq_temp, linear)

    Xq_temp, Yq_temp = np.meshgrid(xq_temp, yq_temp)

    ax3 = fig.add_subplot(2, 3, 3)
    contour = ax3.contourf(Xq_temp, Yq_temp, Tq, levels=20, cmap='hot')
    ax3.scatter(X_temp, Y_temp, color='blue', s=30)
    ax3.set_title('温度分布 (°C)')
    ax3.set_xlabel('东西距离 (km)')
    ax3.set_ylabel('南北距离 (km)')
    plt.colorbar(contour, ax=ax3)

    示例3:图像放大(计算机视觉)

    创建低分辨率图像(5x5像素)
    small_image = np.array([
        [0.1, 0.3, 0.5, 0.3, 0.1],
        [0.3, 0.7, 0.9, 0.7, 0.3],
        [0.5, 0.9, 1.0, 0.9, 0.5],
        [0.3, 0.7, 0.9, 0.7, 0.3],
        [0.1, 0.3, 0.5, 0.3, 0.1]
    ])

    x_img = np.arange(5)
    y_img = np.arange(5)

    放大到25x25
    xq_img = np.linspace(0, 4, 25)
    yq_img = np.linspace(0, 4, 25)

    使用三次样条插值获得更平滑的放大
    large_image = interp2(x_img, y_img, small_image, xq_img, yq_img, cubic)

    ax4 = fig.add_subplot(2, 3, 4)
    ax4.imshow(small_image, cmap='gray', extent=[0, 4, 0, 4], interpolation='none')
    ax4.set_title('原始低分辨率图像')
    ax4.set_xlabel('X 像素')
    ax4.set_ylabel('Y 像素')

    ax5 = fig.add_subplot(2, 3, 5)
    ax5.imshow(large_image, cmap='gray', extent=[0, 4, 0, 4], interpolation='none')
    ax5.set_title('插值放大图像')
    ax5.set_xlabel('X 像素')
    ax5.set_ylabel('Y 像素')

    示例4:流体力学 - 速度场插值

    模拟流体速度场
    x_flow = np.array([0, 1, 2, 3, 4])
    y_flow = np.array([0, 1, 2, 3])
    X_flow, Y_flow = np.meshgrid(x_flow, y_flow)

    速度大小(模拟管道流动)
    U = Y_flow * (4 - Y_flow) / 4  # 抛物线速度分布

    密集查询网格
    xq_flow = np.linspace(0, 4, 20)
    yq_flow = np.linspace(0, 3, 15)

    Uq = interp2(x_flow, y_flow, U, xq_flow, yq_flow, cubic)

    Xq_flow, Yq_flow = np.meshgrid(xq_flow, yq_flow)

    ax6 = fig.add_subplot(2, 3, 6)
    stream = ax6.streamplot(Xq_flow, Yq_flow, Uq, np.zeros_like(Uq),
                            color=Uq, cmap='viridis', linewidth=2)
    ax6.scatter(X_flow, Y_flow, color='red', s=20)
    ax6.set_title('流体速度场')
    ax6.set_xlabel('X 位置')
    ax6.set_ylabel('Y 位置')
    plt.colorbar(stream.lines, ax=ax6)

    plt.tight_layout()
    plt.show()
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import re
    import sympy as sp
    from scipy.interpolate import RegularGridInterpolator


    def interpolation_two_dimensional(input_str):
        """
        对标 MATLAB 的 interp2 函数,实现二维网格数据插值

        参数:
        input_str: 输入参数字符串,支持以下格式:
                   "X, Y, V, Xq, Yq"                  -> 基本插值(默认线性)
                   "X, Y, V, Xq, Yq, method"          -> 指定插值方法
                   "X, Y, V, Xq, Yq, method, extrap"  -> 指定方法和外推值

        返回:
          插值结果数组,错误时返回错误信息字符串

        示例:
        >>> interpolation_two_dimensional("[0,1], [0,1], [[1,2],[3,4]], 0.5, 0.5")
        array(2.5)
        >>> interpolation_two_dimensional("[0,1], [0,1], [[1,2],[3,4]], [0.5,2], [0.5,1], 'linear', 0)")
        array([2.5, 0. ])
        """
        try:
            # ------------------------- 输入解析 -------------------------
            # 解析输入字符串为参数元组
            expr = sp.sympify(input_str, evaluate=False)
            print(expr)
            params = list(expr) if isinstance(expr, tuple) else [expr]
            # 有效插值方法集合
            valid_methods = {
                'linear', 'nearest', 'cubic',
                'makima'  # 注意:SciPy 的 cubic 对应 MATLAB 的 spline
            }

            # 初始化默认参数
            X, Y, V, Xq, Yq = None, None, None, None, None
            extrap = np.nan

            # 提取前5个必要参数
            arrays = []
            for i, param in enumerate(params[:5]):
                try:
                    if isinstance(param, list):
                        arr = np.array(param, dtype=float)
                    elif param.is_number:
                        arr = np.array([float(param)])
                    else:
                        try:
                            arr = np.array([float(param.evalf())])
                        except:
                            raise ValueError(f"无法转换符号表达式: {param}")
                    arrays.append(arr.squeeze())  # 去除单一维度
                except Exception as e:
                    if i < 3:
                        raise ValueError(f"参数 {i + 1} 转换失败: {str(e)}")
                    else:
                        # 查询点可能是单个数值
                        arrays.append(np.array([float(param.evalf())]))

            # 分配参数
            X, Y, V, Xq, Yq = arrays[:5]

            # ------------------------- 参数验证 -------------------------
            # 验证网格结构
            if X.ndim != 1 or Y.ndim != 1:
                raise ValueError("X 和 Y 必须是一维数组")
            # 检查单调性
            if not (np.all(np.diff(X) > 0) and np.all(np.diff(Y) > 0)):
                raise ValueError("X 和 Y 必须是严格单调递增的")

            # 验证 V 的维度
            expected_shape = (len(Y), len(X))  # MATLAB 的 meshgrid 是 (Y,X) 顺序
            if V.shape != expected_shape:
                raise ValueError(f"V 的维度应为 {expected_shape},实际为 {V.shape}")

            # ------------------------- 处理方法参数 -------------------------
            scipy_method = 'linear'
            if len(params) >= 6:
                scipy_method = str(params[5])

            # ------------------------- 处理外推参数 -------------------------
            if len(params) >= 7:
                try:
                    extrap = float(params[6])
                except:
                    raise ValueError("无效的外推值")

            # ------------------------- 创建插值器 -------------------------
            # 使用 RegularGridInterpolator (适用于规则网格)
            interpolator = RegularGridInterpolator(
                (Y, X),  # 注意顺序:MATLAB 是 (X,Y),但 SciPy 是 (Y,X)
                V,
                method=scipy_method,
                bounds_error=False,
                fill_value=extrap
            )

            # ------------------------- 准备查询点 -------------------------
            # 生成网格点坐标 (兼容标量输入)
            Xq_mesh, Yq_mesh = np.meshgrid(Xq, Yq)
            query_points = np.column_stack((Yq_mesh.ravel(), Xq_mesh.ravel()))

            # ------------------------- 执行插值 -------------------------
            Vq = interpolator(query_points)
            Vq = Vq.reshape(Xq_mesh.shape)

            return Vq

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


    # 示例使用 ---------------------------------------------------
    if __name__ == "__main__":
        # 测试案例1:外推值设置
        input_str = "[0,1],[0,1],[[1,2],[3,4]],[0.5,2],[0.5,1],linear,0"
        result = interpolation_two_dimensional(re.sub(r"\s+", "", input_str))
        print("测试1结果:", result)
        # [[2.5 0. ]
        #  [3.5 0. ]]
    
    
    meshgrid格式的三维网格数据的插值

    Vq = interp3(X,Y,Z,V,Xq,Yq,Zq) 使用线性插值返回三变量函数在特定查询点的插值。结果始终穿过函数的原始采样。X、Y 和 Z 包含样本点的坐标。V 包含各样本点处的对应函数值。Xq、Yq 和 Zq 包含查询点的坐标。

    Vq = interp3(___,method) 指定备选插值方法:'linear'、'nearest'、'cubic'、'makima' 或 'spline'。默认方法为 'linear'。

    Vq = interp3(___,method,extrapval) 还指定标量值 extrapval,此参数会为处于样本点域范围外的所有查询点赋予该标量值。

    X,Y,Z — 样本网格点, 数组 | 向量

    V — 样本值, 数组

    Xq,Yq,Zq — 查询点, 标量 | 向量

    k — 细化因子, 1 (默认) | 非负实整数标量

    method — 插值方法, 'linear' (默认) | 'nearest'

    extrapval — X、Y 和 Z 域范围外的函数值, 标量

    示例1. 三维数据外推处理

    创建有限区域的数据
    x_limited = np.array([10, 20, 30, 40, 50])
    y_limited = np.array([10, 20, 30, 40])
    z_limited = np.array([5, 10, 15, 20, 25])

    X_lim, Y_lim, Z_lim = np.meshgrid(x_limited, y_limited, z_limited, indexing='ij')

    模拟数据(中心有高值)
    V_limited = 100 * np.exp(-((X_lim - 30) ** 2 / 100 + (Y_lim - 25) ** 2 / 80 + (Z_lim - 15) ** 2 / 50))

    查询点(包含数据范围外的点)
    xq_ext = np.array([0, 25, 50, 75])  # 0和75在范围外
    yq_ext = np.array([0, 20, 40, 60])  # 0和60在范围外
    zq_ext = np.array([0, 12.5, 25, 35])  # 0和35在范围外

    无外推(默认NaN)
    Vq_no_extrap = interp3(x_limited, y_limited, z_limited, V_limited, xq_ext, yq_ext, zq_ext, linear)

    使用常数外推
    Vq_with_extrap = interp3(x_limited, y_limited, z_limited, V_limited, xq_ext, yq_ext, zq_ext, linear, 0)

    nan_count_no_extrap = np.sum(np.isnan(Vq_no_extrap))
    nan_count_with_extrap = np.sum(np.isnan(Vq_with_extrap))

    print(f"无外推时的NaN数量: {nan_count_no_extrap}")
    print(f"有外推时的NaN数量: {nan_count_with_extrap}")
    print(f"外推值设置: 0 (在数据范围外)")
    #无外推时的NaN数量: 56
    #有外推时的NaN数量: 0
    #外推值设置: 0 (在数据范围外)

    示例2:数据重采样(改变网格分辨率)

    原始低分辨率数据
    x_low = np.array([0, 10, 20, 30, 40])
    y_low = np.array([0, 8, 16, 24, 32])
    z_low = np.array([0, 5, 10, 15, 20])

    X_low, Y_low, Z_low = np.meshgrid(x_low, y_low, z_low, indexing='ij')

    模拟物理场数据
    V_low = 50 + 20 * np.sin(X_low / 5) * np.cos(Y_low / 4) * np.sin(Z_low / 3)

    高分辨率查询网格
    xq_high = np.linspace(0, 40, 20)
    yq_high = np.linspace(0, 32, 16)
    zq_high = np.linspace(0, 20, 12)

    Vq_high = interp3(x_low, y_low, z_low, V_low, xq_high, yq_high, zq_high, linear)

    print(f"原始数据分辨率: {V_low.shape}")
    print(f"重采样后分辨率: {Vq_high.shape}")
    print(f"分辨率提升倍数: {Vq_high.size / V_low.size:.1f}x")

    可视化重采样效果
    fig, axes = plt.subplots(1, 2, figsize=(12, 5))

    # 低分辨率数据的一个切片
    z_low_idx = len(z_low) // 2
    im1 = axes[0].imshow(V_low[:, :, z_low_idx].T, cmap='coolwarm',
                         extent=[x_low[0], x_low[-1], y_low[0], y_low[-1]],
                         origin='lower', interpolation='nearest')
    axes[0].set_title('低分辨率原始数据')
    axes[0].set_xlabel('X')
    axes[0].set_ylabel('Y')
    plt.colorbar(im1, ax=axes[0])

    高分辨率插值的一个切片
    Xq_high, Yq_high, Zq_high = np.meshgrid(xq_high, yq_high, zq_high, indexing='ij')
    z_high_idx = len(zq_high) // 2
    im2 = axes[1].imshow(Vq_high[:, :, z_high_idx].T, cmap='coolwarm',
                         extent=[xq_high[0], xq_high[-1], yq_high[0], yq_high[-1]],
                         origin='lower', interpolation='bilinear')
    axes[1].set_title('高分辨率插值结果')
    axes[1].set_xlabel('X')
    axes[1].set_ylabel('Y')
    plt.colorbar(im2, ax=axes[1])

    plt.tight_layout()
    plt.show()
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import sympy as sp
    from scipy.interpolate import RegularGridInterpolator


    def parse_3d_array(param):
        """递归将 SymPy 嵌套结构转换为三维 numpy 数组"""
        if isinstance(param, (sp.Tuple, list, tuple)):
            return np.array([parse_3d_array(e) for e in param], dtype=float)
        elif param.is_Number:
            return float(param.evalf())
        else:
            raise ValueError("无法解析的三维数组元素")


    def interpolation_three_dimensional(input_str):
        """
        对标 MATLAB 的 interp3 函数,实现三维网格数据插值

        参数:
        input_str: 输入参数字符串,支持以下格式:
                   "X, Y, Z, V, Xq, Yq, Zq"            -> 基本插值(默认线性)
                   "X, Y, Z, V, Xq, Yq, Zq, method"    -> 指定插值方法
                   "X, Y, Z, V, Xq, Yq, Zq, method, extrap" -> 指定方法和外推值

        返回:
          插值结果数组,错误时返回错误信息字符串

        示例:
        >>> interpolation_three_dimensional("[0,1], [0,1], [0,1], [[[1,2],[3,4]],[[5,6],[7,8]]], 0.5, 0.5, 0.5")
        array(4.5)
        """
        try:
            import re
            # ------------------------- 输入解析 -------------------------
            # 移除注释内容(#之后的所有字符)
            cleaned_str = re.sub(r'#.*', '', input_str)
            expr = sp.sympify(cleaned_str, evaluate=False)
            params = list(expr) if isinstance(expr, tuple) else [expr]
            valid_methods = {'linear', 'nearest'}

            # 初始化参数
            X, Y, Z, V, Xq, Yq, Zq = None, None, None, None, None, None, None
            extrap = np.nan
            method = 'linear'

            # 解析前7个参数
            arrays = []
            for i, param in enumerate(params[:7]):
                if i == 3:  # 处理三维数组 V
                    try:
                        if isinstance(param, (sp.Tuple, list, tuple)):
                            arr = parse_3d_array(param)
                        else:
                            raise ValueError("V 必须是三维数组")
                        arrays.append(arr)
                    except Exception as e:
                        raise ValueError(f"参数4 (V) 转换失败: {str(e)}")
                else:  # 处理其他参数
                    try:
                        if isinstance(param, list):
                            arr = np.array(param, dtype=float).squeeze()
                        elif param.is_Number:
                            arr = np.array([float(param.evalf())])
                        else:
                            arr = np.array([float(param.evalf())])
                        arrays.append(arr.squeeze())
                    except Exception as e:
                        raise ValueError(f"参数 {i + 1} 转换失败: {str(e)}")

            X, Y, Z, V, Xq, Yq, Zq = arrays[:7]

            # ------------------------- 参数验证 -------------------------
            # 验证一维数组
            for arr, name in zip([X, Y, Z], ['X', 'Y', 'Z']):
                if arr.ndim != 1:
                    raise ValueError(f"{name} 必须是一维数组")

            # 验证严格单调递增
            for arr, name in zip([X, Y, Z], ['X', 'Y', 'Z']):
                if not np.all(np.diff(arr) > 0):
                    raise ValueError(f"{name} 必须是严格单调递增的")

            # 验证 V 的维度
            expected_shape = (len(Z), len(Y), len(X))
            if V.shape != expected_shape:
                raise ValueError(f"V 的维度应为 {expected_shape},实际为 {V.shape}")

            # ------------------------- 处理可选参数 -------------------------
            if len(params) >= 8:
                method = str(params[7])
                if method not in valid_methods:
                    raise ValueError(f"无效的插值方法: {method},支持的方法: {valid_methods}")

            if len(params) >= 9:
                try:
                    extrap = float(params[8])
                except:
                    raise ValueError("无效的外推值")

            # ------------------------- 创建插值器 -------------------------
            interpolator = RegularGridInterpolator(
                (Z, Y, X),  # 注意坐标顺序
                V,
                method=method,
                bounds_error=False,
                fill_value=extrap
            )

            # ------------------------- 生成查询点 -------------------------
            # 创建三维网格坐标
            Zq_mesh, Yq_mesh, Xq_mesh = np.meshgrid(Zq, Yq, Xq, indexing='ij')
            query_points = np.column_stack((
                Zq_mesh.ravel(),
                Yq_mesh.ravel(),
                Xq_mesh.ravel()
            ))

            # ------------------------- 执行插值 -------------------------
            Vq = interpolator(query_points)
            Vq = Vq.reshape(Zq_mesh.shape)

            return Vq

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


    # 测试三维线性插值
    input_str = "[0,1], [0,1], [0,1], [[[1,2],[3,4]],[[5,6],[7,8]]], 0.5, 0.5, 0.5"
    result = interpolation_three_dimensional(input_str)
    print(result)
    # [[[4.5]]]
    
    
    一维插值(FFT 方法)

    y = interpft(X,n) 在 X 中内插函数值的傅里叶变换以生成 n 个等间距的点。interpft 对第一个大小不等于 1 的维度进行运算。

    y = interpft(X,n,dim) 沿维度 dim 运算。例如,如果 X 是矩阵,interpft(X,n,2) 将在 X 行上进行运算。

    X — 输入数组, 向量 | 矩阵

    n — 点的数目, 正整数标量

    dim — 沿其运算的维度, 正整数标量

    y — 插入的点, 向量 | 矩阵

    import matplotlib.pyplot as plt

    示例1:信号处理 - 周期信号插值

    创建原始周期信号(采样率较低)
    t_original = np.linspace(0, 2 * np.pi, 16, endpoint=False)
    signal_original = np.sin(t_original) + 0.5 * np.cos(2 * t_original)

    使用FFT插值增加采样点
    n_interp = 64
    input_str = f"{signal_original.tolist()}, {n_interp}"
    signal_interp = interpft(input_str)

    生成插值后的时间轴
    t_interp = np.linspace(0, 2 * np.pi, n_interp, endpoint=False)

    真实信号(用于比较)
    t_true = np.linspace(0, 2 * np.pi, 200)
    signal_true = np.sin(t_true) + 0.5 * np.cos(2 * t_true)

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

    plt.subplot(2, 3, 1)
    plt.plot(t_original, signal_original, 'ro-', label='原始采样点', markersize=6)
    plt.plot(t_interp, signal_interp, 'b-', label='FFT插值', alpha=0.7)
    plt.plot(t_true, signal_true, 'g--', label='真实信号', alpha=0.5)
    plt.title('周期信号FFT插值')
    plt.xlabel('时间')
    plt.ylabel('幅度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    示例2:音频处理 - 音频信号重采样

    模拟音频信号(低频正弦波叠加高频成分)
    fs_original = 1000  # 原始采样率 1kHz
    t_audio = np.linspace(0, 1, fs_original, endpoint=False)
    audio_original = 0.8 * np.sin(2 * np.pi * 100 * t_audio) + 0.3 * np.sin(2 * np.pi * 300 * t_audio)

    降采样(模拟低采样率情况)
    downsample_factor = 4
    audio_low_rate = audio_original[::downsample_factor]

    使用FFT插值恢复到原始采样率
    n_audio_interp = fs_original
    audio_interp = interpft(audio_low_rate, n_audio_interp)

    t_low_rate = np.linspace(0, 1, len(audio_low_rate), endpoint=False)
    t_interp_audio = np.linspace(0, 1, n_audio_interp, endpoint=False)

    plt.subplot(2, 3, 2)
    plt.plot(t_audio, audio_original, 'g-', label='原始音频', alpha=0.7)
    plt.plot(t_low_rate, audio_low_rate, 'ro', label='低采样率点', markersize=4)
    plt.plot(t_interp_audio, audio_interp, 'b-', label='FFT插值', alpha=0.7)
    plt.title('音频信号重采样')
    plt.xlabel('时间 (s)')
    plt.ylabel('幅度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    频域分析
    plt.subplot(2, 3, 3)
    freqs_orig = fftfreq(len(audio_original), 1 / fs_original)
    freqs_interp = fftfreq(len(audio_interp), 1 / fs_original)

    fft_orig = np.abs(fft(audio_original))[:len(freqs_orig) // 2]
    fft_interp = np.abs(fft(audio_interp))[:len(freqs_interp) // 2]

    plt.plot(freqs_orig[:len(freqs_orig) // 2], fft_orig, 'g-', label='原始频谱', alpha=0.7)
    plt.plot(freqs_interp[:len(freqs_interp) // 2], fft_interp, 'b-', label='插值后频谱', alpha=0.7)
    plt.title('频域比较')
    plt.xlabel('频率 (Hz)')
    plt.ylabel('幅度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    示例3:地震信号处理

    模拟地震信号(包含多个频率成分)
    t_seismic = np.linspace(0, 10, 50)  # 稀疏采样

    主震频率 + 余震频率 + 噪声
    seismic_original = (2.0 * np.exp(-0.5 * t_seismic) * np.sin(2 * np.pi * 2 * t_seismic) +
                        0.5 * np.exp(-0.2 * t_seismic) * np.sin(2 * np.pi * 5 * t_seismic) +
                        0.1 * np.random.normal(0, 0.1, len(t_seismic)))

    FFT插值到更高分辨率
    n_seismic_interp = 200
    seismic_interp = interpft(seismic_original, n_seismic_interp)

    t_seismic_interp = np.linspace(0, 10, n_seismic_interp)

    plt.subplot(2, 3, 4)
    plt.plot(t_seismic, seismic_original, 'ro-', label='原始地震数据', markersize=4)
    plt.plot(t_seismic_interp, seismic_interp, 'b-', label='FFT插值', alpha=0.8)
    plt.title('地震信号插值')
    plt.xlabel('时间 (s)')
    plt.ylabel('振幅')
    plt.legend()
    plt.grid(True, alpha=0.3)

    示例4:心电图(ECG)信号处理

    模拟ECG信号(QRS复合波)
    t_ecg_original = np.linspace(0, 2, 40)  # 低采样率ECG
    ecg_original = (
            0.5 * np.exp(-((t_ecg_original - 0.2) * 10) ** 2) +  # P波
            1.2 * np.exp(-((t_ecg_original - 0.3) * 8) ** 2) -  # QRS复合波
            0.3 * np.exp(-((t_ecg_original - 0.4) * 6) ** 2) +  # T波
            0.1 * np.random.normal(0, 0.05, len(t_ecg_original))  # 噪声
    )

    FFT插值到医疗标准采样率
    n_ecg_interp = 200  # 相当于100Hz采样率
    ecg_interp = interpft(ecg_original, n_ecg_interp)

    t_ecg_interp = np.linspace(0, 2, n_ecg_interp)

    plt.subplot(2, 3, 5)
    plt.plot(t_ecg_original, ecg_original, 'ro-', label='原始ECG', markersize=4)
    plt.plot(t_ecg_interp, ecg_interp, 'b-', label='FFT插值ECG', alpha=0.8)
    plt.title('心电图信号插值')
    plt.xlabel('时间 (s)')
    plt.ylabel('电压 (mV)')
    plt.legend()
    plt.grid(True, alpha=0.3)

    示例5:天文观测数据插值

    模拟恒星亮度观测数据(由于天气原因采样不均匀)
    t_astro_original = np.array([0, 1, 3, 4, 6, 8, 9, 11, 13, 15])  # 不均匀时间点

    模拟食双星的光变曲线
    brightness_original = 1.0 - 0.3 * np.exp(-((t_astro_original % 5 - 2.5) ** 2) / 0.5)

    由于时间点不均匀,需要先插值到均匀网格
    t_uniform = np.linspace(0, 15, 16)  # 均匀时间网格
    brightness_uniform = np.interp(t_uniform, t_astro_original, brightness_original)

    使用FFT进一步插值到更高分辨率
    n_astro_interp = 100
    brightness_interp = interpft(brightness_uniform, n_astro_interp)

    t_astro_interp = np.linspace(0, 15, n_astro_interp)

    plt.subplot(2, 3, 6)
    plt.plot(t_astro_original, brightness_original, 'ro', label='原始观测', markersize=6)
    plt.plot(t_astro_interp, brightness_interp, 'b-', label='FFT插值', alpha=0.8)
    plt.title('恒星亮度变化插值')
    plt.xlabel('时间 (小时)')
    plt.ylabel('相对亮度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    示例6: 包含多个频率成分

    t_original = np.linspace(0, 4 * np.pi, 32)
    test_signal = (np.sin(t_original) +
                   0.5 * np.sin(3 * t_original) +
                   0.2 * np.sin(7 * t_original))

    插值到更高分辨率
    n_interp = 128

    FFT插值
    signal_fft = interpft(test_signal, n_interp)

    线性插值
    t_interp = np.linspace(0, 4 * np.pi, n_interp)
    signal_linear = np.interp(t_interp, t_original, test_signal)

    真实信号(用于误差计算)
    t_true = np.linspace(0, 4 * np.pi, 200)
    signal_true = np.sin(t_true) + 0.5 * np.sin(3 * t_true) + 0.2 * np.sin(7 * t_true)

    计算误差
    signal_fft_true = np.interp(t_true, t_interp, signal_fft)
    signal_linear_true = np.interp(t_true, t_interp, signal_linear)

    error_fft = np.sqrt(np.mean((signal_fft_true - signal_true) ** 2))
    error_linear = np.sqrt(np.mean((signal_linear_true - signal_true) ** 2))

    可视化比较
    plt.figure(figsize=(12, 8))

    plt.subplot(2, 2, 1)
    plt.plot(t_original, test_signal, 'ro-', label='原始信号', markersize=4)
    plt.plot(t_interp, signal_fft, 'b-', label='FFT插值', alpha=0.7)
    plt.plot(t_true, signal_true, 'g--', label='真实信号', alpha=0.5)
    plt.title(f'FFT插值 (RMSE: {error_fft:.4f})')
    plt.xlabel('时间')
    plt.ylabel('幅度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    plt.subplot(2, 2, 2)
    plt.plot(t_original, test_signal, 'ro-', label='原始信号', markersize=4)
    plt.plot(t_interp, signal_linear, 'orange', label='线性插值', alpha=0.7)
    plt.plot(t_true, signal_true, 'g--', label='真实信号', alpha=0.5)
    plt.title(f'线性插值 (RMSE: {error_linear:.4f})')
    plt.xlabel('时间')
    plt.ylabel('幅度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    频域比较
    plt.subplot(2, 2, 3)
    freqs_orig = fftfreq(len(test_signal), 1 / 32)[:16]
    freqs_fft = fftfreq(len(signal_fft), 1 / 128)[:64]
    freqs_linear = fftfreq(len(signal_linear), 1 / 128)[:64]

    fft_orig = np.abs(fft(test_signal))[:16]
    fft_fft = np.abs(fft(signal_fft))[:64]
    fft_linear = np.abs(fft(signal_linear))[:64]

    plt.plot(freqs_orig, fft_orig, 'ro-', label='原始频谱', markersize=4)
    plt.plot(freqs_fft, fft_fft, 'b-', label='FFT插值频谱', alpha=0.7)
    plt.plot(freqs_linear, fft_linear, 'orange', label='线性插值频谱', alpha=0.7)
    plt.title('频域特性比较')
    plt.xlabel('频率')
    plt.ylabel('幅度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    误差比较
    plt.subplot(2, 2, 4)
    methods = ['FFT插值', '线性插值']
    errors = [error_fft, error_linear]
    colors = ['blue', 'orange']

    bars = plt.bar(methods, errors, color=colors, alpha=0.7)
    plt.title('插值方法误差比较')
    plt.ylabel('均方根误差 (RMSE)')

    添加数值标签
    for bar, error in zip(bars, errors):
        plt.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 0.001,
                 f'{error:.4f}', ha='center', va='bottom')

    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    print(f"FFT插值误差: {error_fft:.6f}")
    print(f"线性插值误差: {error_linear:.6f}")
    print(f"FFT插值相对于线性插值的改进: {(error_linear - error_fft) / error_linear * 100:.1f}%")
    #FFT插值误差: 0.271828
    #线性插值误差: 0.099717
    #FFT插值相对于线性插值的改进: -172.6%

    示例7:信号压缩和重建

    原始高分辨率信号
    t_high_res = np.linspace(0, 2 * np.pi, 128)
    signal_high_res = np.sin(t_high_res) + 0.3 * np.sin(5 * t_high_res)

    压缩:降采样
    compression_ratio = 4
    signal_compressed = signal_high_res[::compression_ratio]

    重建:使用FFT插值恢复到原始分辨率
    signal_reconstructed = interpft(signal_compressed, signal_high_res)

    t_compressed = t_high_res[::compression_ratio]

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

    plt.subplot(1, 2, 1)
    plt.plot(t_high_res, signal_high_res, 'g-', label='原始信号', alpha=0.7)
    plt.plot(t_compressed, signal_compressed, 'ro', label='压缩后采样点', markersize=4)
    plt.plot(t_high_res, signal_reconstructed, 'b-', label='FFT重建', alpha=0.7)
    plt.title('信号压缩和FFT重建')
    plt.xlabel('时间')
    plt.ylabel('幅度')
    plt.legend()
    plt.grid(True, alpha=0.3)

    计算重建误差
    reconstruction_error = np.sqrt(np.mean((signal_reconstructed - signal_high_res) ** 2))
    compression_ratio_value = len(signal_high_res) / len(signal_compressed)

    plt.subplot(1, 2, 2)
    plt.plot(t_high_res, signal_reconstructed - signal_high_res, 'r-')
    plt.title(f'重建误差 (RMSE: {reconstruction_error:.4f})')
    plt.xlabel('时间')
    plt.ylabel('误差')
    plt.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()

    print(f"压缩比: {compression_ratio_value}:1")
    print(f"重建误差: {reconstruction_error:.6f}")
    #压缩比: 4.0:1
    #重建误差: 0.011341

    示例8:多通道信号处理

    模拟多通道生物信号(如EEG)
    n_channels = 3
    t_multi = np.linspace(0, 1, 32)

    创建不同通道的信号
    multi_channel_signals = []
    for i in range(n_channels):
        freq = 10 + i * 5  # 每个通道不同频率
        signal = np.sin(2 * np.pi * freq * t_multi) + 0.2 * np.random.normal(0, 0.1, len(t_multi))
        multi_channel_signals.append(signal)

    将多通道信号组合成矩阵
    multi_signal_matrix = np.column_stack(multi_channel_signals)

    对每个通道进行FFT插值
    n_multi_interp = 128
    multi_signal_interp = interpft(multi_signal_matrix, n_multi_interp, 1)  # 按列插值

    t_multi_interp = np.linspace(0, 1, n_multi_interp)

    plt.figure(figsize=(12, 8))
    for i in range(n_channels):
        plt.subplot(n_channels, 1, i + 1)
        plt.plot(t_multi, multi_channel_signals[i], 'ro-', markersize=2, label=f'通道{i + 1}原始')
        plt.plot(t_multi_interp, multi_signal_interp[:, i], 'b-', alpha=0.7, label=f'通道{i + 1}插值')
        plt.ylabel(f'通道{i + 1}')
        plt.legend()
        plt.grid(True, alpha=0.3)

    plt.xlabel('时间 (s)')
    plt.suptitle('多通道信号同步FFT插值')
    plt.tight_layout()
    plt.show()
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    from scipy.fft import fft, ifft
    import sympy as sp


    def interpolation_fft(input_str):
        """
        实现类似于 MATLAB 的 interpft 函数,通过 FFT 方法进行一维插值。

        参数:
        x (array-like): 输入信号(实数或复数)。
        n (int): 插值后的信号长度,必须大于原信号长度。

        返回:
        ndarray: 插值后的实数信号(虚部被丢弃)。

        异常:
        ValueError: 如果 n 小于原信号长度。

        示例:
        >>> import numpy as np
        >>> x = np.array([1, -1, 1, -1])
        >>> interpft(x, 6)
        array([ 1. , -0.5, -0.5, 1. , -0.5, -0.5])
        """
        try:
            # 将输入的字符串转换为 SymPy 表达式
            expr = sp.sympify(input_str)
            # 标记是否出现错误
            error = False
            # 存储插值结果
            result = None

            def interpft_single(x, n):
                """
                对一维数组进行插值的辅助函数
                """
                # 获取输入信号的长度
                m = len(x)
                # 检查插值后的长度是否小于原信号长度
                if n < m:
                    raise ValueError("插值后的长度 n 不能小于输入信号的长度。")
                # 对输入信号进行快速傅里叶变换
                X = fft(x)
                if m % 2 == 0:
                    # 若原信号长度为偶数
                    # 计算中间位置
                    mid = m // 2
                    # 在频域中间插入零以进行插值
                    X_new = np.concatenate((X[:mid], np.zeros(n - m, dtype=X.dtype), X[mid:]))
                else:
                    # 若原信号长度为奇数
                    # 计算中间位置
                    mid = (m + 1) // 2
                    # 在频域中间插入零以进行插值
                    X_new = np.concatenate((X[:mid], np.zeros(n - m, dtype=X.dtype), X[mid:]))
                # 对零填充后的频域信号进行逆快速傅里叶变换
                y = ifft(X_new) * (n / m)
                # 返回插值后的实数信号(丢弃虚部)
                return y.real

            if isinstance(expr, tuple) and isinstance(expr[0], list):
                if len(expr) == 3:
                    # 输入包含信号、插值后的长度和维度信息
                    matrix = sp.Matrix(expr[0])
                    n = int(expr[1])
                    dim = int(expr[2])
                elif len(expr) == 2:
                    # 输入包含信号和插值后的长度,默认维度为 0
                    matrix = sp.Matrix(expr[0])
                    n = int(expr[1])
                    dim = 0
                else:
                    # 输入的元组长度不符合要求,标记错误
                    error = True

                if matrix is not None:
                    if matrix.shape[1] == 1:
                        # 如果矩阵是单列矩阵,将其展平为一维数组
                        x_np = np.array(matrix, dtype=float).ravel()
                    else:
                        # 否则,将矩阵转换为 NumPy 数组
                        x_np = np.array(matrix, dtype=float)
                else:
                    # 输入不是有效的矩阵,标记错误
                    error = True

                if dim == 0:
                    # 按整体进行插值
                    result = interpft_single(x_np, n)
                elif dim == 1:
                    if x_np.ndim == 2:
                        # 按列进行插值
                        result = []
                        for col in x_np.T:
                            result.append(interpft_single(col, n))
                        result = np.array(result).T
                    else:
                        # 如果输入不是二维矩阵,按整体进行插值
                        result = interpft_single(x_np, n)
                elif dim == 2:
                    if x_np.ndim == 2:
                        # 按行进行插值
                        result = []
                        for row in x_np:
                            result.append(interpft_single(row, n))
                        result = np.array(result)
                    else:
                        # 如果输入不是二维矩阵,按整体进行插值
                        result = interpft_single(x_np, n)
                else:
                    # 输入的维度信息无效,标记错误
                    error = True
            else:
                # 输入不是元组,标记错误
                error = True

            return result if not error else f"输入错误: {input_str}"
        except Exception as e:
            return f"错误: {str(e)}"  # 请增加注释


    # 示例测试
    if __name__ == "__main__":
        # 示例1:偶数长度插值
        x = [1, -1, 1, -1]
        n = 6
        y = interpolation_fft(f"{x}, {n}")
        print(y)
        # [ 1.  -0.5 -0.5  1.  -0.5 -0.5]

        # 示例2:奇数长度插值
        x = [1, 0, -1]
        n = 5
        y = interpolation_fft(f"{x}, {n}")
        print(y)
        # [ 1.          0.85810973 -0.46965902 -1.14837497 -0.24007574]
    
    
    ndgrid格式的一维二维三维和N维网格数据的插值

    Vq = interpn(X1,X2,...,Xn,V,Xq1,Xq2,...,Xqn) 使用线性插值返回 n 变量函数在特定查询点的插入值。结果始终穿过函数的原始采样。

    X1,X2,...,Xn 包含样本点的坐标。V 包含各样本点处的对应函数值。Xq1,Xq2,...,Xqn 包含查询点的坐标。

    示例1: 二维温度场插值

    模拟一个温度场:x方向[0,10]米,y方向[0,8]米

    已知网格点温度值
    result1 = interpn([0,2,4,6,8,10],
                      [0,2,4,6,8],
                      [[25,26,27,28,29],
                       [24,25,26,27,28],
                       [23,24,25,26,27],
                       [22,23,24,25,26],
                       [21,22,23,24,25],
                       [20,21,22,23,24]], 3.5, 4.2)
    print(f"位置(3.5, 4.2)的温度: {result1}°C")
    #位置(3.5, 4.2)的温度: (6, 5)°C

    示例2: 三维流体速度场

    V是速度大小在三维网格上的分布
    result2 = interpn([0,1,2],[0,1,2],[0,1,2],
                      [[[1.0,1.2,1.5],[1.1,1.3,1.6],[1.2,1.4,1.7]],
                       [[1.3,1.5,1.8],[1.4,1.6,1.9],[1.5,1.7,2.0]],
                       [[1.6,1.8,2.1],[1.7,1.9,2.2],[1.8,2.0,2.3]]],1.5, 1.5, 1.5)
    print(f"位置(1.5,1.5,1.5)的速度: {result2} m/s")
    #位置(1.5,1.5,1.5)的速度: [[[1.95]]] m/s

    示例3: 地形高度插值(最近邻方法)

    使用最近邻插值获取地形高度
    result3 = interpn([0,100,200,300],[0,100,200],
                      [[100,105,110],
                       [120,125,130],
                       [115,120,125],
                       [110,115,120]],150,80,nearest)
    print(f"位置(150,80)的地形高度(最近邻): {result3}米")
    #位置(150,80)的地形高度(最近邻): (4, 3)米

    示例4: 一维信号插值

    一维信号在时间点上的采样值
    result5 = interpn([0,1,2,3,4,5], [0,2,4,6,8,10], 2.7)
    print(f"时间t=2.7时的信号值: {result5}")
    #时间t=2.7时的信号值: [5.4]

    示例5: 批量查询多个点

    同时查询多个位置的插值结果
    result7 = interpn([0,1,2],[0,1,2],
                      [[1,4,7],
                       [2,5,8],
                       [3,6,9]],
                       [0.5,1.5],[0.5,1.5])
    print(f"多个查询点的结果:\n{result7}")
    #多个查询点的结果:
    #[[3,4]
      [6,7]]

    示例6: 四维数据插值(颜色+透明度)

    result8 = interpn([0,1], [0,1], [0,1], [0,1],
                      [[[[0.1,0.2],[0.3,0.4]],[[0.5,0.6],[0.7,0.8]]],
                      [[[0.2,0.3],[0.4,0.5]],[[0.6,0.7],[0.8,0.9]]]],
                      0.3, 0.4, 0.5, 0.6)
    print(f"四维空间点(0.3,0.4,0.5,0.6)的值: {result8}")
    #四维空间点(0.3,0.4,0.5,0.6)的值: [[[[0.47]]]]
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import numpy as np
    import sympy as sp
    from scipy.interpolate import RegularGridInterpolator


    def parse_nd_array(param):
        """递归将 SymPy 嵌套结构转换为 n 维 numpy 数组"""
        if isinstance(param, (sp.Tuple, list, tuple)):
            return np.array(param, dtype=float)
        elif param.is_Number:
            return float(param.evalf())
        else:
            raise ValueError("Non-numeric element in array")


    def interpolation_nd(input_str):
        """
          对标 MATLAB 的 interpn 函数,实现 N 维网格数据插值。

          参数:
          input_str: 输入参数字符串,格式为:
                     "X1, X2, ..., Xn, V, Xq1, Xq2, ..., Xqn"               -> 默认线性插值
                     "X1, X2, ..., Xn, V, Xq1, Xq2, ..., Xqn, method"       -> 指定插值方法
                     "X1, X2, ..., Xn, V, Xq1, Xq2, ..., Xqn, method, extrap" -> 指定方法和外推值

          返回:
            插值结果数组,错误时返回错误信息字符串

          示例:
          >>> interpolation_nd("[0,1], [0,1], [[1,2],[3,4]], 0.5, 0.5")
          array(2.5)  # 二维线性插值示例
          """
        try:
            expr = sp.sympify(input_str, evaluate=False)
            params = list(expr) if isinstance(expr, tuple) else [expr]
            valid_methods = {'linear', 'nearest'}

            m = len(params)
            if m < 3:
                raise ValueError("参数数量不足")

            n = (m - 1) // 2
            if 2 * n + 1 > m or m > 2 * n + 3:
                raise ValueError(f"参数数量不匹配: m={m}, n={n}")

            # 解析坐标轴
            coords_axes = []
            for i in range(n):
                param = params[i]
                matrix = sp.Matrix(param) if isinstance(param, list) else None

                if matrix is not None:
                    arr = np.array(matrix, dtype=float).squeeze()
                elif param.is_Number:
                    arr = np.array([float(param.evalf())])
                else:
                    try:
                        arr = np.array([float(param.evalf())])
                    except:
                        raise ValueError(f"第 {i + 1} 个参数转换失败")
                if arr.ndim != 1:
                    raise ValueError(f"X{i + 1} 必须是一维数组")
                if not np.all(np.diff(arr) > 0):
                    raise ValueError(f"X{i + 1} 必须是严格递增的")
                coords_axes.append(arr)

            # 反转坐标轴以适应 scipy 的坐标顺序
            reversed_coords = list(reversed(coords_axes))
            expected_shape = tuple(len(ax) for ax in reversed_coords)

            # 解析 V 矩阵
            v_param = params[n]

            try:
                if isinstance(v_param, (sp.Tuple, list, tuple)):
                    V = parse_nd_array(v_param)
                else:
                    raise ValueError("V 必须是多维数组")

                if V.ndim != n:
                    raise ValueError(f"V 必须是 {n} 维,实际为 {V.ndim} 维")

                if V.shape != expected_shape:
                    raise ValueError(f"V 形状不匹配: 期望 {expected_shape},实际为 {V.shape}")

            except Exception as e:
                raise ValueError(f"V 解析失败: {str(e)}")

            # 解析查询点
            Xqs = []
            for i in range(n):
                param = params[n + 1 + i]
                matrix = sp.Matrix(param) if isinstance(param, list) else None

                if matrix is not None:
                    arr = np.array(matrix, dtype=float).squeeze()
                elif param.is_Number:
                    arr = np.array([float(param.evalf())])
                else:
                    try:
                        arr = np.array([float(param.evalf())])
                    except:
                        raise ValueError(f"Xq{i + 1} 转换失败")
                Xqs.append(arr)

            # 处理可选参数
            method = 'linear'
            extrap = np.nan
            if m >= 2 * n + 2:
                method = str(params[2 * n + 1])
                if method not in valid_methods:
                    raise ValueError(f"无效的插值方法: {method}")
            if m >= 2 * n + 3:
                try:
                    extrap = float(params[2 * n + 2])
                except:
                    raise ValueError("无效的外推值")

            # 创建插值器
            interpolator = RegularGridInterpolator(
                reversed_coords,
                V,
                method=method,
                bounds_error=False,
                fill_value=extrap
            )

            # 生成查询网格
            Xqs_reversed = list(reversed(Xqs))
            mesh_arrays = np.meshgrid(*Xqs_reversed, indexing='ij')
            query_points = np.column_stack([arr.ravel() for arr in mesh_arrays])

            # 进行插值
            Vq = interpolator(query_points)
            Vq = Vq.reshape(mesh_arrays[0].shape)

            # 转置以匹配原始查询点顺序
            if n > 1:
                Vq = np.transpose(Vq, axes=tuple(reversed(range(n))))

            return Vq

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


    result = interpolation_nd("[0,1], [0,1], [[1,2],[3,4]], 0.5, 0.5")
    print(result)
    # [[2.5]]

    result = interpolation_nd("[0,1], [0,1], [0,1], [[[1,2],[3,4]],[[5,6],[7,8]]], 0.5, 0.5, 0.5")
    print(result)
    # [[[4.5]]]
    
    
    矩阵求逆

    Y = inv(X) 计算方阵 X 的逆矩阵

    Y = inv(X,method) 按method方法分解矩阵,计算方阵X的逆矩阵.

    X^(-1) 等效于 inv(X)

    X — 输入矩阵,方阵.

    method - 'GE', 'LU', 'ADJ', 'CH', 'LDL'

    GE - 使用高斯消去法求逆.

    LU - 使用LU分解计算求逆.

    ADJ - 使用辅助矩阵和行列式求逆.

    CH - 使用cholesky分解求逆.

    LDL - 使用LDL分解求逆.

    如果X是密集矩阵,默认method是GE,如果X是稀疏矩阵,默认method是LDL

    示例1:线性方程组求解(工程应用)

    电路中的节点电压方程:
    3V₁ - V₂ = 5
    -V₁ + 2V₂ = 3

    A = [[3, -1], [-1, 2]]
    b = [5, 3]

    A_inv = inv([[3, -1], [-1, 2]])
    V = A_inv * b

    print(f"系数矩阵 A: {A}")
    print(f"逆矩阵 A⁻¹: {A_inv}")
    print(f"解向量 V = A⁻¹b: {V}")
    print(f"验证: A * V = {A * V} (应该等于 {b})")
    #系数矩阵 A:
    #[[3, -1],
      [-1, 2]]

    #逆矩阵 A⁻¹:
    #[[0.4, 0.2],
      [0.2, 0.6]]

    #解向量 V = A⁻¹b:
    #[[2.6],
      [2.8]]

    #验证: A * V = [[5], [3]]
    #应该等于 [[5], [3]]

    示例2:坐标变换(计算机图形学)

    旋转矩阵的逆等于其转置(正交矩阵性质)

    R = [[cos(theta), -sin(theta)],
        [sin(theta), cos(theta)]]

    R_inv_symbolic = R.inv()
    R_inv_numeric = inv([[0.866, -0.5], [0.5, 0.866]])  # 30度旋转

    print(f"旋转矩阵 R(θ): {R}")
    print(f"符号逆矩阵 R⁻¹(θ): {R_inv_symbolic}")
    print(f"数值逆矩阵 (θ=30°): {R_inv_numeric}")
    print(f"验证 Rᵀ = R⁻¹: {R.T.equals(R_inv_symbolic)}")
    #旋转矩阵 R(θ):
    #[[cos(theta), -sin(theta)],
      [sin(theta), cos(theta)]]
    #符号逆矩阵 R⁻¹(θ):
    #[[-sin(theta)**2/cos(theta) + 1/cos(theta), sin(theta)],
      [-sin(theta), cos(theta)]]
    #数值逆矩阵 (θ=30°):
    #[[0.866038105676650, 0.500022000968043],
      [-0.500022000968043, 0.866038105676650]]
    #验证 Rᵀ = R⁻¹: True

    示例3:最小二乘法(数据拟合)

    求解 y = ax + b 的最佳拟合参数

    数据点
    x_data = [1, 2, 3, 4, 5]
    y_data = [2.1, 3.9, 6.2, 7.8, 10.1]

    设计矩阵
    X = [[1, x] for x in x_data]
    Y = y_data

    正规方程: (XᵀX)β = XᵀY
    XTX = X.T * X
    XTY = X.T * Y

    XTX_inv = inv(XTX)
    beta = XTX_inv * XTY

    print(f"设计矩阵 X: {X}")
    print(f"XᵀX: {XTX}")
    print(f"(XᵀX)⁻¹: {XTX_inv}")
    print(f"参数估计 β = [b, a]: {beta}")
    print(f"拟合直线: y = {float(beta[1]):.3f}x + {float(beta[0]):.3f}")
    #设计矩阵 X:
    #[[1, 1],
      [1, 2],
      [1, 3],
      [1, 4],
      [1, 5]]
    #XᵀX:
    #[[5, 15],
      [15, 55]]
    #(XᵀX)⁻¹:
    #[[1.1, -0.3],
      [-0.3, 0.1]]
    #参数估计 β = [b, a]:
    #[[0.0500000000000043],
      [1.99]]
    #拟合直线: y = 1.990x + 0.050

    示例4:马尔可夫链(概率论)

    转移矩阵 P 的稳态分布 π 满足 π = πP"
    即 π(I - P) = 0,需要求 (I-P) 的伪逆

    P = [[0.7, 0.2, 0.1],
        [0.3, 0.4, 0.3],
        [0.2, 0.3, 0.5]]

    I = eye(3)
    A_markov = I - P

    对于奇异矩阵,使用广义逆
    A_inv_markov = inv(A_markov)
    print("直接求逆成功(但可能不是最佳方法)")
    #直接求逆成功(但可能不是最佳方法)

    示例5:机械系统(动力学分析)

    系统方程: Mẍ + Kx = F
    在频域: (-ω²M + K)X = F

    M = [[m1, 0], [0, m2]]  # 质量矩阵
    K = [[k1 + k2, -k2], [-k2, k2]]  # 刚度矩阵

    dynamic_matrix = -omega ** 2 * M + K

    print(f"质量矩阵 M: {M}")
    print(f"刚度矩阵 K: {K}")
    print(f"动力矩阵 -ω²M + K: {dynamic_matrix}")
    #质量矩阵 M:
    #[[m1, 0],
      [0, m2]]
    #刚度矩阵 K:
    #[[k1 + k2, -k2],
      [-k2, k2]]
    #动力矩阵 -ω²M + K:
    #[[k1 + k2 - m1*omega**2, -k2],
      [-k2, k2 - m2*omega**2]]

    数值示例
    M_num = [[2, 0], [0, 1]]
    K_num = [[3, -1], [-1, 1]]
    omega_val = 1.0
    dynamic_matrix_num = -omega_val ** 2 * M_num + K_num

    dynamic_inv = inv(dynamic_matrix_num)
    print(f"数值动力矩阵: {dynamic_matrix_num}")
    print(f"数值逆矩阵: {dynamic_inv}")
    #数值动力矩阵:
    #[[1, -1],
      [-1, 0]]
    #数值逆矩阵:
    #[[0, -1],
      [-1, -1]]

    示例6:经济学 - 投入产出分析

    (I - A)x = d,其中A是技术系数矩阵

    A_econ = [[0.2, 0.3, 0.2],
              [0.4, 0.1, 0.3],
              [0.1, 0.2, 0.1]]

    I_econ = eye(3)
    leontief_matrix = I_econ - A_econ

    leontief_inv = inv(leontief_matrix)
    demand = [100, 150, 200]  # 最终需求

    production = leontief_inv * demand

    print(f"技术系数矩阵 A: {A_econ}")
    print(f"Leontief矩阵 I-A: {leontief_matrix}")
    print(f"Leontief逆矩阵: {leontief_inv}")
    print(f"最终需求 d: {demand}")
    print(f"总产出 x = (I-A)⁻¹d: {production}")
    #技术系数矩阵 A:
    #[[0.2, 0.3, 0.2],
      [0.4, 0.1, 0.3],
      [0.1, 0.2, 0.1]]
    #Leontief矩阵 I-A:
    #[[0.8, -0.3, -0.2],
      [-0.4, 0.9, -0.3],
      [-0.1, -0.2, 0.9]]
    #Leontief逆矩阵:
    #[[1.67037861915367, 0.690423162583519, 0.601336302895323],
      [0.868596881959911, 1.55902004454343, 0.712694877505568],
      [0.378619153674833, 0.423162583518931, 1.33630289532294]]
    #最终需求 d:
    #[[100],
      [150],
      [200]]
    #总产出 x = (I-A)⁻¹d:
    #[[390.868596881960],
      [463.251670378619],
      [368.596881959911]]
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp

    def inverse_matrix(input_str):
        """
        对标MATLAB inv函数的矩阵求逆函数

        参数:
        input_str: 矩阵的字符串表示,可以是:
                   - 纯矩阵表达式(如 "[[1,2],[3,4]]")
                   - 带方法的元组(如 "(Matrix([[1,2],[3,4]]), 'LU')")

        返回:
        求逆后的矩阵(成功时)或错误信息字符串(失败时)

        支持的方法参数:
        'GE' - 高斯消元法(默认)
        'LU' - LU分解法
        'ADJ' - 伴随矩阵法
        'CH' - Cholesky分解(需矩阵正定)
        'LDL' - LDL分解(需矩阵厄米特)

        示例:
        >>> inverse_matrix("[[1, 0], [0, 1]]")
        Matrix([[1, 0], [0, 1]])
        >>> inverse_matrix("(Matrix([[1,2],[3,4]]), 'LU')")
        Matrix([[-2, 1], [3/2, -1/2]])
        """
        try:
            # 将输入字符串转换为SymPy表达式
            expr = sp.sympify(input_str)
            error = False
            result = None

            # 处理带方法参数的元组输入(如 (Matrix, 'LU'))
            if isinstance(expr, tuple) and len(expr) == 2:
                # 尝试转换第一个元素为矩阵并验证方法参数
                matrix = sp.Matrix(expr[0]) if isinstance(expr[0], list) else None
                method = str(expr[1])  # 确保方法参数为字符串

                # 验证矩阵转换是否成功和方法是否有效
                if matrix is not None and method in ['GE', 'LU', 'ADJ', 'CH', 'LDL']:
                    result = matrix.inv(method=method).evalf()
                else:
                    error = True
            # 处理普通矩阵输入
            else:
                matrix = sp.Matrix(expr) if isinstance(expr, list) else None
                if matrix is not None:
                    result = matrix.inv().evalf()  # 使用默认方法(GE)
                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(inverse_matrix("[[1, 2], [3, 4]]"))
        # Matrix([[-2.00000000000000, 1.00000000000000],
        #         [1.50000000000000, -0.500000000000000]])
    
    
    反古德曼函数

    invGudermannian(z) 返回z的逆古德曼函数。

    z — 标量

    示例1: 基本数值计算

    print(f"invGudermannian(0) = {invGudermannian(0)}")
    print(f"invGudermannian(0.5) = {invGudermannian(0.5)}")
    print(f"invGudermannian(1.0) = {invGudermannian(1.0)}")
    #inverse_gudermannian(0) = 0.0
    #inverse_gudermannian(0.5) = 0.5222381032784403
    #inverse_gudermannian(1.0) = 1.2261911708835171

    示例2: 符号计算

    print(f"invGudermannian('y') = {invGudermannian(y)}")
    print(f"invGudermannian('theta') = {invGudermannian(theta)}")
    inverse_gudermannian('y') = asinh(tan(y))
    inverse_gudermannian('theta') = asinh(tan(theta))

    示例3: 地图投影应用(墨卡托投影)

    在墨卡托投影中,纬度 φ 与投影坐标 y 的关系:
    y = gd⁻¹(φ) = asinh(tan(φ))
    latitudes = [0, 30, 45, 60]  # 纬度(度)
    for lat_deg in latitudes:
        lat_rad = np.radians(lat_deg)
        y_coord = invGudermannian(lat_rad)
        print(f"纬度 {lat_deg}° -> 墨卡托投影y坐标: {y_coord:.6f}")
    #纬度 0° -> 墨卡托投影y坐标: 0.000000
    #纬度 30° -> 墨卡托投影y坐标: 0.549306
    #纬度 45° -> 墨卡托投影y坐标: 0.881374
    #纬度 60° -> 墨卡托投影y坐标: 1.316958

    示例4: 双曲几何应用

    在双曲几何中,反古德曼函数用于角度和长度的转换
    angles = [0.1, 0.5, 1.0]  # 弧度
    for angle in angles:
        hyperbolic_measure = invGudermannian(angle)
        print(f"欧几里得角度 {angle:.3f} -> 双曲度量: {hyperbolic_measure:.6f}")
    #欧几里得角度 0.100 -> 双曲度量: 0.100167
    #欧几里得角度 0.500 -> 双曲度量: 0.522238
    #欧几里得角度 1.000 -> 双曲度量: 1.226191

    示例5: 特殊值验证

    special_values = {
        '0': 0,
        'pi/4': asinh(1),
        'pi/6': asinh(1/√3)
    }

    for val, expected in special_values.items():
        result = invGudermannian(val)
        print(f"gd⁻¹({val}) = {result} (期望: {expected})")
    #gd⁻¹(0) = 0.0 (期望: 0)
    #gd⁻¹(pi/4) = 0.8813735870195429 (期望: asinh(1))
    #gd⁻¹(pi/6) = 0.5493061443340549 (期望: asinh(1/√3))

    示例6: 边界条件测试

    boundary_values = [-1.56, -1.57, 1.56, 1.57]  # 接近 ±π/2
    for val in boundary_values:
        result = invGudermannian(val)
        print(f"gd⁻¹({val}) = {result}")
    #gd⁻¹(-1.56) = -5.221686781391221
    #gd⁻¹(-1.57) = -7.828648037733774
    #gd⁻¹(1.56) = 5.221686781391221
    #gd⁻¹(1.57) = 7.828648037733774
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np

    def inverse_gudermannian(input_str):
        '''
        返回z的逆古德曼函数(使用解析表达式,避免数值求解的不稳定性)

        古德曼函数:gd(x) = 2 * atan(exp(x)) - pi/2
        反古德曼函数:x = arcsinh(tan(y)) 或 x = ln(sec(y) + tan(y))

        :param input_str: 输入值或表达式
        :return: 反古德曼函数值或表达式
        '''
        try:
            # 将输入字符串转换为SymPy表达式
            y = sp.sympify(input_str)

            # 使用解析表达式:inverse_gudermannian(y) = arcsinh(tan(y)) = ln(sec(y) + tan(y))
            if y.free_symbols:
                # 符号情况:返回解析表达式
                result = sp.asinh(sp.tan(y))
                # 也可以写成对数形式:sp.log(sp.sec(y) + sp.tan(y))
                return result
            else:
                # 数值情况:直接计算
                y_val = float(y.evalf())
                # 检查定义域:tan(y) 在 y = ±pi/2 处无定义
                if abs(y_val) >= np.pi / 2:
                    return f"错误: 输入值 {y_val} 超出定义域 (-π/2, π/2)"

                # 使用解析公式计算
                result = np.arcsinh(np.tan(y_val))
                return result

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


    # --------------------------
    # 示例代码
    # --------------------------
    if __name__ == "__main__":
        # 示例1:基本数值矩阵求逆
        print(inverse_gudermannian("0"))
        # 6.083691555487232e-17

        # 示例2:使用LU分解法
        print(inverse_gudermannian("1.5"))
        # 3.3406775427982867

        # 示例3:单位矩阵求逆(结果应不变)
        print(inverse_gudermannian("x"))
        # Eq(2*atan(exp(x)) - pi/2, x)
    
    
    希尔伯特矩阵的逆矩阵

    H = invhilb(n) 生成确切希尔伯特矩阵的的逆矩阵.

    n — 矩阵的阶次,非负整数标量

    示例1: 基本测试

    for n in [1, 2, 3, 4]:
        print(f"\n{n}阶希尔伯特矩阵的逆:")
        H_inv = invhilb(n)
        print(H_inv)

        # 验证逆矩阵性质
        H = hilbert_matrix(n)
        identity_check = H * H_inv
        print(f"验证 H * H_inv ≈ I:")
        print(identity_check.evalf(3))  # 保留3位小数显示
    #1阶希尔伯特矩阵的逆:
    #[[1]]
    #验证 H * H_inv ≈ I:
    #[[1.00]]

    #2阶希尔伯特矩阵的逆:
    #[[4, -6],
      [-6, 12]]
    #验证 H * H_inv ≈ I:
    #[[1.00, 0],
      [0, 1.00]]

    #3阶希尔伯特矩阵的逆:
    #[[9, -36, 30],
      [-36, 192, -180],
      [30, -180, 180]]
    #验证 H * H_inv ≈ I:
    #[[1.00, 0, 0],
      [0, 1.00, 0],
      [0, 0, 1.00]]

    #4阶希尔伯特矩阵的逆:
    #[[16, -120, 240, -140],
      [-120, 1200, -2700, 1680],
      [240, -2700, 6480, -4200],
      [-140, 1680, -4200, 2800]]
    #验证 H * H_inv ≈ I:
    #[[1.00, 0, 0, 0],
      [0, 1.00, 0, 0],
      [0, 0, 1.00, 0],
      [0, 0, 0, 1.00]]

    示例2: 条件数分析(病态性研究)

    希尔伯特矩阵是著名的病态矩阵,条件数随阶数增长极快
    for n in [3, 5, 7, 10]:
        H = hilbert_matrix(n)
        cond_num = matrix_condition_number(H)
        print(f"{n}阶希尔伯特矩阵的条件数: {cond_num}")

        # 显示矩阵元素
        if n <= 5:
            print(f"H_{n} = ")
            print(H.evalf(3))
    #3阶希尔伯特矩阵的条件数: 524.0567775860644
    #H_3 = [[1.00, 0.500, 0.333],
            [0.500, 0.333, 0.250],
            [0.333, 0.250, 0.200]]
    #5阶希尔伯特矩阵的条件数: 476607.25024224253
    #H_5 = [[1.00, 0.500, 0.333, 0.250, 0.200],
            [0.500, 0.333, 0.250, 0.200, 0.167],
            [0.333, 0.250, 0.200, 0.167, 0.143],
            [0.250, 0.200, 0.167, 0.143, 0.125],
            [0.200, 0.167, 0.143, 0.125, 0.111]]
    #7阶希尔伯特矩阵的条件数: 475367356.37688667
    #10阶希尔伯特矩阵的条件数: 16024859712306.152

    示例3: 数值稳定性测试

    比较符号计算和数值计算的差异
    n = 6
    H_sym = hilbert_matrix(n)
    H_inv_sym = invhilb(n)

    数值计算(可能不准确)
    H_np = np.array([[1 / (i + j + 1) for j in range(n)] for i in range(n)], dtype=float)
    try:
        H_inv_np = np.linalg.inv(H_np)
        print(f"\n{n}阶希尔伯特矩阵数值逆的前3×3元素:")
        print(H_inv_np[:3, :3])
        print(f"符号计算逆的前3×3元素:")
        print(np.array(H_inv_sym[:3, :3], dtype=float))

        # 计算差异
        diff = np.array(H_inv_sym, dtype=float) - H_inv_np
        print(f"最大差异: {np.max(np.abs(diff))}")
    except Exception as e:
        print(f"数值计算失败: {e}")
    #6阶希尔伯特矩阵数值逆的前3×3元素:
    #[[ 3.6000e+01,-6.3000e+02,3.3600e+03]
      [-6.3000e+02,1.4700e+04,-8.8200e+04]
      [ 3.3600e+03,-8.8200e+04,5.6448e+05]]
    #符号计算逆的前3×3元素:
    #[[ 3.6000e+01,-6.3000e+02,3.3600e+03]
      [-6.3000e+02,1.4700e+04,-8.8200e+04]
      [ 3.3600e+03,-8.8200e+04,5.6448e+05]]
    #最大差异: 0.0006772307679057121

    示例4: 在多项式拟合中的应用

    希尔伯特矩阵出现在最小二乘多项式拟合中

    在多项式拟合中,法方程系数矩阵通常是希尔伯特矩阵

    对于n次多项式拟合,法方程矩阵是(n+1)×(n+1)的希尔伯特矩阵

    演示3次多项式拟合
    degree = 3
    n = degree + 1
    H_fit = hilbert_matrix(n)
    print(f"\n{degree}次多项式拟合的法方程矩阵:")
    print(H_fit.evalf(3))

    H_inv_fit = invhilb(str(n))
    print(f"逆矩阵:")
    print(H_inv_fit)
    #3次多项式拟合的法方程矩阵:
    #[[1.00, 0.500, 0.333, 0.250],
      [0.500, 0.333, 0.250, 0.200],
      [0.333, 0.250, 0.200, 0.167],
      [0.250, 0.200, 0.167, 0.143]]
    #逆矩阵:
    #[[16, -120, 240, -140],
      [-120, 1200, -2700, 1680],
      [240, -2700, 6480, -4200],
      [-140, 1680, -4200, 2800]]

    示例5: 误差分析

    研究扰动对解的影响
    n = 4
    H = hilbert_matrix(n)
    H_inv = invhilb(n)

    创建扰动向量
    b = [1, 1, 1, 1]
    delta_b = [0.001, -0.001, 0.0005, -0.0005]

    原始解和扰动解
    x_original = H_inv * b
    x_perturbed = H_inv * (b + delta_b)

    error = x_perturbed - x_original
    print(f"原始解: {x_original.evalf(6)}")
    print(f"扰动解: {x_perturbed.evalf(6)}")
    print(f"误差: {error.evalf(6)}")
    print(f"相对误差范数: {error.norm() / x_original.norm():.6f}")
    #原始解:
    #[[-4.00000],
      [60.0000],
      [-180.000],
      [140.000]]
    #扰动解:
    #[[-3.67400],
      [56.4900],
      [-171.720],
      [134.680]]
    #误差:
    #[[0.326000],
      [-3.51000],
      [8.28000],
      [-5.32000]]
    #相对误差范数: 0.044329

    示例6: 特殊性质验证

    希尔伯特逆矩阵的元素都是整数
    n = 5
    H_inv = invhilb(n)

    print(f"{n}阶希尔伯特逆矩阵的元素都是整数:")
    for i in range(min(n, 3)):  # 只显示前3行
        row = [H_inv[i, j] for j in range(min(n, 3))]
        print(f"第{i + 1}行: {row}")
    #5阶希尔伯特逆矩阵的元素都是整数:
    #第1行: [25, -300, 1050]
    #第2行: [-300, 4800, -18900]
    #第3行: [1050, -18900, 79380]

    示例7: 与其它矩阵的比较

    比较希尔伯特矩阵和其它矩阵的逆
    matrices = {
        "希尔伯特矩阵": hilbert_matrix(3),
        "单位矩阵": sp.eye(3),
        "三对角矩阵": sp.Matrix([[2, 1, 0], [1, 2, 1], [0, 1, 2]])
    }

    for name, mat in matrices.items():
        try:
            inv_mat = mat.inv()
            print(f"\n{name}的逆:")
            print(inv_mat.evalf(3))
        except Exception as e:
            print(f"{name}求逆失败: {e}")
    #希尔伯特矩阵的逆:
    #[[9.00, -36.0, 30.0],
      [-36.0, 192., -180.],
      [30.0, -180., 180.]]

    #单位矩阵的逆:
    #[[1.00, 0, 0],
      [0, 1.00, 0],
      [0, 0, 1.00]]

    #三对角矩阵的逆:
    #[[0.750, -0.500, 0.250],
      [-0.500, 1.00, -0.500],
      [0.250, -0.500, 0.750]]

    示例8: 大规模计算警告

    测试较大阶数(可能有性能问题)
    large_n = 12
    result = invhilb(large_n)
    if isinstance(result, str):
        print(f"n={large_n}: {result}")
    else:
        print(f"n={large_n}: 计算成功,逆矩阵形状 {result.shape}")
        # 显示一些统计信息
        elements = [abs(float(result[i, j])) for i in range(large_n) for j in range(large_n)]
        print(f"元素绝对值范围: [{min(elements):.2e}, {max(elements):.2e}]")
    #n=12: 计算成功,逆矩阵形状 (12, 12)
    #元素绝对值范围: [1.44e+02, 3.66e+15]
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np

    def inverse_hilb_matrix(input_str):
        """
        对标MATLAB invhilb函数,生成n×n希尔伯特矩阵的逆矩阵

        参数:
        input_str: 表示正整数的字符串

        返回:
        SymPy矩阵对象(成功时)或错误信息字符串(失败时)

        示例:
        >>> inverse_hilb_matrix("3")
        Matrix([
        [  9, -36,  30],
        [-36, 192,-180],
        [ 30,-180, 180]])
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            def hilbert_matrix_symbolic(n):
                """完全符号计算的实现方案"""
                H = sp.zeros(n)
                for i in range(n):
                    for j in range(n):
                        H[i, j] = 1 / (sp.Integer(i) + sp.Integer(j) + 1)
                return H.inv()

            if isinstance(expr, tuple):
                error = True
            elif expr.is_integer:
                n = int(expr)
                if n <= 0:
                    return f"错误: 阶数必须为正整数,得到 {n}"
                if n > 15:
                    return f"警告: 阶数 {n} 较大,计算可能较慢。希尔伯特矩阵是高度病态的,高阶数可能导致数值不稳定。"
                result = hilbert_matrix_symbolic(n)
            else:
                error = True

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


    def hilbert_matrix(n):
        """生成n×n希尔伯特矩阵"""
        H = sp.zeros(n)
        for i in range(n):
            for j in range(n):
                H[i, j] = 1 / (sp.Integer(i) + sp.Integer(j) + 1)
        return H


    def matrix_condition_number(H):
        """计算矩阵的条件数(近似)"""
        try:
            H_np = np.array(H, dtype=float)
            return np.linalg.cond(H_np)
        except:
            return "无法计算条件数"

    # --------------------------
    # 示例代码
    # --------------------------
    if __name__ == "__main__":
        # 示例1:3阶希尔伯特逆矩阵
        print("示例1:n=4")
        print(inverse_hilb_matrix("4"))
        # Matrix([[16, -120, 240, -140],
        #         [-120, 1200, -2700, 1680],
        #         [240, -2700, 6480, -4200],
        #         [-140, 1680, -4200, 2800]])

        # 示例2:边界条件测试(n=1)
        print("\n示例2:n=1")
        print(inverse_hilb_matrix("1"))
        # Matrix([[1]])
    
    
    逆置换数组维度

    A = ipermute(B,dimorder) 按照向量 dimorder 指定的顺序重新排列数组 B 的维度,使得 B = permute(A,dimorder)。换句话说,输入数组的第 i 个维度变为输出数组的维度 dimorder(i)。

    B — 输入数组,向量,矩阵

    dimorder — 维度顺序,行向量

    示例1: 基本二维数组转置

    原始数组
    original = [[1, 2, 3], [4, 5, 6]]
    print("原始数组:")
    print(original)
    #原始数组:
    #[[1, 2, 3],
      [4, 5, 6]]

    先permute转置
    permuted = permute_order([[1,2,3],[4,5,6]],[2,1])
    print("\npermute转置后:")
    print(permuted)
    #permute转置后:
    #[[1, 4],
      [2, 5],
      [3, 6]]

    再ipermute恢复
    recovered = ipermute([[1,4],[2,5],[3,6]],[2,1])
    print("\nipermute恢复后:")
    print(recovered)
    #ipermute恢复后:
    #[[1, 2, 3],
      [4, 5, 6]]

    示例2: 三维数组维度重排

    3x2x4 三维数组
    array_3d = [[[1, 2, 3, 4], [5, 6, 7, 8]],
                [[9, 10, 11, 12], [13, 14, 15, 16]],
                [[17, 18, 19, 20], [21, 22, 23, 24]]]
    print("原始3D数组形状: 3x2x4")
    print("原始数组:")
    print(array_3d)
    #原始3D数组形状: 3x2x4
    #原始数组:
    #[[[1, 2, 3, 4], [5, 6, 7, 8]],
      [[9, 10, 11, 12], [13, 14, 15, 16]],
      [[17, 18, 19, 20], [21, 22, 23, 24]]]

    permute: 从 [1,2,3] 变为 [2,3,1]
    permuted_3d = permute_order([[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]],[[17,18,19,20],[21,22,23,24]]],[2,3,1])
    print("\npermute [2,3,1] 后:")
    print(permuted_3d)
    #permute [2,3,1] 后:
    #[[[1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20]],
      [[5, 13, 21], [6, 14, 22], [7, 15, 23], [8, 16, 24]]]

    ipermute恢复
    recovered_3d = ipermute(permuted_3d,[2,3,1])
    print("\nipermute恢复后:")
    print(recovered_3d)
    #ipermute恢复后:
    #[[[1, 2, 3, 4], [5, 6, 7, 8]],
      [[9, 10, 11, 12], [13, 14, 15, 16]],
      [[17, 18, 19, 20], [21, 22, 23, 24]]]

    示例3: 图像处理中的通道重排

    模拟RGB图像数据: 高度x宽度x通道

    假设 2x3 RGB图像
    image_data = [
        [[255, 0, 0], [0, 255, 0], [0, 0, 255]],  # 第一行: 红,绿,蓝
        [[255, 255, 0], [255, 0, 255], [0, 255, 255]]  # 第二行: 黄,紫,青
    ]
    print("原始图像数据 (2x3x3 - 高x宽x通道):")
    print(image_data)
    #原始图像数据 (2x3x3 - 高x宽x通道):
    #[[[255, 0, 0], [0, 255, 0], [0, 0, 255]],
      [[255, 255, 0], [255, 0, 255], [0, 255, 255]]]

    从 [高,宽,通道] 变为 [通道,高,宽] (深度学习常用)
    permuted_image = permute_order(image_data,[3,1,2])
    print("\npermute为通道优先 [3,1,2]:")
    print(permuted_image)
    #permute为通道优先 [3,1,2]:
    #[[[255, 0, 0], [255, 255, 0]],
      [[0, 255, 0], [255, 0, 255]],
      [[0, 0, 255], [0, 255, 255]]]

    恢复原始布局
    recovered_image = ipermute(permuted_image,[3,1,2])
    print("\nipermute恢复原始布局:")
    print(recovered_image)
    #ipermute恢复原始布局:
    #[[[255, 0, 0], [0, 255, 0], [0, 0, 255]],
      [[255, 255, 0], [255, 0, 255], [0, 255, 255]]]

    示例4: 时间序列数据重排

    多个传感器的时间序列: 时间x传感器x测量值
    sensor_data = [
        [[1.1, 1.2], [2.1, 2.2], [3.1, 3.2]],  # 时间点1: 3个传感器的2个测量值
        [[1.3, 1.4], [2.3, 2.4], [3.3, 3.4]],  # 时间点2
        [[1.5, 1.6], [2.5, 2.6], [3.5, 3.6]]  # 时间点3
    ]

    print("传感器数据 (3x3x2 - 时间x传感器x测量):")
    print(sensor_data)
    #传感器数据 (3x3x2 - 时间x传感器x测量):
    #[[[1.1, 1.2], [2.1, 2.2], [3.1, 3.2]],
      [[1.3, 1.4], [2.3, 2.4], [3.3, 3.4]],
      [[1.5, 1.6], [2.5, 2.6], [3.5, 3.6]]]

    重排为 [传感器, 测量, 时间]
    rearranged = permute_order(sensor_data,[2,3,1])
    print("\n重排为 [传感器,测量,时间] [2,3,1]:")
    print(rearranged)
    #重排为 [传感器,测量,时间] [2,3,1]:
    #[[[1.1, 1.3, 1.5], [1.2, 1.4, 1.6]],
      [[2.1, 2.3, 2.5], [2.2, 2.4, 2.6]],
      [[3.1, 3.3, 3.5], [3.2, 3.4, 3.6]]]

    恢复原始顺序
    original_order = ipermute(rearranged,[2,3,1])
    print("\n恢复原始顺序:")
    print(original_order)
    #恢复原始顺序:
    #[[[1.1, 1.2], [2.1, 2.2], [3.1, 3.2]],
      [[1.3, 1.4], [2.3, 2.4], [3.3, 3.4]],
      [[1.5, 1.6], [2.5, 2.6], [3.5, 3.6]]]

    示例5: 符号计算中的张量操作

    使用符号变量的张量
    symbolic_tensor = [
        [[x, x ** 2], [y, y ** 2]],
        [[z, z ** 2], [x + y, (x + y) ** 2]]
    ]
    print("符号张量:")
    print(symbolic_tensor)
    #符号张量:
    #[[[x, x**2], [y, y**2]],
      [[z, z**2], [x + y, (x + y)**2]]]

    维度重排
    permuted_symbolic = permute_order(symbolic_tensor,[3,1,2])
    print("\n符号张量permute [3,1,2]:")
    print(permuted_symbolic)
    #符号张量permute [3,1,2]:
    #[[[x, y], [z, x + y]],
      [[x**2, y**2], [z**2, (x + y)**2]]]

    恢复
    recovered_symbolic = ipermute(permuted_symbolic,[3,1,2])
    print("\n符号张量ipermute恢复:")
    print(recovered_symbolic)
    #符号张量ipermute恢复:
    #[[[x, x**2], [y, y**2]],
      [[z, z**2], [x + y, (x + y)**2]]]

    示例6: 四维数据(如批量图像)

    批量图像数据: 批量大小x通道x高x宽
    batch_images = [
        [  # 第一个样本
            [[1, 2], [3, 4]],  # 通道1
            [[5, 6], [7, 8]]  # 通道2
        ],
        [  # 第二个样本
            [[9, 10], [11, 12]],  # 通道1
            [[13, 14], [15, 16]]  # 通道2
        ]
    ]
    print("批量图像数据 (2x2x2x2 - 批量x通道x高x宽):")
    print(batch_images)
    #批量图像数据 (2x2x2x2 - 批量x通道x高x宽):
    #[[[[1, 2], [3, 4]],
       [[5, 6], [7, 8]]],
      [[[9, 10], [11, 12]],
       [[13, 14], [15, 16]]]]

    重排为 PyTorch 风格: [批量, 通道, 高, 宽] -> [批量, 高, 宽, 通道]
    pytorch_style = permute_order(batch_images,[1,3,4,2])
    print("\n重排为PyTorch风格 [1,3,4,2]:")
    print(pytorch_style)
    #重排为PyTorch风格 [1,3,4,2]:
    #[[[[1, 5], [2, 6]],
       [[3, 7], [4, 8]]],
      [[[9, 13], [10, 14]],
       [[11, 15], [12, 16]]]]

    恢复
    original_batch = ipermute(pytorch_style,[1,3,4,2])
    print("\n恢复原始批量格式:")
    print(original_batch)
    #恢复原始批量格式:
    #[[[[1, 2], [3, 4]],
       [[5, 6], [7, 8]]],
      [[[9, 10], [11, 12]],
       [[13, 14], [15, 16]]]]

    示例7: 验证逆置换性质

    验证 permute 和 ipermute 是互逆操作
    test_array = [[1, 2], [3, 4], [5, 6]]
    print("测试数组:")
    print(test_array)
    #测试数组:
    #[[1, 2],
      [3, 4],
      [5, 6]]

    order = [2, 1]
    permuted_test = permute_order(test_array,[2,1])
    print(f"\npermute with order {order}:")
    print(permuted_test)
    #permute with order [2, 1]:
    #[[1, 3, 5],
      [2, 4, 6]]

    ipermuted_test = ipermute(permuted_test,[2,1])
    print(f"\nipermute with same order {order}:")
    print(ipermuted_test)
    #ipermute with same order [2, 1]:
    #[[1, 2],
      [3, 4],
      [5, 6]]

    print(f"\n恢复是否成功: {test_array == ipermuted_test}")
    #恢复是否成功: True
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np

    def permute_order(input_str):
        """
        实现permute功能,用于对比测试
        """
        try:
            expr = sp.sympify(input_str)
            result = None
            error = False

            if isinstance(expr, tuple) and len(expr) == 2:
                if isinstance(expr[0], list) and isinstance(expr[1], list):
                    order = expr[1]
                    # 将MATLAB的1-based order转换为0-based
                    order = [o - 1 for o in order]
                    arr_np = np.array(matrix.tolist(), dtype=object)
                    result_np = np.transpose(arr_np, order)
                    result = sp.Array(result_np.tolist())
                else:
                    error = True
            else:
                error = True

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

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

    def inverse_permute_order(input_str):
        """
        实现与MATLAB ipermute等效的功能,通过计算逆排列并调整转置顺序。
        :param arr: 输入的数组,可以是sympy矩阵或numpy数组
        :param order: 原permute操作使用的维度顺序(1-based,如MATLAB)
        :return: 重排后的数组
        """
        try:
            expr = sp.sympify(input_str)
            result = None
            error = False

            if isinstance(expr, tuple) and len(expr) == 2:
                if isinstance(expr[0], list) and isinstance(expr[1], list):
                    matrix = sp.Matrix(expr[0])
                    order = expr[1]
                    # 将MATLAB的1-based order转换为0-based
                    order = [o - 1 for o in order]
                    # 计算逆排列:inv_order使得应用后恢复原始维度
                    inv_order = np.argsort(order)
                    arr_np = np.array(matrix.tolist(), dtype=object)
                    result_np = np.transpose(arr_np, inv_order)
                    result = sp.Matrix(result_np.tolist())
                else:
                    error = True
            else:
                error = True

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

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


    def main():
        # 示范使用sympy矩阵
        sympy_result = inverse_permute_order("[[x,y],[z,x+y]],[2,1]")
        print("\n使用sympy矩阵重排后的数组:")
        print(sympy_result)
        # Matrix([[x, z],
        #         [y, x + y]])

        # 示范使用numpy数组
        numpy_result = inverse_permute_order("[[1,2],[3,4]],[2,1]")
        print("\n使用numpy数组重排后的数组:")
        print(numpy_result)
        # Matrix([[1, 3],
        #         [2, 4]])


    if __name__ == "__main__":
        main()
    
    
    确定矩阵是否在指定带宽范围内

    如果A是在指定的下带宽和上带宽范围内的矩阵,则tf = isbanded(A,lower,upper) 返回逻辑值 1 (true).否则,将返回逻辑值 0 (false).

    A — 输入数组,数组

    lower — 下带宽,非负整数标量

    upper — 上带宽,非负整数标量

    示例1: 基本带状矩阵测试

    三对角矩阵 (下带宽=1, 上带宽=1)
    tridiagonal = [[2, 1, 0, 0],
                   [1, 2, 1, 0],
                   [0, 1, 2, 1],
                   [0, 0, 1, 2]]
    result = isbanded(tridiagonal, 1, 1)
    print(f"三对角矩阵 (下带宽1, 上带宽1): {bool(result)}")
    #三对角矩阵 (下带宽1, 上带宽1): True

    下三角矩阵 (下带宽=3, 上带宽=0)
    lower_tri = [[1, 0, 0, 0],
                 [2, 3, 0, 0],
                 [4, 5, 6, 0],
                 [7, 8, 9, 10]]
    result = isbanded(lower_tri, 3, 0)
    print(f"下三角矩阵 (下带宽3, 上带宽0): {bool(result)}")
    #下三角矩阵 (下带宽3, 上带宽0): True

    示例2: 有限差分矩阵

    一维有限差分矩阵 (三对角)
    fd_matrix = [[-2, 1, 0, 0, 0],
                 [1, -2, 1, 0, 0],
                 [0, 1, -2, 1, 0],
                 [0, 0, 1, -2, 1],
                 [0, 0, 0, 1, -2]]
    result = isbanded(fd_matrix, 1, 1)
    print(f"有限差分矩阵 (下带宽1, 上带宽1): {bool(result)}")
    #有限差分矩阵 (下带宽1, 上带宽1): True

    示例3: 边界条件测试

    对角矩阵 (下带宽=0, 上带宽=0)
    diagonal = [[1, 0, 0],
                [0, 2, 0],
                [0, 0, 3]]
    result = isbanded(diagonal, 0, 0)
    print(f"对角矩阵 (下带宽0, 上带宽0): {bool(result)}")
    #对角矩阵 (下带宽0, 上带宽0): True

    测试非对角矩阵
    not_diagonal = [[1, 0.1, 0],
                    [0, 2, 0],
                    [0, 0, 3]]
    result = isbanded(not_diagonal, 0, 0)
    print(f"非严格对角矩阵 (下带宽0, 上带宽0): {bool(result)}")
    #非严格对角矩阵 (下带宽0, 上带宽0): False

    示例4: 数值线性代数中的常见矩阵

    对称带状矩阵
    symmetric_banded = [[4, 1, 0, 0],
                        [1, 4, 1, 0],
                        [0, 1, 4, 1],
                        [0, 0, 1, 4]]
    result = isbanded(symmetric_banded, 1, 1)
    print(f"对称带状矩阵 (下带宽1, 上带宽1): {bool(result)}")
    #对称带状矩阵 (下带宽1, 上带宽1): True

    Toeplitz 矩阵
    toeplitz = [[2, 1, 0, 0],
                [3, 2, 1, 0],
                [0, 3, 2, 1],
                [0, 0, 3, 2]]
    result = isbanded(toeplitz, 1, 1)
    print(f"Toeplitz矩阵 (下带宽1, 上带宽1): {bool(result)}")
    #Toeplitz矩阵 (下带宽1, 上带宽1): True

    示例5: 符号矩阵测试

    使用符号变量的带状矩阵
    symbolic_banded = [[a, b, 0, 0],
                       [c, a, b, 0],
                       [0, c, a, b],
                       [0, 0, c, a]]

    result = isbanded(symbolic_banded, 1, 1)
    print(f"符号三对角矩阵 (下带宽1, 上带宽1): {bool(result)}")
    #符号三对角矩阵 (下带宽1, 上带宽1): True

    示例6: 稀疏矩阵应用

    典型的稀疏矩阵结构
    sparse_pattern = [[0, 5, 0, 0, 0],
                      [2, 0, 7, 0, 0],
                      [0, 3, 0, 9, 0],
                      [0, 0, 4, 0, 6],
                      [0, 0, 0, 1, 0]]
    result = isbanded(sparse_pattern, 1, 1)
    print(f"稀疏矩阵模式 (下带宽1, 上带宽1): {bool(result)}")
    #稀疏矩阵模式 (下带宽1, 上带宽1): True

    更宽松的带宽检查
    result = isbanded(sparse_pattern, 2, 2)
    print(f"稀疏矩阵模式 (下带宽2, 上带宽2): {bool(result)}")
    #稀疏矩阵模式 (下带宽2, 上带宽2): True

    示例7: 实际工程应用

    结构力学中的刚度矩阵 (通常有固定带宽)
    stiffness_matrix = [
        [10, -5, 0, 0, 0],
        [-5, 15, -5, 0, 0],
        [0, -5, 15, -5, 0],
        [0, 0, -5, 15, -5],
        [0, 0, 0, -5, 10]
    ]
    result = isbanded(stiffness_matrix, 1, 1)
    print(f"结构刚度矩阵 (下带宽1, 上带宽1): {bool(result)}")
    #结构刚度矩阵 (下带宽1, 上带宽1): True

    电路分析中的导纳矩阵
    admittance_matrix = [
        [3, -1, 0, -1, 0],
        [-1, 4, -1, 0, -1],
        [0, -1, 3, -1, 0],
        [-1, 0, -1, 4, -1],
        [0, -1, 0, -1, 3]
    ]
    result = isbanded(admittance_matrix, 2, 2)
    print(f"电路导纳矩阵 (下带宽2, 上带宽2): {bool(result)}")
    #电路导纳矩阵 (下带宽2, 上带宽2): False
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp

    def is_within_banded(input_str):
        """
        对标 MATLAB 的 isbanded 函数,判断矩阵是否在指定带宽范围内。

        参数:
            input_str (str): 输入字符串,格式为 "矩阵, 下带宽, 上带宽"。
                            示例: "[[0,1,0], [2,0,3], [0,4,0]], 1, 0"

        返回:
            bool 或 str: 如果矩阵满足带宽要求返回 True,否则返回 False。
                         输入错误时返回错误信息字符串。

        示例:
            >>> result = is_within_banded("[[0,1,0], [2,0,3], [0,4,0]], 1, 0")
            >>> print(result)  # True
        """
        try:
            # 解析输入字符串为 SymPy 表达式
            expr = sp.sympify(input_str)

            # 验证输入是否为三元组 (矩阵, 下带宽, 上带宽)
            if not (isinstance(expr, tuple) and len(expr) == 3):
                return f"输入错误:需要形如 '矩阵, 下带宽, 上带宽' 的三元组,当前输入为 {input_str}"

            # 提取矩阵、下带宽、上带宽
            M_sym = sp.Matrix(expr[0]) if isinstance(expr[0], list) else None
            lower = expr[1]
            upper = expr[2]

            # 检查矩阵和带宽的有效性
            if M_sym is None:
                return "错误:输入的矩阵无效"
            if not (lower.is_Integer and upper.is_Integer):
                return "错误:下带宽和上带宽必须为整数"
            lower = int(lower)
            upper = int(upper)
            if lower < 0 or upper < 0:
                return "错误:带宽不能为负数"

            # 检查矩阵是否为带状矩阵
            rows, cols = M_sym.shape
            for i in range(rows):
                for j in range(cols):
                    # 关键逻辑:判断元素是否在带宽范围外且非零
                    if (i - j > lower) or (j - i > upper):
                        if M_sym[i, j] != 0:
                            return 0
            return 1

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


    input_str = "[[2,1,0], [3,2,1], [0,4,3]], 1, 1"
    print(is_within_banded(input_str))
    # 1

    input_str = "[[1,0,5], [2,3,0], [0,4,6]], 1, 0"
    print(is_within_banded(input_str))
    # 0
    
    
    确定哪些元素在指定范围内

    TF=isbetween(A,lower,upper)确定输入数据中的哪些元素在由下限和上限定义的区间内,并返回与输入数据大小相同的逻辑数组. 默认情况下, 该间隔为封闭间隔. 当对应元素在指定范围内时,TF包含1(true),否则包含0(false).

    A — 输入向量或矩阵

    lower — 下限,标量或向量

    upper — 上限,标量或向量

    示例 1: 学生成绩评定

    判断学生成绩是否在及格范围内 [60, 100]
    grades = [[55, 78, 92], [61, 59, 85], [88, 72, 65]], 60, 100
    print("成绩矩阵:", grades)
    print("及格情况:", isbetween(grades))
    #成绩矩阵: ([[55, 78, 92], [61, 59, 85], [88, 72, 65]], 60, 100)
    #及格情况: [[0, 1, 1], [1, 0, 1], [1, 1, 1]]

    示例 2: 温度监控系统

    不同房间有不同的温度要求范围
    temperatures = [[25, 22, 18], [30, 15, 20], [28, 19, 23]], [20,18,16], [26,22,25]
    print("温度矩阵:", temperatures)
    print("温度正常:", isbetween(temperatures))
    #温度矩阵: ([[25, 22, 18], [30, 15, 20], [28, 19, 23]], [20,18,16], [26,22,25])
    #温度正常: [[1, 1, 0], [0, 0, 1], [0, 1, 1]

    示例 3: 财务预算控制

    各部门支出是否在预算范围内
    expenses = [[12000, 8500], [9500, 11000], [7800, 9200]], [8000,9000], [10000,10000]
    print("支出矩阵:", expenses)
    print("预算内:", isbetween(expenses))
    # 支出矩阵: ([[12000, 8500], [9500, 11000], [7800, 9200]], [8000,9000], [10000,10000])
    #预算内: lower

    示例 4: 产品质量检测

    产品各项指标是否在合格范围内
    quality_metrics = [8.5, 7.2, 9.1, 6.8], 7.0, 9.0
    print("质量指标:", quality_metrics)
    print("合格产品:", isbetween(quality_metrics))
    #质量指标: ([8.5, 7.2, 9.1, 6.8], 7.0, 9.0)
    #合格产品: [1, 1, 0, 0]

    示例 5: 库存管理

    检查库存是否在安全库存和最大库存之间
    inventory = [[150, 200], [80, 350], [120, 180]], [100,150], [300,250]
    print("库存水平:", inventory)
    print("库存合理:", isbetween(inventory))
    #库存水平: ([[150, 200], [80, 350], [120, 180]], [100,150], [300,250])
    #库存合理: lower

    示例 6: 血压监测

    收缩压和舒张压是否在正常范围内
    blood_pressure = [[120, 80], [140, 90], [110, 70]], [90,60], [140,90]
    print("血压数据:", blood_pressure)
    print("血压正常:", isbetween(blood_pressure))
    #血压数据: ([[120, 80], [140, 90], [110, 70]], [90,60], [140,90])
    #血压正常: lower

    示例 7: 传感器数据验证

    验证传感器读数是否在有效范围内
    sensor_data = [2.3, 5.1, 3.8, 6.2, 1.9], 2.0, 5.0
    print("传感器读数:", sensor_data)
    print("有效数据:", isbetween(sensor_data))
    #传感器读数: ([2.3, 5.1, 3.8, 6.2, 1.9], 2.0, 5.0)
    #有效数据: [1, 0, 1, 0, 0]

    示例 8: 考试成绩等级划分

    判断成绩是否在A等级范围内 [90, 100]
    exam_scores = [[85, 92, 78], [95, 88, 91], [89, 93, 87]], 90, 100
    print("考试成绩:", exam_scores)
    print("A等级:", isbetween(exam_scores))
    #考试成绩: ([[85, 92, 78], [95, 88, 91], [89, 93, 87]], 90, 100)
    #A等级: [[0, 1, 0], [1, 0, 1], [0, 1, 0]]

    示例 9: 工程参数合规检查

    检查工程参数是否在设计规范内
    engineering_params = [[10.2, 8.7], [9.8, 11.1], [10.5, 9.2]], [9.5,8.0], [10.5,9.5]
    print("工程参数:", engineering_params)
    print("参数合规:", isbetween(engineering_params))
    #工程参数: ([[10.2, 8.7], [9.8, 11.1], [10.5, 9.2]], [9.5,8.0], [10.5,9.5])
    #参数合规: lower

    示例 10: 心率监测

    运动员心率是否在目标训练区间
    heart_rates = [65, 142, 128, 155, 118], 120, 150
    print("心率数据:", heart_rates)
    print("目标区间:", isbetween(heart_rates))
    #心率数据: ([65, 142, 128, 155, 118], 120, 150)
    #目标区间: [0, 1, 1, 0, 0]
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    def is_between_range(input_str):
        """
        判断矩阵元素是否在指定区间内 [lower, upper]。
        返回 SymPy 矩阵,1 表示在区间内,0 表示不在。

        参数格式示例:
        "( [[1,2],[3,4]], [0,2], 5 )" 表示矩阵、下限向量、上限标量
        """
        try:
            expr = sp.sympify(input_str)

            if not (isinstance(expr, tuple)) and len(expr) == 3:
                return f"输入必须为三元组 (矩阵, lower, upper),当前长度 {len(expr)}"

            matrix = sp.Matrix(expr[0]) if isinstance(expr[0], list) else None

            if matrix is None:
                return "第一个元素必须为矩阵或可转换列表"

            # 转换矩阵为 numpy 数组
            if matrix.shape[1] == 1:  # 列向量转一维
                A = np.array(matrix).ravel().astype(float)
            else:
                A = np.array(matrix, dtype=float)

            # 处理 lower
            lower = expr[1]
            if isinstance(lower, (list, sp.Matrix)):
                lower = np.array(lower, dtype=float).ravel()
            elif lower.is_number:
                lower = float(lower)
            else:
                return f"lower 参数类型错误: {type(lower)}"

            # 处理 upper
            upper = expr[2]
            if isinstance(upper, (list, sp.Matrix)):
                upper = np.array(upper, dtype=float).ravel()
            elif upper.is_number:
                upper = float(upper)
            else:
                return f"upper 参数类型错误: {type(upper)}"

            # 维度验证
            if A.ndim == 2:
                rows = A.shape[0]
                if isinstance(lower, np.ndarray) and len(lower) != rows:
                    return f"lower 向量长度 {len(lower)} 与矩阵行数 {rows} 不匹配"
                if isinstance(upper, np.ndarray) and len(upper) != rows:
                    return f"upper 向量长度 {len(upper)} 与矩阵行数 {rows} 不匹配"

            # 核心判断逻辑
            result = []
            if A.ndim == 1:  # 向量处理
                l = lower if np.isscalar(lower) else lower[0]
                u = upper if np.isscalar(upper) else upper[0]
                bool_arr = np.logical_and(A >= l, A <= u)
                result = sp.Matrix([int(x) for x in bool_arr])
            else:  # 矩阵处理
                for i in range(A.shape[0]):
                    row = A[i]
                    l = lower[i] if isinstance(lower, np.ndarray) else lower
                    u = upper[i] if isinstance(upper, np.ndarray) else upper
                    bool_arr = np.logical_and(row >= l, row <= u)
                    result.append([int(x) for x in bool_arr])
                result = sp.Matrix(result)

            return result

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


    # 示例用法
    if __name__ == "__main__":
        # 示例 1: 向量 + 标量上下限
        print(is_between_range("([1, 2, 3], 2, 4)"))
        # Matrix([[0],
        #         [1],
        #         [1]])

        # 示例 2: 矩阵 + 向量上下限
        print(is_between_range("([[1,2], [3,4]], [0,3], [3,3])"))
        # Matrix([[1, 1],
        #         [1, 0]])
    
    
    确定矩阵是否为对角矩阵

    如果A是在指定的下带宽和上带宽范围内的矩阵,则tf = isbanded(A,lower,upper) 返回逻辑值 1 (true).否则,将返回逻辑值 0 (false).

    A — 输入数组,数组

    lower — 下带宽,非负整数标量

    upper — 上带宽,非负整数标量
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp

    def is_diagonal_matrix(input_str):
        """
        判断输入矩阵是否为对角矩阵 (对标 MATLAB 的 isdiag 函数)

        参数:
            input_str: 矩阵的字符串表示,支持以下格式:
                       "[[1, 0], [0, 2]]" - 二维列表格式
                       "[1, 0, 0]"         - 一维向量格式

        返回:
            int: 1 表示是对角矩阵,0 表示不是
            str: 错误信息字符串(输入无效时)

        示例:
            >>> is_diagonal_matrix("[[1, 0], [0, 2]]")
            1
            >>> is_diagonal_matrix("[[1, 2], [3, 4]]")
            0
            >>> is_diagonal_matrix("[[1, 0, 0], [0, 2, 0]]")  # 非方阵
            1
            >>> is_diagonal_matrix("[[0, 0], [0, 0]]")        # 零矩阵
            1
            >>> is_diagonal_matrix("invalid_matrix")
            'Error: 语法错误'
        """
        try:
            # 将输入字符串转换为 SymPy 表达式
            expr = sp.sympify(input_str)

            # 检查输入是否为元组(无效类型)
            if isinstance(expr, tuple):
                return f"输入错误: 不支持元组类型 {input_str}"

            # 转换为 SymPy 矩阵
            M = sp.Matrix(expr) if isinstance(expr, list) else None

            if M is None:
                return f"输入错误: 无法转换为矩阵 {input_str}"

            # 核心判断逻辑
            return 1 if M.is_diagonal() else 0

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


    # 测试用例
    if __name__ == "__main__":
        # 标准对角矩阵(方阵)
        print(is_diagonal_matrix("[[1, 0], [0, 2]]"))
        # 输出 1

        # 非对角矩阵
        print(is_diagonal_matrix("[[1, 2], [3, 4]]"))
        # 输出 0

        # 非方阵对角矩阵
        print(is_diagonal_matrix("[[1, 0, 0], [0, 2, 0]]"))
        # 输出 1

        # 零矩阵
        print(is_diagonal_matrix("[[0, 0], [0, 0]]"))
        # 输出 1

        # 列向量(非对角)
        print(is_diagonal_matrix("[[1], [2], [3]]"))
        # 输出 0
    
    
    确定矩阵是埃尔米特矩阵还是斜埃尔米特矩阵

    如果A是埃尔米特矩阵,则tf = ishermitian(A) 返回逻辑值1(true).否则,将返回逻辑值0(false).

    tf = ishermitian(A,skewOption) 指定测试的类型.将skewOption指定为 "skew" 以确定A是否为斜埃尔米特矩阵.

    A — 输入数组,数组
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def is_hermitian_matrix(input_str):
        """
        判断输入的矩阵是否为埃尔米特矩阵或斜埃尔米特矩阵。

        参数:
        input_str: 输入的字符串,表示矩阵或矩阵与选项的组合。例如:
                   - "Matrix([[1, I], [-I, 3]])" 检查埃尔米特矩阵。
                   - "(Matrix([[0, -1], [1, 0]]), skew)" 检查斜埃尔米特矩阵。

        返回:
         1 表示是,0 表示否,错误信息字符串表示输入有误。
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            if isinstance(expr, tuple):
                # 检查是否为 (矩阵, skew) 的形式
                if len(expr) != 2:
                    error = True
                else:
                    matrix_part, option_part = expr
                    M = sp.Matrix(matrix_part) if isinstance(matrix_part, list) else None
                    # 提取选项并去除可能的引号
                    option = str(option_part).strip("'\"")
                    if M is not None and option == "skew":
                        # 斜埃尔米特矩阵检查: M == -M.H
                        is_skew = M == -M.H
                        result = 1 if is_skew else 0
                    else:
                        error = True
            else:
                # 普通埃尔米特矩阵检查
                M = sp.Matrix(expr) if isinstance(expr, list) else None
                if M is not None:
                    is_herm = M.is_hermitian
                    result = 1 if is_herm else 0
                else:
                    error = True

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


    # 示例1: 埃尔米特矩阵
    print(is_hermitian_matrix("[[1, 2 + 3*I], [2 - 3*I, 4]]"))
    # 输出: 1

    # 示例2: 非埃尔米特矩阵
    print(is_hermitian_matrix("[[1, 2], [3, 4]]"))
    # 输出: 0

    # 示例3: 斜埃尔米特矩阵
    print(is_hermitian_matrix("[[0, -1], [1, 0]], skew"))
    # 输出: 1

    # 示例4: 非斜埃尔米特矩阵
    print(is_hermitian_matrix("[[0, 2], [-2, 0]], skew"))
    # 输出: 1
    
    
    查找缺失值

    TF = ismissing(A) 返回一个逻辑数组,该数组指示输入数据的哪些元素包含缺失值。TF 的大小与 A 的大小相同

    A — 向量,矩阵

    示例 1: 数据清洗 - 处理调查问卷缺失值

    假设 1-5 分制,nan 表示未回答
    survey_data = [[5, 3, nan, 4], [nan, 2, 5, nan], [1, nan, nan, 3]]
    print("调查问卷数据:", survey_data)
    print("缺失值位置:", ismissing(survey_data))
    #调查问卷数据: [[5, 3, nan, 4],
                  [nan, 2, 5, nan],
                  [1, nan, nan, 3]]
    #缺失值位置: [[0, 0, 1, 0],
                [1, 0, 0, 1],
                [0, 1, 1, 0]]

    示例 2: 传感器数据质量检测

    传感器故障时产生 NaN 值
    sensor_readings = [[23.5, 24.1, nan, 25.8], [22.9, nan, nan, 24.3], [nan, 23.7, 24.5, 25.1]]
    print("传感器读数:", sensor_readings)
    print("故障传感器:", ismissing(sensor_readings))
    #传感器读数: [[23.5, 24.1, nan, 25.8],
                [22.9, nan, nan, 24.3],
                [nan, 23.7, 24.5, 25.1]]
    #故障传感器: [[0, 0, 1, 0],
                [0, 1, 1, 0],
                [1, 0, 0, 0]]

    示例 3: 金融时间序列数据

    某些日期可能没有交易数据
    stock_prices = [120.5, 122.3, nan, 118.7, 119.8, nan, 121.2]
    print("股价序列:", stock_prices)
    print("缺失交易日:", ismissing(stock_prices))
    #股价序列: [120.5, 122.3, nan, 118.7, 119.8, nan, 121.2]
    #缺失交易日: [[0],
                [0],
                [1],
                [0],
                [0],
                [1],
                [0]]

    示例 4: 医疗记录完整性检查

    某些检查项目可能未完成
    patient_records = [[98.6, 120, 80, nan], [nan, 118, 78, 36.5], [97.9, nan, 82, 37.1]]
    print("医疗记录:", patient_records)
    print("缺失检查项:", ismissing(patient_records))
    #医疗记录: [[98.6, 120, 80, nan],
               [nan, 118, 78, 36.5],
               [97.9, nan, 82, 37.1]]
    #缺失检查项: [[0, 0, 0, 1],
                [1, 0, 0, 0],
                [0, 1, 0, 0]]

    示例 5: 实验数据质量控制

    实验测量失败时记录为 NaN
    experiment_data = [[1.23, nan, 1.34], [1.19, 1.28, nan], [nan, 1.25, 1.31]]
    print("实验数据:", experiment_data)
    print("无效测量:", is_nan_missing(experiment_data))
    #实验数据: [[1.23, nan, 1.34],
               [1.19, 1.28, nan],
               [nan, 1.25, 1.31]]
    #无效测量: [[0, 1, 0],
               [0, 0, 1],
               [1, 0, 0]]

    示例 6: 学生成绩记录

    缺考或未评分记录为 NaN
    grades = [[85, 92, nan, 78], [90, nan, 88, 85], [nan, 95, 87, 91]]
    print("成绩记录:", grades)
    print("缺考记录:", ismissing(grades))
    #成绩记录: [[85, 92, nan, 78],
               [90, nan, 88, 85],
               [nan, 95, 87, 91]]
    #缺考记录: [[0, 0, 1, 0],
               [0, 1, 0, 0],
               [1, 0, 0, 0]]

    示例 7: 库存管理系统

    未盘点或未知库存量
    inventory = [[150, nan, 200], [180, 190, nan], [nan, 210, 195]]
    print("库存数据:", inventory)
    print("未盘点项:", ismissing(inventory))
    #库存数据: [[150, nan, 200],
               [180, 190, nan],
               [nan, 210, 195]]
    #未盘点项: [[0, 1, 0],
               [0, 0, 1],
               [1, 0, 0]]

    示例 8: 气象数据质量评估

    传感器故障或数据传输中断
    weather_data = [[25.3, 65, 1013.2, nan], [24.8, nan, 1012.8, 2.1], [nan, 70, nan, 1.8]]
    print("气象数据:", weather_data)
    print("数据缺失:", ismissing(weather_data))
    #气象数据: [[25.3, 65, 1013.2, nan],
               [24.8, nan, 1012.8, 2.1],
               [nan, 70, nan, 1.8]]
    #数据缺失: [[0, 0, 0, 1],
               [0, 1, 0, 0],
               [1, 0, 1, 0]]

    示例 9: 电商用户行为数据

    用户未进行某些操作
    user_behavior = [[5, 3, nan, 2], [nan, 4, 1, nan], [2, nan, 3, 4]]
    print("用户行为:", user_behavior)
    print("缺失行为:", ismissing(user_behavior))
    #用户行为: [[5, 3, nan, 2],
              [nan, 4, 1, nan],
              [2, nan, 3, 4]]
    #缺失行为: [[0, 0, 1, 0],
               [1, 0, 0, 1],
               [0, 1, 0, 0]]

    示例 10: 生产质量检测数据

    某些检测项未执行
    quality_checks = [[8.5, nan, 9.1, 7.8], [7.9, 8.2, nan, 8.7], [nan, 8.9, 8.4, 8.6]]
    print("质量数据:", quality_checks)
    print("未检测项:", ismissing(quality_checks))
    #质量数据: [[8.5, nan, 9.1, 7.8],
               [7.9, 8.2, nan, 8.7],
               [nan, 8.9, 8.4, 8.6]]
    #未检测项: [[0, 1, 0, 0],
               [0, 0, 1, 0],
               [1, 0, 0, 0]]

    示例 11: 边缘情况测试

    print("全正常数据:", ismissing("[[1,2,3],[4,5,6]]"))
    print("全缺失数据:", ismissing("[[nan,nan],[nan,nan]]"))
    print("混合数据:", ismissing("[1, nan, 3, nan, 5]"))
    #全正常数据: [[0, 0, 0],
                [0, 0, 0]]
    #全缺失数据: [[1, 1],
                [1, 1]]
    #混合数据: [[0],
               [1],
               [0],
               [1],
               [0]]
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def is_nan_missing(input_str):
        """
        对标 MATLAB 的 ismissing 函数,查找输入矩阵中的缺失值(NaN)。

        参数:
        input_str: 字符串形式的矩阵输入,例如 "[[1, nan], [3, 4]]"

        返回:
        如果输入合法,返回对应的 0-1 矩阵(1 表示 NaN);
        否则返回错误信息字符串。
        """
        try:
            # 将输入字符串转换为 SymPy 表达式
            expr = sp.sympify(input_str)
            error = False
            result = None

            def check_nan(x):
                """检查元素是否为 NaN,返回 1(是)或 0(否)"""
                return 1 if x is sp.nan else 0

            # 检查表达式类型
            if isinstance(expr, tuple):
                # 元组类型无法处理,标记错误
                error = True
            else:
                # 尝试转换为矩阵
                A = sp.Matrix(expr) if isinstance(expr, list) else None

                if A is not None:
                    # 对每个元素应用 check_nan 函数
                    result = A.applyfunc(check_nan)
                else:
                    # 无法转换为矩阵,标记错误
                    error = True

            # 返回结果或错误信息
            return result if not error else f"输入错误: {input_str}"
        except Exception as e:
            return f"错误: {e}"


    ### 示例代码
    if __name__ == "__main__":
        # 示例 1: 输入列向量
        input_str1 = "[nan, 2, 3]"
        print(f"\n输入: {input_str1}")
        print("输出:", is_nan_missing(input_str1))
        # Matrix([[1],
        #         [0],
        #         [0]])
    
    
    分离方程中的变量或表达式

    isolate(eqn,expr)重新排列方程式eqn, 使表达式expr出现在左侧. 结果类似于求解eqn中的expr. 如果isolate无法isolate expr, 它会将所有包含expr的项移到左侧. 隔离的输出允许您使用subs从eqn中消除expr.

    eqn — 输入方程,符号方程

    expr — 要隔离的变量或表达式,符号变量,符号表达式

    示例 1: 物理运动学 - 位移公式

    print("输出:", isolate(s - u*t - 0.5*a*t**2, t))
    #输出: Eq(t, (-u - 1.4142135623731*sqrt(a*s + 0.5*u**2))/a)

    示例 2: 金融计算 - 复利公式

    print("输出:", isolate(A - P*(1 + r)**n, r))
    #输出: Eq(r, (A/P)**(1/n) - 1)

    示例 3: 几何学 - 圆面积公式

    print("输出:", isolate(A - pi*r**2, r))
    #输出: Eq(r, -sqrt(A)/sqrt(pi))

    示例 4: 热力学 - 理想气体定律

    print("输出:", isolate(P*V - n*R*T, T))
    #输出: Eq(T, P*V/(R*n))

    示例 5: 工程学 - 梁的弯曲公式

    print("输出:", isolate(M - E*I/R, R))
    #输出: Eq(R, E*I/M)

    示例 6: 统计学 - 正态分布

    print("输出:", isolate(z - (x - mu)/sigma, x))
    #输出: Eq(x, mu + sigma*z)

    示例 7: 化学 - 浓度计算

    print("输出:", isolate(C - n/V, V))
    #输出: Eq(V, n/C)

    示例 8: 相对论 - 时间膨胀

    print("输出:", isolate(t - t0/sqrt(1 - v**2/c**2), v))
    #输出: Eq(v, -c*sqrt(1 - t0**2/t**2))

    示例 9: 流体力学 - 伯努利方程

    print("输出:", isolate(P1 + 0.5*rho*v1**2 + rho*g*h1 - P2 - 0.5*rho*v2**2 - rho*g*h2, v2))
    #输出: Eq(v2, -1.4142135623731*sqrt(P1/rho - P2/rho + g*h1 - g*h2 + 0.5*v1**2))

    示例 10: 光学 - 透镜公式

    print("输出:", isolate(1/f - 1/u - 1/v, v))
    #输出: Eq(v, f*u/(-f + u))

    示例 11: 声学 - 多普勒效应

    print("输出:", isolate(f_observed - f_source*(v_sound + v_observer)/(v_sound + v_source), v_source))
    #输出: Eq(v_source, (-f_observed*v_sound + f_source*v_observer + f_source*v_sound)/f_observed)

    示例 12: 材料科学 - 胡克定律

    print("输出:", isolate(F - k*x, k))
    #输出: Eq(k, F/x)

    示例 13: 使用显式等式格式

    print("输出:", isolate(Eq(energy, mass*c**2), mass))
    #输出: Eq(mass, energy/c**2)

    示例 14: 复杂表达式 - 二次方程求根

    print("输出:", isolate(a*x**2 + b*x + c, x))
    #输出: Eq(x, (-b - sqrt(-4*a*c + b**2))/(2*a))

    示例 15: 三角函数方程

    print("输出:", isolate(sin(theta) - opposite/hypotenuse, theta))
    #输出: Eq(theta, pi - asin(opposite/hypotenuse))
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def isolate_expr_eqn(input_str):
        """
        对标MATLAB的isolate函数,将方程中的指定变量分离到等式一侧。

        参数:
        input_str: 字符串形式的输入,格式为"(方程, 变量)"。
                   方程可以是等式(如Eq(a*x + b, 0))或表达式(自动设为等于0)。
                   例如: "(a*x**2 + b*x + c, x)" 或 "(Eq(y, m*x + b), x)"

        返回:
        分离后的等式(如Eq(x, ...)),若失败返回错误信息字符串。
        """
        try:
            # 将输入字符串解析为SymPy表达式
            expr = sp.sympify(input_str, evaluate=False)

            # 验证是否为包含方程和变量的元组
            if not isinstance(expr, tuple) or len(expr) != 2:
                return f"输入格式错误: 需要形如'(方程, 变量)'的元组,实际输入: {input_str}"

            eqn, var = expr[0], expr[1]

            # 验证变量是否为符号
            if not var.free_symbols:
                return f"第二个元素必须是符号,实际类型: {type(var).__name__}"

            # 将表达式自动转换为等式(如果不是等式)
            if not isinstance(eqn, sp.Equality):
                eqn = sp.Eq(eqn, 0)  # 假设表达式等于0

            # 求解方程并提取第一个解
            solutions = sp.solve(eqn, var, dict=True)
            if not solutions:
                return f"无法分离变量{var}:方程无显式解"

            # 构建等式结果
            return sp.Eq(var, solutions[0][var])

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


    ### 示例代码 ###
    if __name__ == "__main__":
        # 示例1: 线性方程
        input_str1 = "(a*y(t)**2+b*c==0,y(t))"
        print(f"输入: {input_str1}")
        print("输出:", isolate_expr_eqn(input_str1))
        # Eq(y(t), -sqrt(-b*c/a))

        # 示例2: 二次方程(自动返回第一个解)
        input_str2 = "(a*x**2 + b*x + c, x)"
        print(f"\n输入: {input_str2}")
        print("输出:", isolate_expr_eqn(input_str2))
        # Eq(x, (-b - sqrt(-4*a*c + b**2))/(2*a))

        # 示例3: 显式等式输入
        input_str3 = "(Eq(y, m*x + b), x)"
        print(f"\n输入: {input_str3}")
        print("输出:", isolate_expr_eqn(input_str3))
        # Eq(x, (-b + y)/m)
    
    
    查找数据中的离群值

    TF = isoutlier(A,method) 返回一个逻辑数组,当在A的元素中检测到离群值时,该数组中与之对应的元素为true.

    如果 A 是矩阵,则 isoutlier 分别对 A 的每列进行运算。

    median — 离群值定义为与中位数相差超过三倍换算 MAD 的元素。换算 MAD 定义为 c*median(abs(A-median(A))),其中 c=-1/(sqrt(2)*erfcinv(3/2))。

    mean — 离群值定义为与均值相差超过三倍标准差的元素。此方法比 "median" 快,但没有它可靠。

    quartiles — 离群值定义为比上四分位数 (75%) 大 1.5 个四分位差以上或比下四分位数 (25%) 小 1.5 个四分位差以上的元素。当 A 中的数据不是正态分布时,此方法很有用。

    gesd — 使用广义极端 Student 化偏差检验检测离群值。此迭代方法与 "grubbs" 类似,但当有多个离群值互相遮盖时,此方法的执行效果更好。

    A — 数值向量,矩阵

    示例 1: 医疗健康 - 异常生理指标检测

    检测血压、心率等生理指标的异常值
    print("输出:", isoutlier("[120, 125, 118, 130, 200, 122, 119], quartiles"))
    #输出: [[0],
           [0],
           [0],
           [0],
           [1],
           [0],
           [0]]

    示例 2: 金融风控 - 异常交易检测

    检测信用卡交易的异常金额
    print("输出:", isoutlier("[[100, 150, 120], [80, 95, 110], [1000, 130, 140], [115, 125, 135]], mean"))
    #输出:
    #[[0,0,0],
      [0,0,0],
      [0,0,0],
      [0,0,0]]

    示例 3: 工业制造 - 产品质量异常检测

    检测产品尺寸的异常测量值
    print("输出:", isoutlier("[10.1, 10.2, 10.15, 9.8, 10.18, 11.5, 10.12, 10.16], median"))
    #输出:
    #[[0],
      [0],
      [0],
      [1],
      [0],
      [1],
      [0],
      [0]]

    示例 4: 环境监测 - 空气质量异常值

    检测PM2.5浓度的异常峰值
    print("输出:", isoutlier("[35, 42, 38, 28, 45, 150, 40, 33, 39, 180], grubbs"))
    #输出:
    #[[0],
      [0],
      [0],
      [0],
      [0],
      [0],
      [0],
      [0],
      [0],
      [0]]

    示例 5: 网络延迟 - 异常延迟检测

    检测网络延迟的异常峰值
    print("输出:", isoutlier("[50, 55, 48, 52, 200, 49, 53, 300, 51, 54], grubbs"))
    #输出:
    #[[0],
      [0],
      [0],
      [0],
      [0],
      [0],
      [0],
      [1],
      [0],
      [0]]

    示例 6: 生产能耗 - 异常能耗检测

    检测工厂能耗的异常值
    print("输出:", isoutlier("[[1000, 1050, 980], [1020, 995, 1015], [500, 1030, 1005], [1010, 2000, 990]], mean"))
    #输出:
    #[[0,0,0],
      [0,0,0],
      [0,0,0],
      [0,0,0]]
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    from scipy.stats import iqr, scoreatpercentile, t


    def is_outlier_data(input_str):
        """
        对标 MATLAB 的 isoutlier 函数,检测数据中的离群值。

        参数:
        input_str: 字符串形式的输入,可以是以下两种格式之一:
                   1. 直接输入矩阵,如 "[1, 2, 3]"
                   2. 元组格式 (矩阵, 方法),如 "(Matrix([[1,2],[3,4]]), 'quartiles')"
                   支持的方法: "median", "mean", "quartiles", "grubbs", "gesd"

        返回:
        与输入矩阵形状相同的 0-1 矩阵,1 表示离群值;
        若输入错误则返回错误信息字符串。
        """
        try:
            # 解析输入字符串为 SymPy 表达式
            expr = sp.sympify(input_str, evaluate=False)
            method = "median"  # 默认方法
            A = None

            # 处理元组输入 (矩阵, 方法)
            if isinstance(expr, tuple) and len(expr) == 2:
                matrix_part = sp.Matrix(expr[0]) if isinstance(expr[0], list) else None
                method_part = expr[1]
                if matrix_part is None or not method_part.free_symbols:
                    return f"输入格式错误: {input_str}"
                A = np.array(matrix_part.tolist(), dtype=float)
                method = str(method_part)
            # 处理单一矩阵输入
            else:
                matrix_part = sp.Matrix(expr) if isinstance(expr, list) else None
                if matrix_part is None:
                    return f"无法解析矩阵: {input_str}"
                A = np.array(matrix_part.tolist(), dtype=float)

            # 验证方法有效性
            valid_methods = ["median", "mean", "quartiles", "grubbs", "gesd"]
            if method.lower() not in valid_methods:
                return f"未知方法: {method},支持的方法: {valid_methods}"

            def detect_outliers(data_col, method_name):
                """对单列数据执行离群值检测"""
                n = len(data_col)
                outliers = np.zeros(n, dtype=int)

                # Median Absolute Deviation (MAD)
                if method_name == "median":
                    median = np.median(data_col)
                    mad = np.median(np.abs(data_col - median))
                    if mad == 0:
                        mad = 1e-6  # 避免除以零
                    threshold = 3 * 1.4826 * mad  # 常数缩放因子
                    outliers = (np.abs(data_col - median) > threshold).astype(int)

                # Mean and Standard Deviation
                elif method_name == "mean":
                    mean = np.mean(data_col)
                    std = np.std(data_col)
                    if std == 0:
                        std = 1e-6
                    threshold = 3 * std
                    outliers = (np.abs(data_col - mean) > threshold).astype(int)

                # Interquartile Range (IQR)
                elif method_name == "quartiles":
                    q1 = scoreatpercentile(data_col, 25)
                    q3 = scoreatpercentile(data_col, 75)
                    iqr_val = iqr(data_col)
                    lower = q1 - 1.5 * iqr_val
                    upper = q3 + 1.5 * iqr_val
                    outliers = ((data_col < lower) | (data_col > upper)).astype(int)

                # Grubbs' Test (单离群值)
                elif method_name == "grubbs":
                    if n < 3:
                        return outliers  # 样本过少不检测
                    mean = np.mean(data_col)
                    std = np.std(data_col)
                    if std == 0:
                        return outliers
                    # 找到最大偏差点
                    max_idx = np.argmax(np.abs(data_col - mean))
                    G = np.abs(data_col[max_idx] - mean) / std
                    # 计算临界值
                    t_crit = t.ppf(1 - 0.05 / (2 * n), n - 2)
                    threshold = (n - 1) / np.sqrt(n) * np.sqrt(t_crit ** 2 / (n - 2 + t_crit ** 2))
                    if G > threshold:
                        outliers[max_idx] = 1

                # Generalized ESD Test (多离群值)
                elif method_name == "gesd":
                    alpha = 0.05
                    max_outliers = min(n // 2, 10)  # 最多检测10个离群值
                    R = np.zeros(max_outliers)
                    lambdas = np.zeros(max_outliers)
                    for i in range(max_outliers):
                        mu = np.mean(data_col)
                        sigma = np.std(data_col)
                        if sigma == 0:
                            break
                        R[i] = np.max(np.abs(data_col - mu))
                        idx = np.argmax(np.abs(data_col - mu))
                        # 计算临界值
                        p = 1 - alpha / (2 * (n - i))
                        t_val = t.ppf(p, n - i - 2)
                        lambdas[i] = (n - i - 1) * t_val / np.sqrt((n - i - 2 + t_val ** 2) * (n - i))
                        if R[i] > lambdas[i] * sigma:
                            outliers[idx] = 1
                            data_col = np.delete(data_col, idx)
                        else:
                            break

                return outliers

            # 处理矩阵数据
            if A.ndim == 1:
                A = A.reshape(-1, 1)
            n_rows, n_cols = A.shape
            result = np.zeros((n_rows, n_cols), dtype=int)

            # 逐列检测离群值
            for col in range(n_cols):
                result[:, col] = detect_outliers(A[:, col], method.lower())

            # 转换为 SymPy 矩阵并保持原始形状
            result_matrix = sp.Matrix(result.tolist())
            if result_matrix.shape[1] == 1:
                result_matrix = result_matrix.T

            return result_matrix

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


    ### 示例代码 ###
    if __name__ == "__main__":
        # 示例1: 默认方法 (median)
        input_str1 = "[1, 2, 3, 100]"
        print(f"输入: {input_str1}")
        print("输出:", is_outlier_data(input_str1))
        # Matrix([[0, 0, 0, 1]])

        # 示例2: 使用quartiles方法
        input_str2 = "[[1, 2], [3, 4], [100, 200]], quartiles"
        print(f"\n输入: {input_str2}")
        print("输出:", is_outlier_data(input_str2))
        # Matrix([[0, 0],
        #         [0, 0],
        #         [0, 0]])

        # 示例3: Grubbs检验
        input_str3 = "[1, 2, 3, 4, 100], grubbs"
        print(f"\n输入: {input_str3}")
        print("输出:", is_outlier_data(input_str3))
        # Matrix([[0, 0, 0, 0, 1]])
    
    
    等值面是三维数据分布中具有相等值的各点的三维曲面表示.

    isosurface 函数通过连接空间的一个三维体内的常量值点来计算和绘制曲面.

    [faces,verts] = isosurface(V,isovalue,points,X,Y,Z) 在单独的数组中返回面和顶点。

    V — 三维体表达式,符号表达式

    isovalue — 指定等值面值,标量

    points — 采样点数

    X — x 轴坐标, 向量 | 三维数组

    Y — y 轴坐标数据, 向量 | 三维数组

    Z — z 轴坐标数据, 向量 | 三维数组

    faces — 面数据, 数组

    verts — 顶点数据,数组

    示例 1: 球面 - 基础几何形状

    result = isosurface(x**2 + y**2 + z**2, 1.0, 40, x=[-1.5,1.5], y=[-1.5,1.5], z=[-1.5,1.5])
    faces, vertices = result
    print(f"球面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #球面 - 顶点数: 3240, 面片数: 6476

    示例 2: 椭球面 - 变形几何

    result = isosurface((x/2)**2 + (y/1.5)**2 + (z/1)**2, 1.0, 40)
    faces, vertices = result
    print(f"椭球面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #椭球面 - 顶点数: 3872, 面片数: 7740

    示例 3: 环面 (甜甜圈形状) - 拓扑学

    result = isosurface((sqrt(x**2 + y**2) - 3)**2 + z**2 - 1, 0, 50, x=[-5,5], y=[-5,5], z=[-2,2])
    faces, vertices = result
    print(f"环面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #环面 - 顶点数: 7464, 面片数: 14928

    示例 4: 正弦曲面 - 波动现象

    result = isosurface(sin(x) + cos(y) + sin(z), 0, 50, x=[-2*pi,2*pi], y=[-2*pi,2*pi], z=[-2*pi,2*pi])
    faces, vertices = result
    print(f"正弦曲面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #正弦曲面 - 顶点数: 5678, 面片数: 10926

    示例 5: 分子轨道 - 量子化学

    result = isosurface(
        exp(-sqrt(x**2+y**2+z**2))*(1 - sqrt(x**2+y**2+z**2)), 0.1, 40, x=[-5,5], y=[-5,5], z=[-5,5])
    faces, vertices = result
    print(f"分子轨道 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #分子轨道 - 顶点数: 192, 面片数: 380

    示例 6: 心脏曲面 - 数学艺术

    result = isosurface(
        (2*x**2 + y**2 + z**2 - 1)**3 - (0.1*x**2 + y**2)*z**3, 0, 60, x=[-1.5,1.5], y=[-1.5,1.5], z=[-1.5,1.5])
    faces, vertices = result
    print(f"心脏曲面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #心脏曲面 - 顶点数: 6800, 面片数: 13596

    示例 7: 超二次曲面 - 计算机图形学

    result = isosurface((abs(x)**2.5 + abs(y)**2.5)**(1/2.5) + abs(z)**2.5 - 1, 0, 40)
    faces, vertices = result
    print(f"超二次曲面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #超二次曲面 - 顶点数: 1720, 面片数: 3436

    示例 8: 隐式曲面 - 代数曲面

    result = isosurface(
        (x**2 + y**2 + z**2 + 2*y - 1)*((x**2 + y**2 + z**2 - 2*y - 1)**2 - 8*z**2) + 16*x*z*(x**2 + y**2 + z**2 - 2*y - 1), 0, 60, x=[-3,3], y=[-3,3], z=[-2,2])
    faces, vertices = result
    print(f"克莱因瓶 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #克莱因瓶 - 顶点数: 16614, 面片数: 32928

    示例 9: 物理场等值面 - 电势分布

    result = isosurface(
        1/sqrt((x-1)**2 + y**2 + z**2) + 1/sqrt((x+1)**2 + y**2 + z**2), 0.5, 40, x=[-3,3], y=[-3,3], z=[-3,3])
    faces, vertices = result
    print(f"电势等值面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #电势等值面 - 顶点数: 3960, 面片数: 7096

    示例 10: 医学成像 - 器官表面重建

    result = isosurface(
        (x/2)**2 + (y/1.2)**2 + (z/1.8)**2 - 1, 0, 50, x=[-2.5,2.5], y=[-1.5,1.5], z=[-2,2])
    faces, vertices = result
    print(f"器官模型 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #器官模型 - 顶点数: 7840, 面片数: 15676

    示例 11: 地质学 - 地层界面

    result = isosurface(0.5*sin(2*x) + 0.3*cos(3*y) - z, 0, 60, x=[-2,2], y=[-2,2], z=[-1,1])
    faces, vertices = result
    print(f"地层界面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #地层界面 - 顶点数: 12666, 面片数: 24790

    示例 12: 建筑设计 - 自由曲面

    result = isosurface(
        sin(x)*cos(y) + sin(y)*cos(z) + sin(z)*cos(x), 0, 50, x=[-pi,pi], y=[-pi,pi], z=[-pi,pi])
    faces, vertices = result
    print(f"自由曲面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #自由曲面 - 顶点数: 7782, 面片数: 14880

    示例 13: 材料科学 - 晶体结构

    result = isosurface(cos(2*pi*x) + cos(2*pi*y) + cos(2*pi*z), 0, 40, x=[-2,2], y=[-2,2], z=[-2,2])
    faces, vertices = result
    print(f"晶体结构 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #晶体结构 - 顶点数: 23646, 面片数: 45884

    示例 14: 气象学 - 等压面

    result = isosurface(1000 - (x**2 + y**2)/100 - 10*z, 900, 50, x=[-50,50], y=[-50,50], z=[0,20])
    faces, vertices = result
    print(f"等压面 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #等压面 - 顶点数: 3724, 面片数: 7202

    示例 15: 参数化曲面 - 复杂形状

    result = isosurface(abs(x)**3 + abs(y)**3 + abs(z)**3 - 1, 0, 40)
    faces, vertices = result
    print(f"八面体变形 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #八面体变形 - 顶点数: 2064, 面片数: 4124

    示例 16: 多等值面 - 分层结构

    for level in [0.5, 1.0, 1.5]:
        result = isosurface(x**2 + y**2 + z**2, level, 30)
        faces, vertices = result
        print(f"半径{level}球壳 - 顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
    #半径0.5球壳 - 顶点数: 480, 面片数: 956
    #半径1.0球壳 - 顶点数: 984, 面片数: 1964
    #半径1.5球壳 - 顶点数: 1536, 面片数: 3068
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    from skimage import measure
    import regex, re


    def extract_functions_and_assignments(input_string):
        # 正则表达式匹配函数表达式
        '''
        function_pattern = r'\b\w+\((?:[^()]*|(?R))*\)'
        functions = regex.findall(function_pattern, input_string)

        # 正则表达式匹配变量赋值
        assignment_pattern = r'\b\w+\s*=\s*\[[^]]*\]'
        assignments = regex.findall(assignment_pattern, input_string)
        '''
        # 提取 assignments 列表

        assignment_pattern = r'\b\w+\s*=\s*\[[^]]*\]'
        assignments = regex.findall(assignment_pattern, input_string)

        # 从 input_string 中删除每个 assignment
        for assignment in assignments:
            input_string = input_string.replace(assignment, '')

        # 判断 input_string 是否是一个区间
        if '[' in input_string and ']' in input_string:
            # 如果是区间,使用 function_pattern 提取函数
            function_pattern = r'\b\w+\((?:[^()]*|(?R))*\)'
            functions = regex.findall(function_pattern, input_string)
        else:
            # 如果不是区间,按逗号分割为 functions 列表
            functions = input_string.split(',')

            # 移除首尾空格
            functions = [func.strip() for func in functions]

            # 移除空字符串
            functions = list(filter(None, functions))

        return functions, assignments


    def parse_and_generate_all_var_values(input_params):
        res_range = []
        res_expr = []
        for param in input_params:
            var_str = param
            var_str = var_str.replace(" ", "")

            match = re.match(r'(\w+)\s*=\s*\[([^]]+)\]', var_str)
            if not match:
                return res_range, res_expr

            var_name = match.group(1)
            var_values_str = match.group(2)
            try:
                var_values = eval(var_values_str)
                var_values = list(var_values)  # 如果只有一个元素,转换为列表
                var_values = var_values[:2]
                var_values.insert(0, var_name)
                res_range.append(var_values)
            except (ValueError, NameError):
                # Plot3D(sin(x^2+3y^2)/(0.1+r^2)+(x^2+5y^2)*exp(1-r^2)/2,r=[sqrt(x^2+y^2)])
                # eval(sqrt(x^2+y^2)) raise except
                res_expr.append([var_name, var_values_str])

        return res_range, res_expr


    def isosurface_data_volume(input_str):
        """
        对标 MATLAB 的 isosurface 函数,从三维隐式函数生成等值面数据

        参数:
        input_str: 输入字符串,格式为 "表达式,等值面值"(例如:"x**2 + y**2 + z**2, 1.0")
        grid_points: 每个维度的采样点数(默认30)
        x_range: x轴采样范围(默认(-2,2))
        y_range: y轴采样范围(默认(-2,2))
        z_range: z轴采样范围(默认(-2,2))

        返回:
        若成功则返回 (vertices, faces) 元组,否则返回错误信息字符串
        """
        try:
            functions, assignments = extract_functions_and_assignments(input_str)

            # 解析表达式、等值面值和网格点数
            if len(functions) < 1:
                return "Error: Missing expression"
            expr_str = functions[0]
            expr = sp.sympify(expr_str)

            isovalue = 1.0  # 默认等值面值
            if len(functions) >= 2:
                isovalue = float(functions[1])

            grid_points = 30  # 默认网格点数
            if len(functions) >= 3:
                grid_points = int(functions[2])

            # 解析变量范围
            assignment_range, _ = parse_and_generate_all_var_values(assignments)

            # 初始化变量范围
            x_range = [-2.0, 2.0]
            y_range = [-2.0, 2.0]
            z_range = [-2.0, 2.0]

            for var_info in assignment_range:
                var_name = var_info[0]
                if var_name == 'x' and len(var_info) >= 3:
                    x_range = [var_info[1], var_info[2]]
                elif var_name == 'y' and len(var_info) >= 3:
                    y_range = [var_info[1], var_info[2]]
                elif var_name == 'z' and len(var_info) >= 3:
                    z_range = [var_info[1], var_info[2]]

            # 生成坐标数组
            x = np.linspace(x_range[0], x_range[1], grid_points)
            y = np.linspace(y_range[0], y_range[1], grid_points)
            z = np.linspace(z_range[0], z_range[1], grid_points)

            # 创建三维网格
            X, Y, Z = np.meshgrid(x, y, z, indexing='ij')

            # 将SymPy表达式转换为数值计算函数
            x_sym, y_sym, z_sym = sp.symbols('x y z')
            expr_func = sp.lambdify((x_sym, y_sym, z_sym), expr, 'numpy')
            volume = expr_func(X, Y, Z)

            # 计算等值面
            verts, faces, _, _ = measure.marching_cubes(volume, isovalue)

            return faces, verts

        except ValueError as ve:
            return f"数值错误: {str(ve)}"
        except sp.SympifyError:
            return "表达式解析失败"
        except Exception as e:
            return f"未知错误: {str(e)}"


    ### 示例代码 ###
    if __name__ == "__main__":
        # 示例1: 球面 (x² + y² + z² = 1)
        print("示例1: 单位球面")
        result = isosurface_data_volume("x**2+y**2+z**2, 1.0, 30, x=[-1.5, 1.5], y=[-1.5, 1.5], z=[-1.5, 1.5]")
        if isinstance(result, tuple):
            vertices, faces = result
            print(vertices)
            # [[   2    1    0]
            #  [   4    3    0]
            #  [   4    0    1]
            #  ...
            #  [1798 1773 1775]
            #  [1798 1775 1799]
            #  [1799 1775 1766]]

            print(faces)
            # [[ 4.9652777 13.        14.       ]
            #  [ 5.        12.826388  14.       ]
            #  [ 5.        13.        13.652778 ]
            #  ...
            #  [24.034721  15.        16.       ]
            #  [24.034721  16.        14.       ]
            #  [24.034721  16.        15.       ]]

            print(f"顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
            # 顶点数: 3596, 面片数: 1800

        # 示例2: 圆柱面 (x² + y² = 0.5)
        print("\n示例2: 圆柱面")
        result = isosurface_data_volume("x**2 + y**2 - 0.5, 0, 50, z=[-3, 3]")
        if isinstance(result, tuple):
            vertices, faces = result
            print(f"顶点数: {vertices.shape[0]}, 面片数: {faces.shape[0]}")
            # 顶点数: 7056, 面片数: 3600
    
    
    确定哪些数组元素为质数

    TF = isprime(X) 返回与 X 大小相同的逻辑数组. 如果 X(i) 为质数,则 TF(i) 的值为 true. 否则值为 false.

    X — 输入值,标量,向量,实数数组,非负整数值

    示例 1: 基础质数判断

    print("2 →", isprime(2))        # 最小的质数
    print("17 →", isprime(17))      # 质数
    print("1 →", isprime(1))        # 不是质数
    print("4 →", isprime(4))        # 合数
    print("2.0 →", isprime(2.0))    # 浮点数形式的质数
    print("4.5 →", isprime(4.5))    # 非整数
    #2 → 1
    #17 → 1
    #1 → 0
    #4 → 0
    #2.0 → 1
    #4.5 → 0

    示例 2: 密码学应用 - RSA密钥生成

    rsa_candidates = [101, 103, 107, 109, 113, 127, 131, 137, 139, 149]
    print(f"RSA候选质数: {rsa_candidates}")
    print("质数检测:", isprime(rsa_candidates))
    #RSA候选质数: [101, 103, 107, 109, 113, 127, 131, 137, 139, 149]
    #质数检测: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

    示例 3: 计算机科学 - 哈希表大小选择

    hash_sizes = [53, 97, 193, 389, 769, 1543, 3079, 6151]
    print(f"哈希表大小候选: {hash_sizes}")
    print("质数验证:", isprime(hash_sizes))
    #哈希表大小候选: [53, 97, 193, 389, 769, 1543, 3079, 6151]
    #质数验证: [1, 1, 1, 1, 1, 1, 1, 1]

    示例 4: 数学教育 - 质数矩阵练习

    number_matrix = [[2, 4, 6], [3, 9, 11], [15, 17, 19]]
    print(f"数字矩阵: {number_matrix}")
    print("质数分布:", isprime(number_matrix))
    #数字矩阵: [[2, 4, 6], [3, 9, 11], [15, 17, 19]]
    #质数分布: [[1, 0, 0], [1, 0, 1], [0, 1, 1]]

    示例 5: 数论研究 - 梅森素数检测

    mersenne_numbers = [3, 7, 31, 127, 2047]
    print(f"梅森数: {mersenne_numbers}")
    print("梅森质数:", isprime(mersenne_numbers))
    #梅森数: [3, 7, 31, 127, 2047]
    #梅森质数: [1, 1, 1, 1, 0]

    示例 6: 安全协议 - 质数验证

    dh_parameters = [23, 47, 97, 197, 397]  # 常用的DH质数参数
    print(f"DH参数: {dh_parameters}")
    print("质数验证:", isprime(dh_parameters))
    #DH参数: [23, 47, 97, 197, 397]
    #质数验证: [1, 1, 1, 1, 1]

    示例 7: 财务计算 - 质数在算法中的应用

    transaction_ids = [1009, 1013, 1019, 1021, 1024, 1031, 1033]
    print(f"交易ID: {transaction_ids}")
    print("质数ID:", isprime(transaction_ids))
    #交易ID: [1009, 1013, 1019, 1021, 1024, 1031, 1033]
    #质数ID: [1, 1, 1, 1, 0, 1, 1]

    示例 8: 游戏开发 - 质数在随机数生成中的应用

    random_seeds = [17, 31, 59, 97, 157, 257, 419]
    print(f"随机种子: {random_seeds}")
    print("质数种子:", isprime(random_seeds))
    #随机种子: [17, 31, 59, 97, 157, 257, 419]
    #质数种子: [1, 1, 1, 1, 1, 1, 1]

    示例 9: 数据分析 - 质数数据过滤

    data_points = [[2, 3, 5], [7, 9, 11], [13, 15, 17], [19, 21, 23]]
    print(f"数据点矩阵: {data_points}")
    print("质数数据点:", isprime(data_points))
    #数据点矩阵: [[2, 3, 5], [7, 9, 11], [13, 15, 17], [19, 21, 23]]
    #质数数据点: [[1, 1, 1], [1, 0, 1], [1, 0, 1], [1, 0, 1]]

    示例 10: 符号数学测试

    symbolic_input = [[2, x], [y, 7]]
    print(f"符号表达式: {symbolic_input}")
    print("质数检测:", isprime(symbolic_input))
    #符号表达式: [[2, x], [y, 7]]
    #质数检测: [[1, None], [None, 1]]

    示例 11: 大型质数验证

    large_primes = [1009, 7919, 104729]
    print(f"大型质数: {large_primes}")
    print("验证结果:", isprime(large_primes))
    #大型质数: [1009, 7919, 104729]
    #验证结果: [1, 1, 1]

    示例 12: 质数分布模式分析

    consecutive_numbers = [90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
    print(f"连续数字: {consecutive_numbers}")
    print("质数位置:", isprime(consecutive_numbers))
    #连续数字: [90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
    #质数位置: [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]

    示例 13: 孪生质数检测

    twin_primes = [[3, 5], [5, 7], [11, 13], [17, 19], [29, 31], [41, 43]]
    print(f"孪生质数对: {twin_primes}")
    print("质数验证:", isprime(twin_primes))
    #孪生质数对: [[3, 5], [5, 7], [11, 13], [17, 19], [29, 31], [41, 43]]
    #质数验证: [[1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1]]

    示例 14: 质数在编码中的应用

    error_detection_codes = [7, 13, 19, 31, 61]  # 常用于校验算法的质数
    print(f"校验质数: {error_detection_codes}")
    print("质数状态:", isprime(error_detection_codes))
    #校验质数: [7, 13, 19, 31, 61]
    #质数状态: [1, 1, 1, 1, 1]

    示例 15: 边界情况测试

    print("0 →", isprime(0))          # 不是质数
    print("-5 →", isprime(-5))        # 负数不是质数
    print("1.0 →", isprime(1.0))      # 浮点数1
    print("2+3j →", isprime(2+3@i))    # 复数
    print("10000000019 →", isprime("10000000019"))  # 大质数
    #0 → 0
    #-5 → 0
    #1.0 → 0
    #2+3j → 0
    #10000000019 → 1

    示例 16: 混合数据类型矩阵

    mixed_matrix = [[2, 4.5, 7], [11, 15, 19.0], [23, 25, 29]]
    print(f"混合矩阵: {mixed_matrix}")
    print("质数检测:", isprime(mixed_matrix))
    #混合矩阵: [[2, 4.5, 7], [11, 15, 19.0], [23, 25, 29]]
    #质数检测: [[1, 0, 1], [1, 0, 1], [1, 0, 1]]

    示例 17: 质数在游戏平衡中的应用

    game_parameters = [17, 37, 73, 149, 293]  # 常用于游戏机制的质数
    print(f"游戏参数: {game_parameters}")
    print("质数参数:", isprime(game_parameters))
    #游戏参数: [17, 37, 73, 149, 293]
    #质数参数: [1, 1, 1, 1, 1]

    示例 18: 质数在分布式系统中的应用

    node_ids = [101, 103, 107, 109, 113, 127, 131, 137]
    print(f"节点ID: {node_ids}")
    print("质数ID:", isprime(node_ids))
    #节点ID: [101, 103, 107, 109, 113, 127, 131, 137]
    #质数ID: [1, 1, 1, 1, 1, 1, 1, 1]
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp

    def is_prime_number(input_str):
        """
        对标 MATLAB 的 isprime 函数,判断输入中的元素是否为质数。
        支持标量、矩阵和符号表达式。

        参数:
        input_str (str): 输入的数学表达式字符串,可以是标量、矩阵或符号。

        返回:
        - 对于数值元素:质数返回 1,非质数返回 0
        - 对于符号元素:返回 None
        - 错误时返回错误信息字符串

        示例:
        >>> is_prime_number("5")
        1
        >>> is_prime_number("[[2, 3], [5, 7]]")
        Matrix([[1, 1], [1, 1]])
        >>> is_prime_number("[[2, x], [4.5, 6]]")
        Matrix([[1, None], [0, 0]])
        """
        try:
            expr = sp.sympify(input_str)

            def evaluate_prime(x):
                """判断单个元素是否为质数"""
                # 处理符号表达式
                if x.free_symbols:
                    return None

                # 处理非数值类型
                if not x.is_number:
                    return None

                try:
                    # 转换为整数(处理浮点数的整数情况)
                    num = int(sp.N(x))
                    if sp.N(x) != num:  # 检查是否为非整数(如 4.5)
                        return 0
                    # 质数判断(质数定义需大于1)
                    return 1 if num > 1 and sp.isprime(num) else 0
                except:
                    return 0  # 转换失败的情况(如复数)

            # 处理标量输入
            return evaluate_prime(expr)

        except sp.SympifyError:
            return f"表达式解析失败: {input_str}"
        except Exception as e:
            return f"错误: {str(e)}"


    # 示例测试
    if __name__ == "__main__":
        # 标量测试
        print("标量测试:")
        print("5 →", is_prime_number("5"))
        # 1

        print("4 →", is_prime_number("4"))
        # 0

        print("2.0 →", is_prime_number("2.0"))
        # 1

        print("x →", is_prime_number("x"))
        # None
    
    
    确定矩阵是对称矩阵还是斜对称矩阵.

    如果 A 是对称矩阵,则tf = issymmetric(A) 返回逻辑值 1 (true). 否则,将返回逻辑值 0 (false).

    tf = issymmetric(A,skewOption)指定测试的类型. 将skewOption指定为"skew" 可确定A是否为斜对称矩阵

    A — 输入数组,数组
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    from sympy import simplify


    def is_symmetric_matrix(input_str):
        """
        对标MATLAB issymmetric函数,判断矩阵的对称性

        参数:
        input_str - 矩阵描述字符串,支持两种格式:
                   1. 纯矩阵:"[[0,1],[1,0]]"
                   2. 带类型标记:"(Matrix([[0,1],[-1,0]]), 'skew')"

        返回:
        1 - 满足对称性要求
        0 - 不满足对称性要求
        错误信息字符串 - 输入不合法时

        示例:
        >>> is_symmetric_matrix("[[1,2],[2,1]]")
        1
        >>> is_symmetric_matrix("(Matrix([[0,1],[-1,0]]), 'skew')")
        1
        >>> is_symmetric_matrix("[[1,2],[3,4]]")
        0
        """
        try:
            expr = sp.sympify(input_str, evaluate=False)
            result = None

            # 处理带选项的元组输入 (矩阵, 'skew')
            if isinstance(expr, tuple) and len(expr) == 2:
                M = sp.Matrix(expr[0]) if isinstance(expr[0], list) else None
                option = str(expr[1]).lower()

                if M is None or option not in ['skew']:
                    return f"输入错误: {input_str}"

                # 斜对称矩阵检查:M^T = -M
                # 使用符号化简处理浮点精度问题
                is_skew = simplify(M.T + M).is_zero_matrix
                result = 1 if is_skew else 0

            # 处理普通矩阵输入
            else:
                M = sp.Matrix(expr) if isinstance(expr, list) else None
                if M is None:
                    return f"输入错误: {input_str}"

                # 对称矩阵检查:M^T = M
                # 使用内置方法处理符号和数值矩阵
                result = 1 if M.is_symmetric() else 0

            return result

        except sp.SympifyError:
            return f"语法错误: 无法解析输入 '{input_str}'"
        except Exception as e:
            return f"运行时错误: {str(e)}"


    # --------------------------
    # 测试用例
    # --------------------------
    if __name__ == "__main__":
        # 测试对称矩阵
        print("对称矩阵测试:")
        print(is_symmetric_matrix("[[1, 2], [2, 1]]"))
        # 1

        print(is_symmetric_matrix("[[a, b], [b, a]]"))
        # 1

        # 测试斜对称矩阵
        print("\n斜对称矩阵测试:")
        print(is_symmetric_matrix("[[0, 2], [-2, 0]], skew"))
        # 1

        print(is_symmetric_matrix("[[0, 1.0], [-1.0001, 0]], skew"))
        # 0

        # 测试非对称矩阵
        print("\n非对称矩阵测试:")
        print(is_symmetric_matrix("[[1, 2], [3, 4]]"))
        # 0
    
    
    确定矩阵是否为下三角矩阵.

    如果A是下三角矩阵,则tf = istril(A) 返回逻辑值1 (true). 否则,将返回逻辑值0 (false).

    A — 输入数组,数组
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def is_lower_triangular(input_str):
        """
           判断输入是否为下三角矩阵(对标MATLAB istril函数)

           参数:
               input_str: 输入字符串,可以是矩阵、标量或符号表达式

           返回:
               1: 是下三角矩阵
               0: 不是下三角矩阵
               str: 错误信息

           示例:
               >>> is_lower_triangular("[[1,0],[2,3]]")
               1
               >>> is_lower_triangular("[[1,2],[3,4]]")
               0
               >>> is_lower_triangular("5")
               1
               >>> is_lower_triangular("[[1,2],[3,4,5]]")
               '输入错误: [[1,2],[3,4,5]]'
        """
        try:
            expr = sp.sympify(input_str)

            # 尝试转换为矩阵
            if isinstance(expr, list):
                M = sp.Matrix(expr)
                # 非方阵直接返回0
                if M.is_square and M.is_lower:
                    return 1
                else:
                    return 0

            # 处理标量和符号(视为1x1矩阵)
            if isinstance(expr, sp.Basic) and expr.is_Atom:
                return 1

            return f"输入错误: {input_str}"

        except Exception as e:
            return f"Error: {e}"


    # 示例测试
    if __name__ == "__main__":
        test_cases = [
            "[[1,0],[2,3]]",
            # 1

            "[[1,2],[3,4]]",
            # 0

            "5",
            # 1

            "a",
            # 1

            "[1,2]",
            # 0

            "[[1,2,3],[4,5,6]]"
            # 0
        ]

        for case in test_cases:
            print(f"输入: {case:<20} 结果: {is_lower_triangular(case)}")
    
    
    确定矩阵是否为上三角矩阵.

    如果A是上三角矩阵,则tf = istril(A) 返回逻辑值1 (true). 否则,将返回逻辑值0 (false).

    A — 输入数组,数组
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    import matplotlib.pyplot as plt


    def is_upper_triangular(input_str):
        """
           判断输入是否为上三角矩阵(对标MATLAB istriu函数)

           参数:
               input_str: 输入字符串,可以是矩阵、标量或符号表达式

           返回:
               1: 是上三角矩阵
               0: 不是上三角矩阵
               str: 错误信息

           示例:
               >>> is_upper_triangular("[[1,0],[2,3]]")
               1
               >>> is_upper_triangular("[[1,2],[3,4]]")
               0
               >>> is_upper_triangular("5")
               1
               >>> is_upper_triangular("[[1,2],[3,4,5]]")
               '输入错误: [[1,2],[3,4,5]]'
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            # 尝试转换为矩阵
            if isinstance(expr, list):
                M = sp.Matrix(expr)
                # 非方阵直接返回0
                if M.is_square and M.is_upper:
                    return 1
                else:
                    return 0

            # 处理标量和符号(视为1x1矩阵)
            if isinstance(expr, sp.Basic) and expr.is_Atom:
                return 1

            return f"输入错误: {input_str}"
        except Exception as e:
            return f"Error: {e}"


    # 示例测试
    if __name__ == "__main__":
        test_cases = [
            "[[17,24,1,8,15],[0,5,7,14,16],[0,0,13,20,22],[0,0,0,21,3],[0,0,0,0,9]]",
            # 1

            "[[1,2],[3,4]]",
            # 0

            "5",
            # 1

            "a",
            # 1

            "[1,2]",
            # 0

            "[[1,2,3],[4,5,6]]"
            # 0
        ]

        for case in test_cases:
            print(f"输入: {case:<20} 结果: {is_upper_triangular(case)}")
    
    
    逆z变换

    iztrans(F) 返回 F 的逆 Z 变换. 默认情况下, 独立变量为 z, 变换变量为 n. 如果 F 不包含 z, iztrans 将使用函数 symvar.

    F — 输入, 符号表达式, 符号函数

    示例1:单位阶跃序列

    result = iztrans(z/(z-1))
    print(f"输出: {result}")
    #输出: Piecewise((1, n >= 0))
    #物理意义: 表示离散时间系统中的单位阶跃响应

    示例2:指数衰减序列

    result = iztrans(1/(1 - a/z))
    print(f"输出: {result}")
    #输出: Piecewise((a**n, n >= 0))
    #物理意义: 表示衰减因子为a的指数序列,常用于系统稳定性分析

    示例3:斜坡序列

    result = iztrans(z/(z-1)**2)
    print(f"输出: {result}")
    #输出: Piecewise((n, n >= 0))
    #物理意义: 表示随时间线性增长的序列

    示例4:二阶系统

    result = iztrans(z**2/(z**2 - 1.5*z + 0.5))
    print(f"输出: {result}")
    #输出: Piecewise((2 - 1/2**n, n >= 0))
    #物理意义: 二阶离散系统的冲激响应,用于控制系统分析

    示例5:带延迟的系统

    result = iztrans(1/z**3 * z/(z-0.5))
    print(f"输出: {result}")
    #输出: Piecewise((-8*UnitImpulse(n) - 2*UnitImpulse(n - 2) - 4*UnitImpulse(n - 1) + 8/2**n, n >= 0))
    #物理意义: 具有3个采样周期延迟的一阶系统

    示例6:数字滤波器系数

    result = iztrans((0.1*z)/(z - 0.9))
    print(f"输出: {result}")
    #输出: Piecewise((1/(10*(10/9)**n), n >= 0))
    #物理意义: 一阶IIR数字滤波器的冲激响应

    示例7:控制系统补偿器

    result = iztrans(Kp + Ki*z/(z-1) + Kd*(z-1)/z)
    print(f"输出: {result}")
    #输出: Piecewise((Kd*(UnitImpulse(n) - UnitImpulse(n - 1)) + Ki + Kp*UnitImpulse(n), n >= 0))
    #物理意义: 离散PID控制器的差分方程形式
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import lcapy as lc


    def inverse_z_transform(input_str):
        """执行逆Z变换,支持矩阵输入

        参数:
            input_str (str): 输入表达式字符串或矩阵描述

        返回:
            SymPy表达式/矩阵 或 错误信息字符串"""
        try:
            # 将输入字符串转换为SymPy表达式
            expr = sp.sympify(input_str)
            # 转换为Lcapy表达式以使用其符号运算功能
            error = False
            result = None

            def eval_inv_ztrans(ele):
                """执行单个表达式的逆Z变换"""
                f_expr = lc.expr(str(ele))
                if f_expr.free_symbols:
                    return f_expr.IZT()  # 调用Lcapy的逆Z变换方法
                else:
                    return None  # 常数项无需变换

            # 矩阵处理分支
            if isinstance(expr, list):
                matrix = sp.Matrix(expr)
                rows, cols = matrix.shape
                # 对矩阵中每个元素递归执行逆Z变换
                result = sp.Matrix(rows, cols, lambda i, j: eval_inv_ztrans(matrix[i, j]))
            elif expr.free_symbols:
                # 单表达式处理
                result = eval_inv_ztrans(expr)
            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:单表达式逆Z变换")
        expr_str = "1/(1 - 1/z)"
        result = inverse_z_transform(expr_str)
        print(f"输入: {expr_str}")
        print(f"输出: {result}")
        # Piecewise((1, n >= 0))
        print("\n" + "=" * 50 + "\n")

        # 示例2:矩阵变换
        print("示例2:矩阵逆Z变换")
        matrix_input = "[2*z/(z-2)**2, 1/(a*z)]"
        result = inverse_z_transform(matrix_input)
        print("\n逆Z变换结果:")
        print(result)
        # Matrix([[DiscreteTimeDomainExpression(Piecewise((2*2**(n - 1)*n, n >= 0)))],
        #         [DiscreteTimeDomainExpression(UnitImpulse(n - 1)/a)]])