范德蒙矩阵
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]]