在下面的代码中,我使用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)))
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
Run Code Online (Sandbox Code Playgroud)
我认为朱莉娅每次都会为此分配新的空间并且感觉很慢,那么解决这个问题的更有效方法是什么呢?
只要数组包含被认为是不可变的元素(包括所有基元),那么数组的元素就包含在1个大的连续内存块中.因此,您可以打破维度规则,只需将二维数组视为一维数组,这就是您想要做的.所以你不需要重塑,但我不认为重塑是你的问题
考虑以下功能
function enumerateArray(a)
for i = 1:*(size(a)...)
print(a[i])
end
end
Run Code Online (Sandbox Code Playgroud)
此函数乘以所有的尺寸的一个在一起,然后从1循环到该号码假设一个是一维的.
当您定义如下时
julia> a = [ 1 2; 3 4; 5 6]
3x2 Array{Int64,2}:
1 2
3 4
5 6
Run Code Online (Sandbox Code Playgroud)
结果是
julia> enumerateArray(a)
135246
Run Code Online (Sandbox Code Playgroud)
这说明了一些事情.
那么,问题是为什么不重塑使用这个事实呢?它确实如此.这是在array.c中重塑的julia源代码
a = (jl_array_t*)allocobj((sizeof(jl_array_t) + sizeof(void*) + ndimwords*sizeof(size_t) + 15)&-16);
Run Code Online (Sandbox Code Playgroud)
所以是的,创建了一个新数组,但只创建了新的维度信息,它指向未复制的原始数据.您可以像这样简单地验证:
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
Run Code Online (Sandbox Code Playgroud)
因此设置的第四元件b组的(1,2)元素一个.
至于整体缓慢
I1(A) = sum(maximum(X*A,1))
Run Code Online (Sandbox Code Playgroud)
将创建一个新的数组.
您可以使用几个宏来跟踪 @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
Run Code Online (Sandbox Code Playgroud)
@profile记录的统计信息使用Profile.print()输出