首页 函数目录

    范德蒙矩阵

    A = vander(v) 返回范德蒙矩阵,以使其列是向量v的幂.

    v - 输入, 数值向量, 支持复数
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    def vander_type_matrix(input_str):
        """
        生成范德蒙矩阵 (对标 MATLAB 的 vander 函数)

        参数:
        input_str (str): 数学表达式字符串,支持以下形式:
            - 向量: 如 "[1,2,3]" 或 "[[1],[2],[3]]"(行/列向量均可)
            生成的矩阵列顺序为 [x^(n-1), x^(n-2), ..., x^0]

        返回:
            sp.Matrix or str:
            - 成功时返回 SymPy 矩阵
            - 失败时返回错误信息字符串 (以"错误:"开头)

        示例:
            >>> vander_type_matrix("[1, 2, 3]")
            Matrix([
                [1, 1, 1],
                [4, 2, 1],
                [9, 3, 1]])

            >>> vander_type_matrix("[[1], [2], [3]]")  # 列向量输入
            Matrix([
                [1, 1, 1],
                [4, 2, 1],
                [9, 3, 1]])

            >>> vander_type_matrix("5")  # 标量视为单元素向量
            Matrix([[1]])
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None

            def validate_vector(A):
                """验证输入是否为有效向量并转换为 numpy 数组"""
                # 检查矩阵维度
                rows, cols = A.shape
                if rows > 1 and cols > 1:
                    raise ValueError("输入必须为向量(行或列数为1)")

                # 尝试转换为数值数组
                try:
                    x = np.array(A, dtype=float).ravel()
                except TypeError:
                    raise ValueError("元素必须为数值类型")

                return x

            # 处理标量输入(视为单元素向量)
            if expr.is_Number:
                result = np.vander([float(expr)], increasing=False)

            else:
                error = True

            return sp.Matrix(result.tolist()) if not error else f"输入错误: {input_str}"

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


    # 标量输入
    print(vander_type_matrix("6"))
    # Matrix([[1.00000000000000]])
    
    
    方差

    V = var(A) 返回A中沿大小不等于1的第一个数组维度的元素的方差.

    如果A是一个观测值向量,则方差为标量.

    V = var(A,w) 指定权重方案.如果w=0(默认值),则V按观测值数量-1实现归一化.如果w=1,则它按观测值数量实现归一化. w也可以是包含非负元素的权重向量.在这种情况下,w的长度必须等于var将作用于的维度的长度.

    A - 输入数组, 向量, 矩阵

    w - 粗细, 0,1,向量
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    import numpy as np


    def variance_array(input_str):
        """
        对标 MATLAB 的 var 函数,计算矩阵的方差。

        参数:
        input_str: 输入的字符串表达式,可以是矩阵或元组形式。
        例如:
        - "[[1,2], [3,4]]":计算样本方差(默认 ddof=1)
        - "([[1,2], [3,4]], 0)":计算样本方差(ddof=1)
        - "([[1,2], [3,4]], 1)":计算总体方差(ddof=0)
        - "([[1,2], [3,4]], [1,1])":加权方差(权重为 [1,1])

        返回:
        SymPy 矩阵表示的方差结果或错误信息。
        """
        try:
            expr = sp.sympify(input_str)
            error = False
            result = None
            M = None
            weight = None
            ddof = None  # 方差计算的自由度调整,对应 np.var 的 ddof 参数

            # 解析输入表达式
            if isinstance(expr, tuple):
                if len(expr) != 2:
                    error = True
                else:
                    m_part, w_part = expr
                    # 转换为矩阵
                    M = sp.Matrix(m_part) if isinstance(m_part, list) else None
                    if M is None:
                        error = True
                    else:
                        # 处理第二个参数:权重或 ddof 标志
                        if isinstance(w_part, (int, sp.Integer)):
                            # MATLAB 中 0 表示样本方差(N-1),1 表示总体方差(N)
                            w_val = int(w_part)
                            if w_val in [0, 1]:
                                ddof = 1 - w_val  # 转换为 np.var 的 ddof 参数
                            else:
                                error = True
                        else:
                            # 尝试转换为权重向量
                            W = sp.Matrix(w_part) if isinstance(w_part, list) else None
                            if W is not None:
                                W_np = np.array(W, dtype=float)
                                # 检查权重是否与数据行数匹配
                                if W_np.size == M.shape[0]:
                                    weight = W_np.flatten()
                                else:
                                    error = True
                            else:
                                error = True
            else:
                # 单个矩阵输入,默认使用样本方差(ddof=1)
                M = sp.Matrix(expr) if isinstance(expr, list) else None
                if M is not None:
                    ddof = 1
                else:
                    error = True

            if not error and M is not None:
                data = np.array(M, dtype=float)
                if weight is not None:
                    # 计算加权方差
                    weighted_mean = np.average(data, axis=0, weights=weight)
                    result = np.average((data - weighted_mean) ** 2, axis=0, weights=weight)
                elif ddof is not None:
                    # 计算普通方差
                    result = np.var(data, axis=0, ddof=ddof)
                else:
                    error = True
            else:
                error = True

            return sp.sympify(result) if not error else f"输入错误: {input_str}"

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


    # 示例代码
    if __name__ == "__main__":
        # 示例 1: 样本方差(默认,ddof=1)
        input1 = "[[1,2], [3,4]]"
        print(f"示例1 {input1} 的结果:")
        print(variance_array(input1))
        # [2.0, 2.0]

        # 示例 2: 总体方差(ddof=0)
        input2 = "([[1,2], [3,4]], 1)"
        print(f"\n示例2 {input2} 的结果:")
        print(variance_array(input2))
        # [1.0, 1.0]

        # 示例 3: 加权方差(权重为 [1,1])
        input3 = "([[1,2], [3,4]], [1,1])"
        print(f"\n示例3 {input3} 的结果:")
        print(variance_array(input3))
        # [1.0, 1.0]
    
    
    向量范数

    N = vecnorm(A) 返回 A 的 2-范数或欧几里德范数:

    如果 A 是向量,则 vecnorm 返回该向量的范数。

    如果 A 是矩阵,则 vecnorm 返回每一列的范数。

    N = vecnorm(A,p) 计算广义向量 p-范数。

    N = vecnorm(A,p,dim) 沿维度 dim 运算。此维度的大小将减少至 1,而所有其他维度的大小保持不变。
    
    # Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
    # Licensed under the MIT License.
    import sympy as sp
    from sympy import sympify, oo, Max, Min


    def vector_norm(input_str):
        """
        计算向量或矩阵的范数,类似于MATLAB的vecnorm函数。

        参数:
        input_str (str): 输入的字符串,代表vecnorm的参数,例如 "A, p, dim"。

        返回:
        sympy.Array 或 sympy.Expr: 计算得到的范数结果(标量、行向量或列向量)。

        异常:
        ValueError: 如果输入无法解析或参数无效。
        """
        try:
            # 解析输入字符串为参数元组
            args = sympify(input_str)
            if not isinstance(args, tuple):
                args = (args,)

            # 处理第一个参数 A
            if len(args) == 0:
                raise ValueError("至少需要一个输入参数")
            A = sp.Array(args[0]) if isinstance(args[0], list) else None
            if A is None:
                raise ValueError("第一个参数必须是有效的矩阵或可以转换为矩阵的形式")

            # 判断是否为向量(一维数组)
            is_vector = len(A.shape) == 1
            if not is_vector and len(A.shape) != 2:
                raise ValueError("输入必须是向量或二维矩阵")

            # 处理 p 参数(范数类型)
            p = 2
            if len(args) >= 2:
                p = args[1]

            # 处理 dim 参数(计算维度)
            dim = 1
            if len(args) >= 3:
                dim = args[2]
                if dim not in (1, 2):
                    raise ValueError("dim 参数必须是 1 或 2")

            # 计算向量范数
            if is_vector:
                elements = A
                if p == oo:  # 无穷范数 (最大值)
                    norm = Max(*[abs(x) for x in elements])
                elif p == -oo:  # 负无穷范数 (最小值)
                    norm = Min(*[abs(x) for x in elements])
                else:  # p-范数
                    norm = sum(abs(x) ** p for x in elements) ** (1 / p)
                return norm.evalf()  # 计算数值结果

            # 计算矩阵范数
            else:
                m, n = A.shape  # 使用 shape 属性获取维度
                norms = []

                # 按列计算 (dim=1)
                if dim == 1:
                    for j in range(n):
                        col = A[:, j]
                        if p == oo:
                            col_norm = Max(*[abs(x) for x in col])
                        elif p == -oo:
                            col_norm = Min(*[abs(x) for x in col])
                        else:
                            col_norm = sum(abs(x) ** p for x in col) ** (1 / p)
                        norms.append(col_norm.evalf())  # 计算数值结果
                    return sp.Array(norms).reshape(1, n)  # 行向量

                # 按行计算 (dim=2)
                else:
                    for i in range(m):
                        row = A[i, :]
                        if p == oo:
                            row_norm = Max(*[abs(x) for x in row])
                        elif p == -oo:
                            row_norm = Min(*[abs(x) for x in row])
                        else:
                            row_norm = sum(abs(x) ** p for x in row) ** (1 / p)
                        norms.append(row_norm.evalf())  # 计算数值结果
                    return sp.Array(norms).reshape(m, 1)  # 列向量

        except Exception as e:
            raise ValueError(f"错误发生:{str(e)}")


    # 测试示例
    if __name__ == "__main__":
        # 示例1:计算向量的2-范数
        vector = [1, 2, 3]
        print("向量范数:", vector_norm(f"{vector}, 2"))
        # 3.74165738677394

        # 示例2:计算矩阵的列2-范数
        matrix = [[1, 2], [3, 4]]
        result = vector_norm(f"{matrix}, 2, 1")
        print("矩阵列范数:", result)
        # [[3.16227766016838, 4.47213595499958]]

        # 示例3:计算矩阵的行无穷范数
        result = vector_norm(f"{matrix}, oo, 2")
        print("矩阵行无穷范数:", result)
        # [[2.0], [4.0]]
    
    
    向量密度图

    VectorDensityPlot(expression1,...)向量场图 和 密度着色图 的结合体。它在一个二维平面上,同时使用两种视觉元素来呈现一个向量场(例如风速场、流体流速场、电磁场).

    1. 流体力学与涡旋场:

    经典涡旋:顺时针旋转流场,等强度同心圆环

    VectorDensityPlot(-y, x)

    剪切流:水平流速随y轴正弦变化,产生层状剪切

    VectorDensityPlot(sin(y), 0)

    2. 电磁场与势场:

    磁偶极子: 双极磁场线,从N极到S极

    VectorDensityPlot(2*x*y, y^2 - x^2)

    均匀电场: 垂直方向强度随x变化的电场

    VectorDensityPlot(0, cos(x))

    电荷阵列: 周期性正负电荷分布的电场

    VectorDensityPlot(sin(x)cos(y), cos(x)sin(y))

    3. 非线性动力学:

    极限环: 单位圆环吸引子,内部向外流/外部向内流

    VectorDensityPlot(y + x*(1-x^2-y^2), -x + y*(1-x^2-y^2))

    鞍点场: X方向发散/Y方向收敛的典型鞍点

    VectorDensityPlot(x, -y)

    混沌系统: 扭曲的螺旋轨迹,具有多个不稳定焦点

    VectorDensityPlot(sin(y) - 0.3*x, cos(x) + 0.3*y)

    4. 数学特殊场:

    梯度场: 标量场 f(x,y)=sin(x)cos(y) 的梯度

    VectorDensityPlot(cos(x)cos(y), -sin(x)sin(y))

    哈密顿系统: 守恒系统,沿椭圆/双曲线流动

    VectorDensityPlot(y^2 - x^2, 2*x*y)

    分形场: 高频振荡产生的自相似结构

    VectorDensityPlot(sin(2y) - cos(3x), sin(3x) + cos(2y))

    5. 自然现象模拟:

    地转风场: 科里奥利力作用下的气旋流场

    VectorDensityPlot(-y/(x^2+y^2+1), x/(x^2+y^2+1))

    心脏电传导: 从原点向外扩散的兴奋波

    VectorDensityPlot(x*exp(-x^2-y^2), y*exp(-x^2-y^2))

    星系旋臂: 微分旋转的星系盘流场

    VectorDensityPlot(-y/(1+x^2), x/(1+y^2))
    
    VectorPlot(u(x,y), v(x,y))

    VectorPlot(u(x,y,T), v(x,y,T))

    通过在空间(通常是平面)上规则或不规则分布的采样点处绘制箭头来表示向量场. 多维空间(通常是2D或3D)中每一点上都有一个向量的情况。它直观地展现了某种“方向”和“强度”在空间中的分布。

    箭头的方向:精确地表示该点处向量的方向。

    箭头的长度(有时也用颜色或箭头粗细辅助表示):表示该点处向量的大小(模)。长度越长(或颜色越暖/越深),表示向量越大.

    x, y -- 空间坐标

    T -- 动画参数

    向量场图

    1. 流体力学与涡旋场:

    经典涡旋:顺时针旋转流场,等强度同心圆环

    VectorPlot(-y, x)

    剪切流:水平流速随y轴正弦变化,产生层状剪切

    VectorPlot(sin(y), 0)

    2. 电磁场与势场:

    磁偶极子: 双极磁场线,从N极到S极

    VectorPlot(2*x*y, y^2 - x^2)

    均匀电场: 垂直方向强度随x变化的电场

    VectorPlot(0, cos(x))

    电荷阵列: 周期性正负电荷分布的电场

    VectorPlot(sin(x)cos(y), cos(x)sin(y))

    3. 非线性动力学:

    极限环: 单位圆环吸引子,内部向外流/外部向内流

    VectorPlot(y + x*(1-x^2-y^2), -x + y*(1-x^2-y^2))

    鞍点场: X方向发散/Y方向收敛的典型鞍点

    VectorPlot(x, -y)

    混沌系统: 扭曲的螺旋轨迹,具有多个不稳定焦点

    VectorPlot(sin(y) - 0.3*x, cos(x) + 0.3*y)

    4. 数学特殊场:

    梯度场: 标量场 f(x,y)=sin(x)cos(y) 的梯度

    VectorPlot(cos(x)cos(y), -sin(x)sin(y))

    哈密顿系统: 守恒系统,沿椭圆/双曲线流动

    VectorPlot(y^2 - x^2, 2*x*y)

    分形场: 高频振荡产生的自相似结构

    VectorPlot(sin(2y) - cos(3x), sin(3x) + cos(2y))

    5. 自然现象模拟:

    地转风场: 科里奥利力作用下的气旋流场

    VectorPlot(-y/(x^2+y^2+1), x/(x^2+y^2+1))

    心脏电传导: 从原点向外扩散的兴奋波

    VectorPlot(x*exp(-x^2-y^2), y*exp(-x^2-y^2))

    星系旋臂: 微分旋转的星系盘流场

    VectorPlot(-y/(1+x^2), x/(1+y^2))

    时变向量场图

    1. 流体动力学模拟:

    旋转流场: 中心旋涡强度周期性变化,产生脉动旋转

    VectorPlot(-y, x + sin(T))

    行波流场: X/Y方向独立传播的正弦波形成移动的网格图案

    VectorPlot(sin(x-T), cos(y+T))

    双涡旋对流: 两个反向涡旋周期性增强/减弱

    VectorPlot(sin(x)*cos(y+T) - 0.5*y,cos(x+T)*sin(y) + 0.5*x)

    2. 电磁场模拟:

    行波磁场: 磁场线以波的形式向右上角传播

    VectorPlot(-sin(y-T), cos(x+T))

    3. 相空间动力学:

    混沌吸引子: 参数T变化导致规则流→混沌流的转变

    VectorPlot(sin(y) + T*cos(x),cos(x) - T*sin(y))

    分岔流场: T增加时出现霍普夫分岔(焦点→极限环)

    VectorPlot(T*x - y - x*(x²+y²),x + T*y - y*(x²+y²))

    4. 特殊效果场:

    螺旋波发射: 从原点发射的螺旋波阵面

    VectorPlot(-y + T*cos(x), x + T*sin(y))
    
    向量场三维图

    VectorPlot3D(f(x),f(y),f(z))在三维空间的每一个点上,都有一个箭头(或其它标记),箭头的方向表示向量场在该点的方向,箭头的长度和颜色通常表示该点向量的大小(模)。

    1. 电偶极子的电场 (Electrodynamics)

    这是经典电磁学中的一个基础模型。一个正电荷和一个负电荷相隔一小段距离,它们共同产生的电场就是一个向量场。

    数学描述: 正电荷在 (0, 0, d),负电荷在 (0, 0, -d)。空间任意一点 (x, y, z) 的电场强度 E 是两个点电荷电场的矢量叠加。

    VectorPlot3D(-x/((x^2+y^2+z^2+0.3)^(3/2)),-y/((x^2+y^2+z^2+0.3)^(3/2)),2z/((x^2+y^2+z^2+0.3)^(3/2)),x=[-2,2],y=[-2,2],z=[-2,2])

    2. 流体速度场:涡流 (Fluid Dynamics)

    想象一个沿着 z 轴旋转的涡流,比如龙卷风或搅拌杯子中的水。流体的速度方向是切向的。

    数学描述: 速度向量 v 在点 (x, y, z) 的分量为 {-y, x, 0}。

    这个向量在 XY 平面内总是垂直于位置向量 (x, y),从而形成旋转。Z 分量为 0 表示没有垂直运动(这是一个理想的平面涡流)。

    VectorPlot3D(-y,x,z,x=[-1,1],y=[-1,1],z=[-0.5,0.5])

    3. 引力场 (Newtonian Gravity)

    一个均匀球体(如地球)产生的引力场。

    数学描述: 根据万有引力定律,引力指向球心,其大小与到球心距离的平方成反比。

    在点 (x, y, z) 的引力向量 g ∝ {-x, -y, -z} / (x^2 + y^2 + z^2)^(3/2)

    VectorPlot3D(-x/((x^2+y^2+z^2+0.1)^(3/2)),-y/((x^2+y^2+z^2+0.1)^(3/2)),-z/((x^2+y^2+z^2+0.1)^(3/2)),x=[-2,2],y=[-2,2],z=[-2,2])