Julia 在一个对象上存储多个矩阵
我有一个简单的计量经济学/统计学练习,我正试图在Julia中实现。我以前从未使用过Julia,我已经用R编写了这段代码,但我似乎无法翻译代码 这里是概要:我有一个内环,其中对于固定的N,我从分布中提取K个样本,并将它们存储在一个矩阵中,即nxk。我对两个矩阵执行此操作,它们将每个矩阵的每列相乘(获得2x1向量),然后存储在一个2xk矩阵中 在那之后,我做了一个外循环,比如说,5个不同的N值。最后,我想有5个不同的矩阵,它们是2xk,这样我就可以绘制它们了。我搞不懂的是如何有效地存储这个矩阵。在R中,我会简单地将它们放在一个列表中,并将它们一一调用以进行计算Julia 在一个对象上存储多个矩阵,julia,Julia,我有一个简单的计量经济学/统计学练习,我正试图在Julia中实现。我以前从未使用过Julia,我已经用R编写了这段代码,但我似乎无法翻译代码 这里是概要:我有一个内环,其中对于固定的N,我从分布中提取K个样本,并将它们存储在一个矩阵中,即nxk。我对两个矩阵执行此操作,它们将每个矩阵的每列相乘(获得2x1向量),然后存储在一个2xk矩阵中 在那之后,我做了一个外循环,比如说,5个不同的N值。最后,我想有5个不同的矩阵,它们是2xk,这样我就可以绘制它们了。我搞不懂的是如何有效地存储这个矩阵。在R
using Distributions
using StatsBase
J = 500
N = [10 100 500 1000 10000]
i = 1
b = ones(3,J)
for n in N
x = ones(n,J)
e = ones(n,J)
y = ones(n,J)
for j = 1:J
x[:,j] = rand(Normal(3,1),n)
y[:,j] = 3 + 2.5*x[:,j] + e[:,j]
x = [y[:,j] x[:,j]]
b[:,j] = inv(y'*x)*(x'*y[:,j])
end
i = i + 1
i
end
我试过使用这个代码,但它似乎根本不起作用。对于下面的循环工作,我甚至无法使其变得简单:
for i = 1:10
x = ones(i, 10)
end
我得到一个
错误:UndefVarError:x未定义
。你们能帮帮我吗?你们只要把它们放在一个向量{Matrix}
中,一个矩阵向量。
但是Julia中的一个常见范例是定义一个函数f
,它做你想要的,然后在N上广播该函数,即通过调用a=f.(N)
(N应该是向量,而不是矩阵,顺便说一句,所以在数字之间使用逗号,而不是空格)
因此,假设您要存储5个矩阵,它们是2 x K,K值不同。事实上,根据口味、风格、方便性等,您可以使用多种方法来实现。以下是一些示例,其中K值从20到24不等:
# a python-style list comprehension
mymatrices = [randn(K,2) for K in 20:24]
# a function broadcast over the array
f(k) = randn(k,2)
mymatrices = f.(20:24)
# a Vector with preallocated elements
mymatrices = Vector{Matrix{Float64}}(5)
for (i, k) in enumerate(20:24) #enumerate is smart
mymatrices[i] = randn(k, 2)
end
# a Vector that grows dynamically
mymatrices = Matrix{Float64}[] # shorter optional syntax for an empty vector
for (i, k) in enumerate(20:24)
push!(mymatrices, randn(k, 2))
end
# map with an anonymous function
mymatrices = map(k -> randn(k,2), 20:24)
您只需将它们放入一个
向量{Matrix}
,一个矩阵向量。
但是Julia中的一个常见范例是定义一个函数f
,它做你想要的,然后在N上广播该函数,即通过调用a=f.(N)
(N应该是向量,而不是矩阵,顺便说一句,所以在数字之间使用逗号,而不是空格)
因此,假设您要存储5个矩阵,它们是2 x K,K值不同。事实上,根据口味、风格、方便性等,您可以使用多种方法来实现。以下是一些示例,其中K值从20到24不等:
# a python-style list comprehension
mymatrices = [randn(K,2) for K in 20:24]
# a function broadcast over the array
f(k) = randn(k,2)
mymatrices = f.(20:24)
# a Vector with preallocated elements
mymatrices = Vector{Matrix{Float64}}(5)
for (i, k) in enumerate(20:24) #enumerate is smart
mymatrices[i] = randn(k, 2)
end
# a Vector that grows dynamically
mymatrices = Matrix{Float64}[] # shorter optional syntax for an empty vector
for (i, k) in enumerate(20:24)
push!(mymatrices, randn(k, 2))
end
# map with an anonymous function
mymatrices = map(k -> randn(k,2), 20:24)
循环工作正常,内部正确设置了
x
,但循环结束后x
超出范围,因此未定义
julia> for i = 1:10
x = ones(i, 10)
end
julia> x
ERROR: UndefVarError: x not defined
如果您先创建它:
julia> x = Array{Float64}(10, 10);
julia> for i = 1:10
x = ones(i, 10)
end
julia> x
10×10 Array{Float64,2}:
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
然后它保持在范围内。循环工作正常,
x
在内部设置正确,但是x
在循环结束后超出范围,因此未定义
julia> for i = 1:10
x = ones(i, 10)
end
julia> x
ERROR: UndefVarError: x not defined
如果您先创建它:
julia> x = Array{Float64}(10, 10);
julia> for i = 1:10
x = ones(i, 10)
end
julia> x
10×10 Array{Float64,2}:
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
然后它就在范围内。所以在你们的帮助和更多的谷歌搜索之后,我想出了这段代码。不确定这是否违反了StackOverflow的目的,但我正在发布我的答案。如果你们有时间,请批评,这似乎有点太冗长了,我相信有一个更有效的方法来做到这一点
using Distributions
N = [10, 100, 500, 1000, 10000]
J = 500
bet = Vector{Matrix{Float64}}()
for n in N
b = Array{Float64, 2}(3, J)
for j = 1:J
x1 = Array{Float64, 2}(n,J)
x2 = Array{Float64, 2}(n,J)
epsilon = Array{Float64, 2}(n,J)
y = Array{Float64, 2}(n,J)
cons = ones(n)
x1[:,j] = rand(Normal(3,1),n)
x2[:,j] = rand(Normal(-1,1),n)
epsilon[:,j] = rand(Normal(0,1),n)
y[:,j] = 3 + 2.5*x1[:,j] + 4*x2[:,j] + epsilon[:,j]
x = [cons x1[:,j] x2[:,j]]
b[:,j] = inv(x'*x)*(x'*y[:,j])
end
push!(bet, b)
end
所以在你们的帮助和更多的谷歌搜索之后,我想出了这个代码。不确定这是否违反了StackOverflow的目的,但我正在发布我的答案。如果你们有时间,请批评,这似乎有点太冗长了,我相信有一个更有效的方法来做到这一点
using Distributions
N = [10, 100, 500, 1000, 10000]
J = 500
bet = Vector{Matrix{Float64}}()
for n in N
b = Array{Float64, 2}(3, J)
for j = 1:J
x1 = Array{Float64, 2}(n,J)
x2 = Array{Float64, 2}(n,J)
epsilon = Array{Float64, 2}(n,J)
y = Array{Float64, 2}(n,J)
cons = ones(n)
x1[:,j] = rand(Normal(3,1),n)
x2[:,j] = rand(Normal(-1,1),n)
epsilon[:,j] = rand(Normal(0,1),n)
y[:,j] = 3 + 2.5*x1[:,j] + 4*x2[:,j] + epsilon[:,j]
x = [cons x1[:,j] x2[:,j]]
b[:,j] = inv(x'*x)*(x'*y[:,j])
end
push!(bet, b)
end
发布一些工作代码总是更好的。甚至你所指的R代码。顺便说一句,最后的for循环是有效的。重新启动Julia并在REPL中输入它,看看会发生什么。另外,你不能做
inv(y'*x)
因为你只能取平方矩阵的逆矩阵sorry,它应该是b[:.j]=inv(x'*x)。发布一些工作代码总是更好的。甚至你所指的R代码。顺便说一句,最后的for循环是有效的。重新启动Julia并在REPL中输入它,看看会发生什么。另外,你不能做inv(y'*x)
因为你只能取一个平方矩阵的逆矩阵sorry,它应该是b[:.j]=inv(x'*x)你能给我一个简单的例子吗?我不理解julia的逻辑,我试着在内部循环之后简单地做“a[i]=b”,但那不起作用。如何定义可以存储N个矩阵的空数组?a=Matrix{Float64}[]
或a=Vector{Matrix{Float64}}()
。但我已经用另一种方法更新了我的答案。这有点难回答,因为我看不出你的代码如何与你描述的相符。。。你想把什么矩阵放在向量中?内环创建一个2xk矩阵,外环对不同的N值(用于计算内环矩阵)执行5次。最后,我希望在一个对象中有5个2xK矩阵,能够调用其中任何一个,然后使用它们的线条绘制直方图。非常感谢Michael!这真的很有帮助,我已经发布了我自己的代码作为答案,但我显然接受你的!你能给我举个简单的例子吗?我不理解julia的逻辑,我试着在内部循环之后简单地做“a[i]=b”,但那不起作用。如何定义可以存储N个矩阵的空数组?a=Matrix{Float64}[]
或a=Vector{Matrix{Float64}}()
。但我已经用另一种方法更新了我的答案。这有点难回答,因为我看不出你的代码如何与你描述的相符。。。你想把什么矩阵放在向量中?内环创建一个2xk矩阵,外环对不同的N值(用于计算内环矩阵)执行5次。最后,我希望在一个对象中有5个2xK矩阵,能够调用其中任何一个,然后使用它们的线条绘制直方图。非常感谢Michael!这真的很有帮助,我已经发布了我自己的代码作为答案,但我显然接受你的!相反,这里鼓励你回答自己的问题。不要害怕用左边的绿色勾选按钮接受你自己的答案。相反,这里鼓励回答你自己的问题。使用左边的绿色复选标记按钮,不要害怕接受自己的答案。