嵌套的;如果;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.