嵌套的;如果;Smalltalk(Pharo)中的“开关”
我需要用一些值填充矩阵(存储为数组数组)。矩阵是一个简单扩散问题的雅可比矩阵,如下所示:嵌套的;如果;Smalltalk(Pharo)中的“开关”,smalltalk,pharo,Smalltalk,Pharo,我需要用一些值填充矩阵(存储为数组数组)。矩阵是一个简单扩散问题的雅可比矩阵,如下所示: J(1,1) = 1, J(N,N)=0 对于1 在哪里 基本上,一般的想法是:每当找到嵌套的IFS时,将该段代码单独地分解为一个方法,并将嵌套转换成一个枚举的情况,该枚举在任何可能的情况下返回一个值。 < P>为了可读性,我将考虑牺牲额外的 O(n)< /C>时间,避免IFS。(这只会让它更快…) 这意味着我可以创建一个只有零的整个矩阵,然后改变对角线和相邻的对角线 jNM := [ k / dx sq
J(1,1) = 1, J(N,N)=0
对于1
在哪里
基本上,一般的想法是:每当找到嵌套的IFS时,将该段代码单独地分解为一个方法,并将嵌套转换成一个枚举的情况,该枚举在任何可能的情况下返回一个值。 < P>为了可读性,我将考虑牺牲额外的<代码> O(n)< /C>时间,避免IFS。(这只会让它更快…)
这意味着我可以创建一个只有零的整个矩阵,然后改变对角线和相邻的对角线
jNM := [ k / dx squared ].
jNN := [ :n | -2.0 * k / dx squared - (2.0 * (c at: n)) ].
n := c size.
m := Matrix
new: n
tabulate: [:i :j | 0 ].
(1 to: n - 1) do: [ :i |
m at: i at: i put: (jNN value: i).
m at: i + 1 at: i put: jnM value.
m at: i at: i + 1 put: jnM value.
].
m at: 1 at: 1 put: 1.
注意:我不熟悉这背后的数学,但是J(n,m-1)
的值对我来说似乎是一个常数
注2:我将值放在I+1
索引处,因为我从位置1;1
开始,但你可以从相反的方向开始,使用I-1
我认为这种方法总体上会更好,但这个矩阵总体只是用于测试用例。因此,我将使用另一个答案,这对r我的具体情况。我也喜欢@Peter的解决方案,我认为我们两人都想让你知道new:tablate:
方法(我称之为fromBlock:dimension:
),不幸的是,我使用的矩阵没有这个方法。也许我不应该使用它,而应该使用标准的matrix
类(或者添加new:tablate:
),但这是一个不同的问题:)@mobiuseng我的意思是new:tablate:
方法如果有选择器fromBlock:dimension:
,会更具表现力。这两种方法的选择器相同,只是在它们的选择器(以及参数的顺序)上有所不同是的,我应该首先考虑沿着对角线走!至于你的问题:J(n,n-1)
在这里确实是常数。但一般来说,它可能更复杂。对于非玩具问题,你可能需要使用更有效的(稀疏的)矩阵实现。@StephanEggermont当然足够了,对于更严肃的任务,我必须实现一个稀疏(带状)矩阵:速度性能x2-x3。
(1 to: c size) collect: [ :n |
(1 to: c size) collect: [ :m |
n = 1 | (n = c size)
ifTrue: [ m = n ifTrue: [ 1.0 ] ifFalse: [ 0.0 ] ]
ifFalse: [ m = n
ifTrue: [ -2.0 * k / dx squared - (2.0 * (c at: n)) ]
ifFalse: [ m = (n-1) | (m = (n+1))
ifTrue: [ k / dx squared ]
ifFalse: [ 0.0 ] ] ]
] ]
n := c size.
Matrix
new: n
tabulate: [:i :j | self jacobianAtRow: i column: j]
jacobianAtRow: i column: j
n := c size.
(i = 1 or: [i = n]) ifTrue: [^j = i ifTrue: [1.0] ifFalse [0.0]].
j = i ifTrue: [^-2.0 * k / dx squared - (2.0 * (c at: i))].
(j = (i - 1) or: [j = (i + 1)]) ifTrue: [^k / dx squared].
^0.0
J(N,N) = 0
J(1,1) = 1
//and for 1<n<N:
J(n,n) = Y(n)
J(n,m-1) = J(n,m+1) = X
( 1 X 0 0 0 )
( X Y X 0 0 )
( 0 X Y X 0 )
( 0 0 X Y X )
( 0 0 0 X 0 )
jNM := [ k / dx squared ].
jNN := [ :n | -2.0 * k / dx squared - (2.0 * (c at: n)) ].
n := c size.
m := Matrix
new: n
tabulate: [:i :j | 0 ].
(1 to: n - 1) do: [ :i |
m at: i at: i put: (jNN value: i).
m at: i + 1 at: i put: jnM value.
m at: i at: i + 1 put: jnM value.
].
m at: 1 at: 1 put: 1.