如何在Python中求解x*y=c的最小范数解(x为向量、y为矩阵)
问题解决方案:向量分解为向量与矩阵的乘积,同时最小化范数
要解决将n维向量c分解为m维向量x和m×n矩阵y(满足x@y = c)且使||x||² + ||y||_F²最小的问题,我们可以通过代数推导得到闭式解,无需依赖随机种子或复杂符号求解。
核心思路
我们的目标是最小化||x||² + ||y||_F²(||·||_F为矩阵Frobenius范数),约束条件为x@y = c。通过将y表示为x与某个向量的外积形式,可将双变量优化问题转化为单变量问题,进而找到最小值对应的解:
- 设
y = xᵀ @ d(d为n维向量),代入约束得(x@xᵀ)d = c,即||x||² d = c,因此d = c / ||x||²(当||x||≠0时)。 - 将
d代入目标函数,化简后得到||x||² + ||c||² / ||x||²,对||x||²求导可知最小值在||x|| = √||c||时取得。 - 此时
d = c / ||c||,代入y的表达式即可得到对应的矩阵。
为了得到确定的解,我们选择构造稀疏的x(仅第一个元素非零),这样实现最简单且满足需求。
Python 实现代码
import numpy as np def minimal_norm_decompose(c, m): """ 将n维向量c分解为m维向量x和m×n矩阵y,满足x@y = c,且||x||² + ||y||_F²最小 参数: c: 形状为(n,)的numpy数组,输入向量 m: 整数,x的维度(即y的行数) 返回: x: 形状为(m,)的numpy数组 y: 形状为(m, n)的numpy数组 """ n = c.size norm_c = np.linalg.norm(c) # 处理零向量特殊情况 if norm_c < 1e-12: return np.zeros(m), np.zeros((m, n)) # 构造x:第一个元素为√||c||,其余为0 x = np.zeros(m) x[0] = np.sqrt(norm_c) # 构造y:第一行为c/√||c||,其余行为0 y = np.zeros((m, n)) y[0] = c / np.sqrt(norm_c) return x, y
验证示例
# 生成测试用100维向量 c = np.random.rand(100) # 分解为30维x和30×100矩阵y x, y = minimal_norm_decompose(c, 30) # 验证约束条件是否满足 print(np.allclose(x @ y, c)) # 输出True,说明x@y与c几乎相等 # 验证范数和是否为最小值 norm_sum = np.linalg.norm(x)**2 + np.linalg.norm(y)**2 print(np.allclose(norm_sum, 2 * np.linalg.norm(c))) # 输出True
说明
- 该方法是通用的,适用于任意维度的
c、任意指定的m(x的维度)。 - 解的范数和是固定的最小值
2||c||,不同的x方向(非稀疏的x)也能达到这个最小值,但我们选择的稀疏解最易实现且可靠。 - 避免了随机种子依赖,完全基于输入向量
c计算,结果确定可控。
内容的提问来源于stack exchange,提问作者Thiago2104
相关产品推荐
相关产品推荐

