如何解决“ LoadError:DimensionMismatch(“无法广播数组以减少维数”)”

时间:2019-02-11 11:13:18

标签: indexing julia ode differentialequations.jl

我想用数值方法求解以下两个耦合的微分方程:

d/dt Phi_i = 1 - 1/N * \sum_{j=1}^N( k_{ij} sin(Phi_i - Phi_j + a) 
d/dt k_{ij} = - epsilon * (sin(Phi_i - Phi_j + b) + k_{ij}

具有已定义的起始条件phi_0(具有N个条目的1-dim数组)和k_0(具有NxN个条目的2-dim数组)

我尝试过:使用DifferentialEquations.js,建立初始起始条件矩阵u0 = hcat(Phi_0,k_0)(2-dim数组,Nx(N + 1)),并以某种方式定义第一个方程适用于到第一列(在我的代码[:,1]中),第二个等式适用于其他列(在我的代码[:,2:N + 1]中)。

using Distributions
using DifferentialEquations

N = 100
phi0 = rand(N)*2*pi
k0 = rand(Uniform(-1,1), N,N)

function dynamics(du, u, p, t)
    a = 0.3*pi 
    b = -0.53*pi 
    epsi = 0.01 

    du[:,1] .= 1 .- 1/N .* sum.([u[i,j+1] * sin(u[i,1] - u[j,1] + a) for i in 1:N, j in 1:N], dims=2)
    du[:,2:N+1] .= .- epsi .* [sin(u[i,1] - u[j,1] + b) + u[i,j+1] for i in 1:N, j in 1:N]
end

u0 = hcat(phi0, k0)
tspan = (0.0, 200.0)
prob = ODEProblem(dynamics, u0, tspan)
sol = solve(prob)

运行以下代码行会导致以下错误:

LoadError: DimensionMismatch ("cannot broadcast array to have fewer dimensions")in expression starting at line 47 (which is sol = solve(prob)) 

我是Julia的新手,我不确定我是否正朝着正确的方向前进。请帮我!

1 个答案:

答案 0 :(得分:1)

首先,编辑第一个程序包,即Distributions而不是Distribution,我花了一段时间查找错误xD

主要问题是第一个方程式中的.=。执行此操作时,您不只是将新值分配给数组,还创建了view。我无法确切地解释什么是视图,但是我可以告诉您的是,当您进行这种分配时,左侧和右侧必须具有相同的类型。

例如:

N = 100
u = rand(N,N+1)
du = rand(N,N+1)

julia> u[:,1] .= du[:,1]
100-element view(::Array{Float64,2}, :, 1) with eltype Float64:
 0.2948248997313967 
 0.2152933893895821 
 0.09114453738716022
 0.35018616658607926
 0.7788869975259098 
 0.2833659299216609 
 0.9093344091412392 
...

结果是view而不是向量。使用此语法,左侧和右侧必须具有相同的类型,而在您的示例中不会发生这种情况。请注意,rand(5)rand(5,1)的类型在Julia中是不同的:第一个是Array{Float64,1},另一个是Array{Float64,2}。在您的代码中,d[:,1]Array{Float64,1},而1 .- 1/N .* sum.([u[i,j+1] * sin(u[i,1] - u[j,1] + a) for i in 1:N, j in 1:N], dims=2)Array{Float64,2},这就是为什么它不起作用的原因。您有两种选择,将等号更改为:

du[:,1] = ...

或者:

du[:,1] .= 1 .- 1/N .* sum.([u[i,j+1] * sin(u[i,1] - u[j,1] + a) for i in 1:N, j in 1:N], dims=2)[:,1]

第一个选择只是基本分配,第二个选择使用view方式并匹配双方的类型。