Julia使用Manopt优化双随机矩阵流形时遇rand!方法错误
问题分析与解决
问题描述
目标是在双随机矩阵流形上寻找某函数的最小值,使用Manopt包时,即使将目标函数设为0,代码仍无法运行,报错:
MethodError: rand!(::TaskLocalRNG, ::AbstractManifold, ::SubArray{Float64, 1, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}) is ambiguous
原代码如下:
using Random using Graphs using Manopt using Manifolds using LinearAlgebra n = 8 G = DiGraph(n) for i = 1:n add_edge!(G, i%n +1, (i+1)%n +1) add_edge!(G, (i+1)%n +1, i%n +1) end A = adjacency_matrix(G) P_0 = A / 2 M = MultinomialMatrices(n, n) f(M, p) = 0 #sum((P_0 - p).^ 2) particle_swarm(M, f)
错误原因
- 流形类型误用:
MultinomialMatrices(n, n)对应的是行随机矩阵流形(仅保证每行元素和为1),而双随机矩阵要求行和、列和均为1,正确的流形应为DoublyStochasticMatrices(n)。 - 目标函数参数顺序错误:Manopt中优化方法要求目标函数的参数顺序为
f(p)(仅接收流形上的点)或f(p, M)(点在前,流形在后),原代码中f(M, p)的顺序会导致参数传递混乱。
修正后的代码
using Random using Graphs using Manopt using Manifolds using LinearAlgebra n = 8 G = DiGraph(n) for i = 1:n add_edge!(G, i%n +1, (i+1)%n +1) add_edge!(G, (i+1)%n +1, i%n +1) end A = adjacency_matrix(G) P_0 = A / 2 # 使用正确的双随机矩阵流形 M = DoublyStochasticMatrices(n) # 修正目标函数参数顺序,或直接定义为仅接收点的函数 f(p) = 0 # 后续可替换为sum((P_0 - p).^2)等复杂函数 # 显式指定初始点,优化过程更可控 particle_swarm(M, f; initial_point=P_0)
补充说明
- 若目标函数需要用到流形对象,可定义为
f(p, M) = ...,Manopt会自动将流形参数传递给函数。 - 显式设置
initial_point可以避免流形随机初始化可能出现的异常,尤其适合有严格约束的流形类型。
内容的提问来源于stack exchange,提问作者Zsombor Varkonyi
相关产品推荐
相关产品推荐

