【问题标题】:If loop acting inside a for loopIf 循环在 for 循环内起作用
【发布时间】:2018-03-28 23:31:07
【问题描述】:

这段代码:

K = 3
N = 3
E = [np.reshape(np.array(i), (K, N)) for i in itertools.product([0, 1, -1], repeat = K*N)]

print 'E = ', E

生成由 2 个整数组成的所有可能的 E 矩阵(维度 3x3):02,例如:

...
array([[0, 2, 2],
       [0, 0, 0],
       [2, 0, 0]]), array([[0, 2, 2],
       [0, 0, 0],
       [2, 0, 2]]), array([[0, 2, 2],
       [0, 0, 0],
       [2, 2, 0]])
...

给定这个矩阵方程:

A_SC = E * A     # Eqn. 1

地点:

1) * 代表标准的matrix multiplication(行、列)

2) A_SCEA 是 3x3 矩阵,

3)E是上述代码生成的所有可能的整数矩阵。

4) A 是一个已知矩阵:

A =np.array([[   0.288155519353E+01,   0.000000000000E+00,   0.568733333333E+01],
             [  -0.144077759676E+01,   0.249550000000E+01,   0.568733333333E+01],
             [  -0.144077759676E+01,  -0.249550000000E+01,   0.568733333333E+01]])

A_SC 矩阵可以表示为 3 行向量:a1_SCa2_SCa3_SC

       |a1_SC|
A_SC = |a2_SC|
       |a3_SC|

对于给定的E 矩阵,有一个A_SC 矩阵。

以下代码:

1) 遍历所有可能的E 矩阵,

2) 计算A_SC矩阵,

3) 计算a1_SCa2_SCa3_SC的范数,

4) 并计算该迭代中E 矩阵的行列式:

for indx_E in E:
      A_SC = np.dot(indx_E,A)
      a1_SC = np.linalg.norm(A_SC[0])
      a2_SC = np.linalg.norm(A_SC[1])
      a3_SC = np.linalg.norm(A_SC[2])

      det_indx_E = np.linalg.det(indx_E)
      print 'a1_SC = ', a1_SC
      print 'a2_SC = ', a2_SC
      print 'a3_SC = ', a3_SC
      print 'det_indx_E = ', det_indx_E

目标是获得所有那些A_SCE 矩阵(方程式1),其中这3 行向量的范数相同且大于10,

norm(a1_SC) = norm(a2_SC) = norm(a3_SC) > 10

同时,E 的行列式必须大于0.0。 这个条件可以这样表示:就在这个for循环之后,我们可以写一个if循环:

tol_1 = 10
tol_2 = 0

for indx_E in E:

      A_SC = np.dot(indx_E,A)
      a1_SC = np.linalg.norm(A_SC[0])
      a2_SC = np.linalg.norm(A_SC[1])
      a3_SC = np.linalg.norm(A_SC[2])

      det_indx_E = np.linalg.det(indx_E)
      print 'a1_SC = ', a1_SC
      print 'a2_SC = ', a2_SC
      print 'a3_SC = ', a3_SC
      print 'det_indx_E = ', det_indx_E

      if  a1_SC > tol_1\
          and a2_SC > tol_1\
          and a3_SC > tol_1\
          and abs(a1_SC - a2_SC) == tol_2\
          and abs(a1_SC - a3_SC) == tol_2\
          and abs(a2_SC - a3_SC) == tol_2\
          and det_indx_E > 0.0:
             print 'A_SC = ', A_SC

             print 'a1_SC = ', a1_SC
             print 'a2_SC = ', a2_SC
             print 'a3_SC = ', a3_SC
             print 'det_indx_E = ', det_indx_E

             # Now, which is the `E` matrix for this `A_SC` ?
             #      A_SC = E * A     # Eqn. 1
             #      A_SC * inv(A) = E * A * inv(A)  # Eqn. 2
             #
             #      ------------------------------
             #     | A_SC * inv(A) = E  # Eqn. 3  |
             #      ------------------------------
             E_sol = np.dot(A_SC, np.linalg.inv(A))
             print 'E_sol = ', E_sol

为了清楚起见,这是整个代码:

A =np.array([[   0.288155519353E+01,   0.000000000000E+00,   0.568733333333E+01],
                 [  -0.144077759676E+01,   0.249550000000E+01,   0.568733333333E+01],
                 [  -0.144077759676E+01,  -0.249550000000E+01,   0.568733333333E+01]])

K = 3
N = 3
E = [np.reshape(np.array(i), (K, N)) for i in itertools.product([0, 1, -1], repeat = K*N)]

print 'type(E) = ', type(E)
print 'E = ', E
print 'len(E) = ', len(E)

tol_1 = 10
tol_2 = 0

for indx_E in E:

      A_SC = np.dot(indx_E,A)
      a1_SC = np.linalg.norm(A_SC[0])
      a2_SC = np.linalg.norm(A_SC[1])
      a3_SC = np.linalg.norm(A_SC[2])

      det_indx_E = np.linalg.det(indx_E)
      print 'a1_SC = ', a1_SC
      print 'a2_SC = ', a2_SC
      print 'a3_SC = ', a3_SC
      print 'det_indx_E = ', det_indx_E

      if  a1_SC > tol_1\
          and a2_SC > tol_1\
          and a3_SC > tol_1\
          and abs(a1_SC - a2_SC) == tol_2\
          and abs(a1_SC - a3_SC) == tol_2\
          and abs(a2_SC - a3_SC) == tol_2\
          and det_indx_E > 0.0:
             print 'A_SC = ', A_SC

             print 'a1_SC = ', a1_SC
             print 'a2_SC = ', a2_SC
             print 'a3_SC = ', a3_SC
             print 'det_indx_E = ', det_indx_E

             # Now, which is the `E` matrix for this `A_SC` ?
             #      A_SC = E * A     # Eqn. 1
             #      A_SC * inv(A) = E * A * inv(A)  # Eqn. 2
             #
             #      ------------------------------
             #     | A_SC * inv(A) = E  # Eqn. 3  |
             #      ------------------------------
             E_sol = np.dot(A_SC, np.linalg.inv(A))
             print 'E_sol = ', E_sol

问题是没有打印A_SC(因此没有E_sol)。 如果您运行此代码,则会在每次迭代时打印所有规范和行列式,例如:

a1_SC =  12.7513326014
a2_SC =  12.7513326014
a3_SC =  12.7513326014
det_indx_E =  8.0

这将是一个完美的候选人,因为它满足

a1_SC = a2_SC = a3_SC = 12.7513326014 > 10.0

determinant > 0.0

但是,没有打印A_SC(因此没有E_sol)……为什么会这样?

例如这个E矩阵:

        2 0 0
  E =   0 2 0
        0 0 2

det = 8.0,并且是候选人,因为它有:

a1_SC = a2_SC = a3_SC = 12.7513326014 > 10.0

【问题讨论】:

  • @MohitC 当我说Just to be clear, this is the entire code: 时,我已经粘贴了整个代码,作为一个最小的工作示例
  • 如果使用浮点数,不能保证如果(str(a) == str(b))(渲染值看起来相等),那么(a - b) == 0。也许您应该尝试将 tol_2 设置为 1e-6 并测试 abs(a1_SC - a2_SC) <= tol_2
  • 它根本不是最小的,但你的问题是在浮点数上使用==。如果您费心进行错误跟踪,您会看到所有abs(. . . . ) == tol2 检查很可能是False,因为浮点错误。使用np.isclose
  • @Ronald 非常感谢您指出这一点。确实,渲染的值看起来相等,我同意你的观点,这并不意味着abs(a1_SC - a2_SC) == tol_2 将是真的。我已将tol_2 设置为1E-6 并执行abs(a1_SC - a2_SC) <= tol_2 而不是abs(a1_SC - a2_SC) == tol_2。这将打印出满足 if 循环中的 7 个条件的所有 A_SC 矩阵。因此,这解决了问题。再次,谢谢你。不过,我完全不明白为什么这篇文章值得 4 票反对。
  • @DanielF 如果entire code 似乎不是最小的,我深表歉意。为什么说它不是 MWE?如果您复制并粘贴 entire code,您将得到我在帖子中提到的所有错误。如果这篇文章看起来很长是因为我想详细解释问题

标签: python arrays numpy matrix linear-algebra


【解决方案1】:

简单的答案是不要将双重输出误认为是具有真正基础精度的字符串。最简单的改变:

tol_2 = 1e-8

并将 tol_2 相关条件更改为限制:

        and abs(a1_SC - a2_SC) <= tol_2\
        and abs(a1_SC - a3_SC) <= tol_2\
        and abs(a2_SC - a3_SC) <= tol_2\

这应该可以解决您的问题。

请记住,当您没有在计算机上明确使用符号计算时,即使在最简单的示例中,您也应该随时准备好出现数值错误

如果您需要检查某些事物的 STRICT数学 相等性 - 您必须使用符号数学包和相关机制。

如果所需的平等更多地是“物理”意义上的(例如,什么力足以拉动那个盒子)-那么我描述的方法就可以了,因为物理世界中总是存在一些“错误” ,您只需要说明所需的容差(在这种情况下我们使用tol_2

【讨论】:

  • this question中可能有更多关于公差和 python 浮点比较的信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
相关资源
最近更新 更多