Julia 将标识块分配到更大的矩阵中
在matlab中,假设我想要构建一个包含标识块的矩阵a,我可以使用Julia 将标识块分配到更大的矩阵中,julia,Julia,在matlab中,假设我想要构建一个包含标识块的矩阵a,我可以使用 A = zeros(4,4); A(1:2,1:2) = eye(2); 在julia中,我知道UniformScaling/I操作符。 然而,我似乎不能以同样的方式使用,我读到的每一篇文章都说它取代了eye操作符 朱利安式的方法是什么 编辑:我目前正在使用一些对角线(…)来实际创建对角线块 关于第一个答案,它似乎与矩阵(I..语法相对可比(速度是max的两倍),但就大型矩阵的内存使用而言,它要好得多(大约少了一百倍) 有关测
A = zeros(4,4);
A(1:2,1:2) = eye(2);
在julia中,我知道UniformScaling/I
操作符。
然而,我似乎不能以同样的方式使用,我读到的每一篇文章都说它取代了eye
操作符
朱利安式的方法是什么
编辑:我目前正在使用一些对角线(…)
来实际创建对角线块
关于第一个答案,它似乎与矩阵(I..
语法相对可比(速度是max的两倍),但就大型矩阵的内存使用而言,它要好得多(大约少了一百倍)
有关测试目的,请参阅此代码
using LinearAlgebra
using BenchmarkTools
A = zeros(10,10)
@btime A[1:8,1:8] = Matrix(I,8,8)
B = zeros(10,10)
@btime B[1:8,1:8] = Diagonal(ones(8))
A == B
A = zeros(100,100)
@btime A[1:80,1:80] = Matrix(I,80,80)
B = zeros(100,100)
@btime B[1:80,1:80] = Diagonal(ones(80))
A == B
A = zeros(1000,1000)
@btime A[1:800,1:800] = Matrix(I,800,800)
B = zeros(1000,1000)
@btime B[1:800,1:800] = Diagonal(ones(800))
A == B
返回
155.858 ns (1 allocation: 160 bytes)
176.879 ns (2 allocations: 160 bytes)
6.680 μs (1 allocation: 6.44 KiB)
10.799 μs (2 allocations: 752 bytes)
617.099 μs (2 allocations: 625.14 KiB)
1.007 ms (2 allocations: 6.39 KiB)
true
我是朱莉娅的新手,请随时纠正我:
julia> z = zeros(Int, 4, 4)
4×4 Matrix{Int64}:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
julia> using LinearAlgebra
julia> z[2:3, 2:3] = Matrix{Int}(I, 2, 2)
2×2 Matrix{Int64}:
1 0
0 1
julia> z
4×4 Matrix{Int64}:
0 0 0 0
0 1 0 0
0 0 1 0
0 0 0 0
以下是一种几乎不进行分配的通用方法:
julia> using LinearAlgebra, BenchmarkTools
julia> function func1(z, a, b)
z[diagind(z)[a:b]] .= one(eltype(z))
return z end
func1 (generic function with 1 method)
julia> test = zeros(1_000, 1_000);
julia> @btime func1($test, 1, 2);
68.680 ns (2 allocations: 80 bytes)
julia> @btime func1($test, 1, 500);
441.919 ns (2 allocations: 80 bytes)
julia> @btime func1($test, 1, 1000);
2.444 μs (2 allocations: 80 bytes)
编辑添加:与许多其他语言相比,Julia中最简单、最有效的解决方案通常是循环:
julia> function func2(z, a, b)
for i ∈ a:b
z[i, i] = one(eltype(z))
end
return z
end
func2 (generic function with 1 method)
julia> @btime func2($test, 1, 2);
2.000 ns (0 allocations: 0 bytes)
julia> @btime func2($test, 1, 500);
265.337 ns (0 allocations: 0 bytes)
julia> @btime func2($test, 1, 1000);
2.200 μs (0 allocations: 0 bytes)
谢谢你的建议。有趣的是,您的解决方案比对角线(…)快了一点,但占用了更多的内存;谢谢你改进了我的回答,很好。它确实分配很少。而且只需要很少的时间(在我的1000x1000示例中大约946 ns),您的编辑有点混乱,for循环没有分配任何内容,但是它比您以前的解决方案需要更多的时间。为什么会这样?很抱歉,当我对不同的操作进行基准测试(替换不同数量的对角线项)时,这确实令人困惑-我再次编辑,以使两个函数具有相同数量的替换。