枫树 13 三对角矩阵帮助

发布于 2024-08-26 03:02:13 字数 147 浏览 7 评论 0原文

我正在尝试制作一个 100 x 100 三对角矩阵,其中 2 沿着对角线向下,-1 围绕 2。我可以制作一个在三个对角线上只有 1 的三对角矩阵,并预制矩阵加法来得到我想要的,但我想知道是否有一种方法可以将三个对角线自定义为你想要的。 maplehelp 没有列出任何有用的内容。

i am trying to make a 100 x 100 tridiagonal matrix with 2's going down the diagonal and -1's surrounding the 2's. i can make a tridiagonal matrix with only 1's in the three diagonals and preform matrix addition to get what i want, but i want to know if there is a way to customize the three diagonals to what ever you want. maplehelp doesn't list anything useful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我家小可爱 2024-09-02 03:02:13

LinearAlgebra 包中的 Matrix 函数可以使用参数 (init) 来调用,该参数是一个可以根据矩阵的位置为每个条目分配值的函数。
这会起作用:

f := (i, j) -> if i = j then 2 elif abs(i - j) = 1 then -1 else 0; end if;
Matrix(100, f);

The Matrix function in the LinearAlgebra package can be called with a parameter (init) that is a function that can assign a value to each entry of the matrix depending on its position.
This would work:

f := (i, j) -> if i = j then 2 elif abs(i - j) = 1 then -1 else 0; end if;
Matrix(100, f);
红衣飘飘貌似仙 2024-09-02 03:02:13

LinearAlgebra[BandMatrix] 也可以工作(并且会更快),特别是当您使用 storage=band[1] 时。您可能也应该使用 shape=symmetry 。

LinearAlgebra[BandMatrix] works too (and will be WAY faster), especially if you use storage=band[1]. You should probably use shape=symmetric as well.

后来的我们 2024-09-02 03:02:13

涉及初始化函数 f 的答案将为 nxn 方阵做 O(n^2) 工作。理想情况下,此任务应该是 O(n),因为需要填充的条目少于 3*n。

还假设您想要一个没有任何特殊(例如带)存储或索引功能的结果矩阵(以便您以后可以任意写入它的任何部分)。并且假设您不想通过使用另一个通用 Matrix() 调用包装带结构 Matrix 来解决这样的问题,这将使使用的临时内存加倍并产生可收集的垃圾。

这里有两种方法可以做到这一点(无需以 O(n^2) 方式将 f 应用于每个条目,或使用单独的 do 循环)。第一个涉及创建三个带作为临时对象(这是要收集的垃圾,但至少不是 n^2 大小的垃圾)。

M:=矩阵(100,[[-1$99],[2$100],[-1$99]],scan=band[1,1]);

第二种方法使用一个例程,该例程遍历 M 并仅用三个标量值填充它(因此不需要显式地使用 3 个波段列表)。

M:=矩阵(100):

ArrayTools:-Fill(100,2,M,0,100+1);

ArrayTools:-填充(99,-1,M,1,100+1);

ArrayTools:-填充(99,-1,M,100,100+1);

请注意,ArrayTools:-Fill 是一个已编译的外部例程,因此原则上可能比解释的 Maple 语言(适当的)方法更快。对于具有“float[8]”等硬件数据类型的 Matrix M 来说,速度尤其快。

顺便说一句,上面的箭头过程失败并出现错误“无效箭头过程”的原因很可能是在 2D 数学模式下输入的。 Maple 13 的 2D 数学解析器不将 if...then...end 语法理解为箭头运算符的主体。替代方案(除了像其他人回答的那样将 f 写为过程之外)是在一维 Maple 表示法模式下输入 f (未编辑),或者编辑 f 以使用 if 的运算符形式。也许这里 if 的运算符形式需要嵌套 if 来处理 elif。例如,

f := (i,j) -> `if`(i=j,2,`if`(abs(i-j)=1,-1,0));
Matrix(100,f);

The answers involving an initializer function f will do O(n^2) work for square nxn Matrix. Ideally, this task should be O(n), since there are just less than 3*n entries to be filled.

Suppose also that you want a resulting Matrix without any special (eg. band) storage or indexing function (so that you can later write to any part of it arbitrarily). And suppose also that you don't want to get around such an issue by wrapping the band structure Matrix with another generic Matrix() call which would double the temp memory used and produce collectible garbage.

Here are two ways to do it (without applying f to each entry in an O(n^2) manner, or using a separate do-loop). The first one involves creation of the three bands as temps (which is garbage to be collected, but at least not n^2 size of it).

M:=Matrix(100,[[-1$99],[2$100],[-1$99]],scan=band[1,1]);

This second way uses a routine which walks M and populates it with just the three scalar values (hence not needing the 3 band lists explicitly).

M:=Matrix(100):

ArrayTools:-Fill(100,2,M,0,100+1);

ArrayTools:-Fill(99,-1,M,1,100+1);

ArrayTools:-Fill(99,-1,M,100,100+1);

Note that ArrayTools:-Fill is a compiled external routine, and so in principal might well be faster than an interpreted Maple language (proper) method. It would be especially fast for a Matrix M with a hardware datatype such as 'float[8]'.

By the way, the reason that the arrow procedure above failed with error "invalid arrow procedure" is likely that it was entered in 2D Math mode. The 2D Math parser of Maple 13 does not understand the if...then...end syntax as the body of an arrow operator. Alternatives (apart from writing f as a proc like someone else answered) is to enter f (unedited) in 1D Maple notation mode, or to edit f to use the operator form of if. Perhaps the operator form of if here requires a nested if to handle the elif. For example,

f := (i,j) -> `if`(i=j,2,`if`(abs(i-j)=1,-1,0));
Matrix(100,f);
琉璃梦幻 2024-09-02 03:02:13

jmbr 提出的解决方案可以适应工作:

f := proc(i, j)
  if i = j then 2
  elif abs(i - j) = 1 then -1
  else 0
  end if
end proc;
Matrix(100, f);

另外,我理解您的评论是说您稍后需要破坏带矩阵性质,这会阻止您使用 BandMatrix - 是这样吗?最简单的解决方案是将 BandMatrix 调用包装在常规 Matrix 调用中,这将为您提供一个可以根据需要进行更改的 Matrix:

 Matrix(LinearAlgebra:-BandMatrix([1,2,1], 1, 100)); 

jmbr's proposed solutions can be adapted to work:

f := proc(i, j)
  if i = j then 2
  elif abs(i - j) = 1 then -1
  else 0
  end if
end proc;
Matrix(100, f);

Also, I understand your comment as saying you later need to destroy the band matrix nature, which prevents you from using BandMatrix - is that right? The easiest solution to that is to wrap the BandMatrix call in a regular Matrix call, which will give you a Matrix you can change however you'd like:

 Matrix(LinearAlgebra:-BandMatrix([1,2,1], 1, 100)); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文