1

我正在尝试制作一个 100 x 100 三对角矩阵,其中 2 在对角线上,-1 在 2 周围。我可以制作三个对角线中只有 1 的三对角矩阵,并预先形成矩阵加法以获得我想要的,但我想知道是否有一种方法可以将三个对角线自定义为你想要的。maplehelp 没有列出任何有用的东西。

4

4 回答 4

3

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

f := (i, j) -> if i = j then 2 elif abs(i - j) = 1 then -1 else 0; end if;
Matrix(100, f);
于 2010-03-17T20:08:20.773 回答
1

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

于 2010-04-29T01:47:25.447 回答
1

涉及初始化函数的答案f将对平方 nxn 矩阵执行 O(n^2) 工作。理想情况下,这个任务应该是 O(n),因为只有少于 3*n 个条目需要填写。

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

这里有两种方法(不以 O(n^2) 的方式将 f 应用于每个条目,或者使用单独的 do-loop)。第一个涉及将三个波段创建为临时(这是要收集的垃圾,但至少不是 n^2 大小)。

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

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

M:=矩阵(100):

ArrayTools:-填充(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]”之类的硬件数据类型的矩阵 M,它会特别快。

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

f := (i,j) -> `if`(i=j,2,`if`(abs(i-j)=1,-1,0));
Matrix(100,f);
于 2010-05-11T17:43:39.433 回答
0

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

f := 过程(i, j)
  如果 i = j 那么 2
  elif abs(i - j) = 1 然后 -1
  否则 0
  万一
结束进程;
矩阵(100,f);

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

矩阵(线性代数:-BandMatrix([1,2,1], 1, 100));
于 2010-05-10T16:46:14.630 回答