matrix - 如何为满足一定条件的矩阵元素赋值?
问题描述
我需要从矩阵 A 创建新矩阵。新矩阵中的所有元素都必须是矩阵 A 中的元素,但主对角线上的元素除外。主对角线上的奇数元素需要除以 2,主对角线上的偶数元素需要乘以 3。
julia> A=rand(1:10 ,3,3)
3×3 Array{Int64,2}:
5 3 1
5 2 6
10 1 7
我决定从两个矩阵创建新矩阵。首先,我决定将矩阵 A 中的所有元素(主对角线上的元素除外)保留在主对角线为零的矩阵 B 中:
julia> B=A .* .~ I(3)
3×3 Array{Int64,2}:
0 3 1
5 0 6
10 1 0
然后我想创建与 A 具有相同主对角线的矩阵 C,并且所有其他元素都为零:
julia> C=A .* one(A)
3×3 Array{Int64,2}:
5 0 0
0 2 0
0 0 7
最后,我的目标是对矩阵 C 进行所有更改,然后将最终矩阵创建为
D = C + B;
我在主对角线上进行更改时遇到问题,因为我不确定如何为满足特定条件的矩阵元素赋值。例如,如何将主对角线上的偶数元素乘以 3,将主对角线上的奇数元素除以 2?
我尝试使用替换: replace!(x->x%2!=0 ? x/2 : x, C)
但它返回错误。我尝试使用C[C .% 2 .!=0]
它而不是用它做某事,但我无法正确处理。
提前致谢!
解决方案
一个简单的循环呢?
function change_diagonal!(A)
@inbounds for i = 1:size(A,1)
if iseven(A[i,i])
A[i,i] = 3*A[i,i]
else
A[i,i] = A[i,i]/2
end
end
return A
end
这样做的一个问题是您的矩阵是 Int64 类型的,并且将奇数除以 2 不会产生整数。但是,一般来说,如果您只想对密集矩阵的主要元素进行操作,那么简单的循环既简单又快速。重要的是要注意这会就地修改矩阵,因此在执行操作时没有任何内存分配。如果我们将其扩展为更通用:
function change_diagonal!(f,A)
@inbounds for i = 1:size(A,1)
A[i,i] = f(A[i,i])
end
return A
end
您可以传递任何函数,该函数将映射到矩阵的对角元素上。
编辑:还有其他方法,我不知道是否更快(可能不会)但为了完整起见,这里的想法是:您可以生成一个与矩阵对角线视图相对应的向量,所以当你修改那个向量时,你就修改了原始矩阵。这是生成该视图的函数:
function diagonal_view(A)
return @view A[diagind(A)]
end
现在,您可以像使用简单向量一样使用对角线:
A = rand(1.0:10.0,5,5)
diagA = diagonal_view(A)
diagA .= 40.0 #all elements of the diagonal of A are changed to 40.0
map!(x->2x,diagA,diagA) # another way to modify the diagonal, doubles the values
推荐阅读
- javascript - Firefox 在第二次和连续单击滚动到顶部按钮时忽略平滑滚动
- php - Wordpress Gutenberg 如何在自定义模板中只允许特定的自定义块
- c# - 如何使用 C# .net 在代码活动中创建可扩展类别?
- r - 根据前 5 个值汇总 R 中的多个列
- android - androidx.navigation 库更新到 2.2.2 版本发布构建问题
- python - 在 keras 中使用 conv2D 层时,在 tf.random.set_seed 中设置种子是否也会设置 glorot_uniform kernel_initializer 使用的种子?
- swift - 尝试在 2 个 VC 之间进行通信时,我在哪里定义闭包的行为?
- python - Plotly:订购甘特图以在左上角而不是左下角显示最早的项目
- javascript - 不能应用于 javascript 中的“字符串”和“日期”类型
- r - 每天在ggplot2中绘制一个多元时间序列