因此对于我的应用程序,我需要创建一个三对角矩阵。使用任何语言都可以轻松完成此操作,您可以遍历所有行和列,然后设置主要对角线值,次对角线值和超级对角线值。通常,这是在二维数组上执行的。
对于我的应用程序,我需要创建一个“三对角线”的一维数组。换句话说,是:取2d三对角矩阵,然后将其变成1d。我可以从2d开始,然后编写一些将2d数组转换为1d数组的函数。我可以的我想知道我们是否可以直接进入一维“三对角线”?例如,假设2D数组是10 * 10,那么我的1D数组将是100个元素长,那么我将需要找出哪个索引是主,超级和次对角线。
是否可以这样做?请让我知道并谢谢您
答案 0 :(得分:1)
主对角线上的元素位于索引(i,i)上,并且其中n个元素;在(i,i-1)和(i,i + 1)的上对角线和下对角线,其中有n-1个(i分别从2开始,在n-1结束)。
一种选择是使用三个向量,并将元素存储在这三个向量的相应索引i上。
您还可以将所有值打包在单个长度为3n的向量中(如果要保留空间,则打包为3n-2)。根据要寻址的对角线,将n或2n添加到索引。对于元素(i,j),对角线的索引由j-i + 2给出。
答案 1 :(得分:0)
您可以仅使用2D数组指针查看您的1D数组。 Fortran:
integer, target :: A(100)
integer, pointer :: B(:,:)
B(1:10,1:10) => A
B = 0
do i = 1, 10
B(i,i) = 1
end do
print '(*(1x,g0))', A
end
> gfortran diag1d.f90
> ./a.out
1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
在C ++中,转换也很容易。
答案 2 :(得分:0)
还请考虑:
@YvesDaoust的答案,因为提出了一种更好的存储策略:与其存储三对角矩阵的所有元素,不如存储非零值。如果值得的话,您可以编写派生类型来封装行为。
@VladmirF的答案,因为指针关联可能比通过reshape
复制整个数组更好(取决于您的用例),如果您想要的只是临时索引更改(为了方便)在处理数据时。
说,让我们来看一下答案。
填充三对角矩阵与构建任何矩阵都不是不同的问题。我认为这并不重要。只需记住,Fortran会以Column Major顺序(基于1的索引)存储数组。
如果存储是连续的,则更改数据的形状很容易并且显而易见。您可以建立pointer
关联或使用reshape
将其转移到新变量。
提取主,对角线和子对角线也是一个琐碎的问题,可以通过简单地操作数组索引三元组来完成。看:
program tridiagonal
implicit none
integer, parameter :: n = 4
integer :: A(n, n), B(n**2), main(n), sub(n-1), sup(n-1)
A(1,:) = [1, 4, 0, 0]
A(2,:) = [3, 4, 1, 0]
A(3,:) = [0, 2, 3, 4]
A(4,:) = [0, 0, 1, 3]
! Remember, colum major
B = reshape(A, shape(B)) ! 1, 3, 0, 0, 4, 4, 2, 0, 0, 1, 3, 1, 0, 0, 4, 3
main = B( 1:n**2:n+1) ! 1, 4, 3, 3
sub = B( 2:n**2:n+1) ! 3, 2, 1
sup = B(n+1:n**2:n+1) ! 4, 1, 4
end