首页 函数目录

    隐式导数

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

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

    x — 取导数的变量

    n — 导数的顺序(默认为1)
    
    # 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'.
    
    # 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 — 沿其运算的维度, 正整数标量
    
    # 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 — 逆变换列数, 正整数标量
    
    # 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 — 逆变换维度的长度, 正整数向量
    
    # 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 的每一行的左右两半部分进行交换。
    
    # 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。
    
    # 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 — 输入, 符号表达式, 符号函数
    
    # 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.
    
    # 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 —— 上限,数字,符号数,符号变量,符号表达式,符号函数
    
    # 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 的上限,实数,复数
    
    # 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 的上限,实数,复数
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def integrate_multi_equation(input_str):
        """
        对标MATLAB integral2函数的多重数值积分实现

        参数:
        input_str: 输入字符串,格式为:
                   "函数表达式, 变量1下限, 变量1上限, 变量2下限, 变量2上限,..."
                   示例:"x*y, 0, 1, y, 0, 1-x"

        **kwargs: 传递给scipy积分函数的参数 (如epsabs, epsrel等)

        返回:
        成功时返回积分结果和误差组成的元组,失败时返回错误信息

        示例:
        >>> integrate_multi_equation("x*y, 0, 1, 0, 1-x")
        (0.04166666666666668, 4.623514334137052e-16)
        """
        try:
            # 将输入字符串转换为SymPy表达式
            expr = sp.sympify(input_str)
            # 初始化错误标志为False
            error = False
            # 初始化积分结果为None
            result = None

            def multi_integral(f, *args):
                # 提取传递的所有积分范围,由于每个积分范围由下限和上限两个值组成,所以除以2
                num_ranges = len(args) // 2

                # 找到函数f中的符号变量,并按符号名称排序
                symbols_in_f = sorted(f.free_symbols, key=lambda s: str(s))

                # 检查符号数量和积分范围是否匹配,如果积分范围数量多于符号变量数量,抛出异常
                if num_ranges > len(symbols_in_f):
                    raise ValueError("传入的积分范围比符号变量多。")

                # 从外到内嵌套integrate,处理多重积分
                for i in range(num_ranges):
                    # 依次取出符号变量
                    symbol = symbols_in_f[i]
                    # 取出当前符号变量的积分下限
                    lower_bound = args[2 * i]
                    # 取出当前符号变量的积分上限
                    upper_bound = args[2 * i + 1]
                    # 对函数f关于当前符号变量进行积分,积分区间为[下限, 上限]
                    f = sp.integrate(f, (symbol, lower_bound, upper_bound))

                return f

            # 检查expr是否为元组
            if isinstance(expr, tuple):
                # 检查元组的第一个元素是否包含符号变量
                if expr[0].free_symbols:
                    # 取出元组的第一个元素作为被积函数
                    F = expr[0]
                    # 取出元组中除第一个元素外的其他元素作为积分范围
                    args = expr[1:]
                    # 调用multi_integral函数进行多重积分
                    result = multi_integral(F, *args)
                else:
                    # 如果元组的第一个元素不包含符号变量,设置错误标志为True
                    error = True
            else:
                # 如果expr不是元组,设置错误标志为True
                error = True

            # 如果没有错误,返回积分结果;否则返回错误信息
            return result if not error else f"输入错误: {input_str}"
        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 的上限,实数,复数
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp


    def integrate_multi_equation(input_str):
        """
        对标MATLAB integral2函数的多重数值积分实现

        参数:
        input_str: 输入字符串,格式为:
                   "函数表达式, 变量1下限, 变量1上限, 变量2下限, 变量2上限,..."
                   示例:"x*y, 0, 1, y, 0, 1-x"

        **kwargs: 传递给scipy积分函数的参数 (如epsabs, epsrel等)

        返回:
        成功时返回积分结果和误差组成的元组,失败时返回错误信息

        示例:
        >>> integrate_multi_equation("x*y, 0, 1, 0, 1-x")
        (0.04166666666666668, 4.623514334137052e-16)
        """
        try:
            # 将输入字符串转换为SymPy表达式
            expr = sp.sympify(input_str)
            # 初始化错误标志为False
            error = False
            # 初始化积分结果为None
            result = None

            def multi_integral(f, *args):
                # 提取传递的所有积分范围,由于每个积分范围由下限和上限两个值组成,所以除以2
                num_ranges = len(args) // 2

                # 找到函数f中的符号变量,并按符号名称排序
                symbols_in_f = sorted(f.free_symbols, key=lambda s: str(s))

                # 检查符号数量和积分范围是否匹配,如果积分范围数量多于符号变量数量,抛出异常
                if num_ranges > len(symbols_in_f):
                    raise ValueError("传入的积分范围比符号变量多。")

                # 从外到内嵌套integrate,处理多重积分
                for i in range(num_ranges):
                    # 依次取出符号变量
                    symbol = symbols_in_f[i]
                    # 取出当前符号变量的积分下限
                    lower_bound = args[2 * i]
                    # 取出当前符号变量的积分上限
                    upper_bound = args[2 * i + 1]
                    # 对函数f关于当前符号变量进行积分,积分区间为[下限, 上限]
                    f = sp.integrate(f, (symbol, lower_bound, upper_bound))

                return f

            # 检查expr是否为元组
            if isinstance(expr, tuple):
                # 检查元组的第一个元素是否包含符号变量
                if expr[0].free_symbols:
                    # 取出元组的第一个元素作为被积函数
                    F = expr[0]
                    # 取出元组中除第一个元素外的其他元素作为积分范围
                    args = expr[1:]
                    # 调用multi_integral函数进行多重积分
                    result = multi_integral(F, *args)
                else:
                    # 如果元组的第一个元素不包含符号变量,设置错误标志为True
                    error = True
            else:
                # 如果expr不是元组,设置错误标志为True
                error = True

            # 如果没有错误,返回积分结果;否则返回错误信息
            return result if not error else f"输入错误: {input_str}"
        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 —— 待整合的差异
    
    # 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,
                        '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,
                        '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 - 分段多项式, 结构体
    
    # 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 域范围外的函数值, 标量
    
    # 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 域范围外的函数值, 标量
    
    # 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 — 插入的点, 向量 | 矩阵
    
    # 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 包含查询点的坐标。
    
    # 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
    
    # 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 — 标量
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np
    from scipy.optimize import fsolve


    def inverse_gudermannian(input_str):
        '''
        返回z的逆古德曼函数。
        :param input_str:
        :return:
        '''
        try:
            # 将输入字符串转换为SymPy表达式
            # 将输入字符串转换为SymPy表达式
            y = sp.sympify(input_str)

            # 定义古德曼函数
            def gudermannian(x):
                return 2 * sp.atan(sp.exp(x)) - sp.pi / 2

            # 如果y是符号性的(包含变量),则返回隐式符号方程
            if y.free_symbols:
                x = list(y.free_symbols)[0]
                return sp.Eq(gudermannian(x), y)

            # 如果y是数值,则使用fsolve进行数值反演
            else:
                # 定义要求解的方程
                def equation(x):
                    return gudermannian(x) - y

                # 使用fsolve定义数值求解器
                def solve_equation_with_fsolve(equation, max_attempts=3, tolerance=1e-6):
                    last_solution = None
                    for _ in range(max_attempts):
                        # 随机生成初始猜测
                        initial_guess = np.random.uniform(-10, 10)

                        # 将符号方程转换为数值函数
                        equation_num = sp.lambdify(sp.Symbol('x'), equation(sp.Symbol('x')))

                        # 使用fsolve求解方程
                        solution = fsolve(equation_num, initial_guess)

                        # 检查方案的准确性
                        if np.isclose(equation_num(solution), 0, atol=tolerance):
                            return solution

                        last_solution = solution
                    return last_solution

                # 求解方程并返回数值解
                solution = solve_equation_with_fsolve(equation)
                return solution[0]

        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 — 矩阵的阶次,非负整数标量
    
    # 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:
                result = hilbert_matrix_symbolic(expr)
            else:
                error = True

            return result if not error else f"输入错误: {input_str}"
        except Exception as e:
            return f"Error: {e}"


    # --------------------------
    # 示例代码
    # --------------------------
    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 — 维度顺序,行向量
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    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 — 上带宽,非负整数标量
    
    # 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 — 上限,标量或向量
    
    # 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 — 向量,矩阵
    
    # 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 — 要隔离的变量或表达式,符号变量,符号表达式
    
    # 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 — 数值向量,矩阵
    
    # 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 — 顶点数据,数组
    
    # 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 — 输入值,标量,向量,实数数组,非负整数值
    
    # 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 — 输入, 符号表达式, 符号函数
    
    # 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)]])