Julia 如何快速重塑阵列
在下面的代码中,我使用Julia Optim包来寻找关于目标函数的最优矩阵。 不幸的是,提供的优化函数只支持向量,因此我必须在将矩阵传递给优化函数之前将其转换为向量,并且在目标函数中使用时将其转换回Julia 如何快速重塑阵列,julia,Julia,在下面的代码中,我使用Julia Optim包来寻找关于目标函数的最优矩阵。 不幸的是,提供的优化函数只支持向量,因此我必须在将矩阵传递给优化函数之前将其转换为向量,并且在目标函数中使用时将其转换回 function opt(A0,X) I1(A) = sum(maximum(X*A,1)) function transform(A) # reshape matrix to vector return reshape(A,prod(size(A)
function opt(A0,X)
I1(A) = sum(maximum(X*A,1))
function transform(A)
# reshape matrix to vector
return reshape(A,prod(size(A)))
end
function transformback(tA)
# reshape vector to matrix
return reshape(tA, size(A0))
end
obj(tA) = -I1(transformback(tA))
result = optimize(obj, transform(A0), method = :nelder_mead)
return transformback(result.minimum)
end
我认为Julia每次都在为此分配新的空间,而且感觉很慢,那么解决这个问题的更有效的方法是什么呢?只要数组包含被认为是不可变的元素,其中包括所有原语,那么数组的元素就包含在一个大的连续的内存块中。因此,您可以打破维度规则,简单地将二维数组视为一维数组,这就是您想要做的。所以你不需要重塑,但我不认为重塑是你的问题 数组是列主数组和连续数组 考虑以下函数
function enumerateArray(a)
for i = 1:*(size(a)...)
print(a[i])
end
end
该函数将a的所有维度相乘,然后假设a是一维的,从1循环到该数字
当您将
julia> a = [ 1 2; 3 4; 5 6]
3x2 Array{Int64,2}:
1 2
3 4
5 6
结果是
julia> enumerateArray(a)
135246
这说明了两件事
b = reshape(a,6);
julia> size(b)
(6,)
julia> size(a)
(3,2)
julia> b[4]=100
100
julia> a
3x2 Array{Int64,2}:
1 100
3 4
5 6
因此,设置b的第四个元素将设置a的(1,2)元素
至于整体的缓慢程度
I1(A) = sum(maximum(X*A,1))
将创建一个新数组
您可以使用几个宏来跟踪此@profile和@time。时间将另外记录分配的内存量,并且可以放在任何表达式前面
比如说
julia> A = rand(1000,1000);
julia> X = rand(1000,1000);
julia> @time sum(maximum(X*A,1))
elapsed time: 0.484229671 seconds (8008640 bytes allocated)
266274.8435928134
@profile记录的统计数据是使用profile.print()输出的。此外,Optim中的大多数方法实际上允许您提供数组,而不仅仅是向量。您可以将
nelder\u mead
函数概括为同样的功能。是否应该有类似于重塑函数的功能,而不是创建/复制到一个新对象,只是为已经存在的数据提供一个重塑的接口?它确实为现有数据提供了一个接口,但是因为Array{Float64,1}
是与数组{Float64,2}不同的类型
,即使基础数据相同,也必须有一个新对象作为包装器。
julia> A = rand(1000,1000);
julia> X = rand(1000,1000);
julia> @time sum(maximum(X*A,1))
elapsed time: 0.484229671 seconds (8008640 bytes allocated)
266274.8435928134