在Julia中有没有办法交换O(1)中的列?

在Julia中有没有办法交换O(1)中的列?,julia,linear-algebra,numerical-methods,Julia,Linear Algebra,Numerical Methods,我让Julia做了一些数值分析的工作,并试图实现一个完整的支点LU分解(比如,试图得到一个尽可能稳定的LU分解)。我认为最好的方法是找到每列的最大值,然后按最大值的降序排列 有没有一种方法可以避免交换两列的每个元素,而改为更改两个引用/指针?在julia中有@view宏,它允许您创建一个数组,该数组只是对另一个数组的引用,例如: A = [1 2;3 4] Aview = @view A[:,1] #view of the first column Aview[1,1] = 10 julia

我让Julia做了一些数值分析的工作,并试图实现一个完整的支点LU分解(比如,试图得到一个尽可能稳定的LU分解)。我认为最好的方法是找到每列的最大值,然后按最大值的降序排列


有没有一种方法可以避免交换两列的每个元素,而改为更改两个引用/指针?

在julia中有@view宏,它允许您创建一个数组,该数组只是对另一个数组的引用,例如:


A = [1 2;3 4]
Aview = @view A[:,1] #view of the first column
Aview[1,1] = 10

julia> A
2×2 Array{Int64,2}:
 10  2
 3  4

julia> A = reshape(1:12, 3, 4)
3×4 reshape(::UnitRange{Int64}, 3, 4) with eltype Int64:
 1  4  7  10
 2  5  8  11
 3  6  9  12

julia> V = view(A, :, [3,2,4,1])
3×4 view(reshape(::UnitRange{Int64}, 3, 4), :, [3, 2, 4, 1]) with eltype Int64:
 7  4  10  1
 8  5  11  2
 9  6  12  3
也就是说,当处理具体的数字类型(Float64、Int64等)时,julia使用连续的内存块直接表示数字类型。也就是说,数字的julia数组不是指针数组,数组的每个元素都是指向值的指针。如果数组的值可以用具体的二进制表示(例如,结构数组)表示,则使用指针数组

我不是计算机科学专家,但我观察到,在进行数字运算时,最好使用大量指针将数据紧密打包


另一种不同的情况是稀疏数组。稀疏数组的基本julia表示是索引数组和值数组。在这里,您可以简单地交换索引,而不是复制值。

在@longemen3000的回答之后,您可以使用视图交换列。例如:


A = [1 2;3 4]
Aview = @view A[:,1] #view of the first column
Aview[1,1] = 10

julia> A
2×2 Array{Int64,2}:
 10  2
 3  4

julia> A = reshape(1:12, 3, 4)
3×4 reshape(::UnitRange{Int64}, 3, 4) with eltype Int64:
 1  4  7  10
 2  5  8  11
 3  6  9  12

julia> V = view(A, :, [3,2,4,1])
3×4 view(reshape(::UnitRange{Int64}, 3, 4), :, [3, 2, 4, 1]) with eltype Int64:
 7  4  10  1
 8  5  11  2
 9  6  12  3
也就是说,这是否是一个好的策略取决于访问模式。如果您将使用
V
元素一次或几次,则此
视图
策略是一个很好的策略。相反,如果您多次访问
V
的元素,最好是复制或将值移动到位,因为这是您只需支付一次的价格,而在这里,每次访问值时您都要支付间接成本。

只是为了“完整性”,以防您真的想在适当的位置交换列

function swapcols!(X::AbstractMatrix, i::Integer, j::Integer)
    @inbounds for k = 1:size(X,1)
        X[k,i], X[k,j] = X[k,j], X[k,i]
    end
end
它简单快速

事实上,在小型矩阵的单个基准中,这甚至比其他答案中提到的
视图
方法更快(视图并不总是免费的):


这个想法是所有的运算一次都在一列上完成,所以如果我有一个指向列开头的指针,我只需交换它们,就不会有内存访问问题,因为操作都在列上,所有列都在连续的内存上。矩阵只是一个大向量,但有一个关联的形状。矩阵的索引只是计算给定形状的值所在的偏移量。如果要避免复制,可以将索引存储在另一个数组中,并返回带有这些索引的修改数组的视图。你可以在转置矩阵上工作并将行视为列,但我想知道是否只实现了交换列查找数据透视至少是一个O(n²)操作,按新顺序复制矩阵也是O(n²),因此,以更有效的方式进行第二步不会获得太多收益。任何节省时间的做法都是节省时间