这里做了什么? (使用数学识别)

时间:2010-06-26 23:25:13

标签: math fortran

我知道这本身并不是完全编程,但程序员是最多的 所有可能会认识到这一点的人很可能。

我有以下内容(X和Y是数组,都有3个元素),我无法识别(虽然它让我想起了一些事情,但没有完全!)这里做了什么。是否会为其他人敲响任何铃声?

我认为你可以忽视下半部分;鞋帮应该放弃......但我仍然看不到它。

起初它让我想起了3d空间中的线性插值......

  SUBROUTINE TRII(X,Y,XR,YR)
DIMENSION X(3),Y(3)

D=X(1)*(X(2)**2-X(3)**2)+
 >    X(2)*(X(3)**2-X(1)**2)+
 >    X(3)*(X(1)**2-X(2)**2)

D1=Y(1)*(X(2)*X(3)**2-X(3)*X(2)**2)+
 >     Y(2)*(X(3)*X(1)**2-X(1)*X(3)**2)+
 >     Y(3)*(X(1)*X(2)**2-X(2)*X(1)**2)

D2=Y(1)*(X(2)**2-X(3)**2)+
 >     Y(2)*(X(3)**2-X(1)**2)+
 >     Y(3)*(X(1)**2-X(2)**2)

D3=X(2)*(Y(3)-Y(1))+
 >     X(1)*(Y(2)-Y(3))+
 >     X(3)*(Y(1)-Y(2))

A=D1/D
B=D2/D
C=D3/D

YR=A+B*XR+C*XR**2

RETURN
END

  SUBROUTINE TRIM(X,Y,XR,YR,XM,YM)
DIMENSION X(3),Y(3)

D=X(1)*(X(2)**2-X(3)**2)+
 >    X(2)*(X(3)**2-X(1)**2)+
 >    X(3)*(X(1)**2-X(2)**2)

D1=Y(1)*(X(2)*X(3)**2-X(3)*X(2)**2)+
 >     Y(2)*(X(3)*X(1)**2-X(1)*X(3)**2)+
 >     Y(3)*(X(1)*X(2)**2-X(2)*X(1)**2)

D2=Y(1)*(X(2)**2-X(3)**2)+
 >     Y(2)*(X(3)**2-X(1)**2)+
 >     Y(3)*(X(1)**2-X(2)**2)

D3=X(2)*(Y(3)-Y(1))+
 >     X(1)*(Y(2)-Y(3))+
 >     X(3)*(Y(1)-Y(2))

A=D1/D
B=D2/D
C=D3/D

XR=-B/(2.*C)
YR=A+B*XR+C*XR**2

XM=XR
IF(XR.GT.X(1).OR.XR.LT.X(3))XM=X(1)
YM=A+B*XM+C*XM**2
IF(YM.LT.Y(1))XM=X(1)
IF(YM.LT.Y(1))YM=Y(1)

RETURN
END

“>” 中是一个延续的标志。

5 个答案:

答案 0 :(得分:9)

代码运行如下

Routine TRII将三个点(x,y)的坐标作为输入,并使用Lagrange interpolation插值抛物线。也将坐标XR作为输入。在YR中返回内插抛物线的XR值。 我想这个例程的名称来自“TRI”(克罗地亚语为“三”(分))和“I”代表插值。

例程TRIM也计算相同的抛物线,并在区间{X(1),X(3)}中返回函数的最小值。名称来自“TRI”和“M”(最小值) )

(我“真的”执行了程序)>)

请注意,这是FORTRAN代码,参数通过引用传递,因此结果以相同的参数返回(非常奇怪!)

修改

只是为了好玩,让我们运行TRII

TRII[X_, Y_, XR_] := 
  Module[{D0, D1, D2, D3, A, B, C}, 
     D0 = X[[1]]*(X[[2]]^2 - X[[3]]^2) + 
          X[[2]]*(X[[3]]^2 - X[[1]]^2) + 
          X[[3]]*(X[[1]]^2 - X[[2]]^2);
     D1 = Y[[1]]*(X[[2]]*X[[3]]^2 - X[[3]]*X[[2]]^2) + 
          Y[[2]]*(X[[3]]*X[[1]]^2 - X[[1]]*X[[3]]^2) + 
          Y[[3]]*(X[[1]]*X[[2]]^2 - X[[2]]*X[[1]]^2);
     D2 = Y[[1]]*(X[[2]]^2 - X[[3]]^2) + 
          Y[[2]]*(X[[3]]^2 - X[[1]]^2) + 
          Y[[3]]*(X[[1]]^2 - X[[2]]^2);
     D3 = X[[2]]*(Y[[3]] - Y[[1]]) + 
          X[[1]]*(Y[[2]] - Y[[3]]) + 
          X[[3]]*(Y[[1]] - Y[[2]]);
   A = D1/D0;
   B = D2/D0;
   C = D3/D0;
   Return[A + B*XR + C*XR^2];];

X = RandomReal[1, 3];
Y = RandomReal[1, 3];
Show[Plot[TRII[X, Y, x], {x, 0, 1}], 
 ListPlot[Transpose[{X, Y}], PlotMarkers -> Automatic]]

enter image description here

答案 1 :(得分:8)

D是矩阵的决定因素:

        | x(1) x(1)² 1 |
D = det | x(2) x(2)² 1 |
        | x(3) x(3)² 1 |

在D1中,最右边的列已替换为Y:

         | x(1) x(1)² Y(1) |
D1 = det | x(2) x(2)² Y(2) |
         | x(3) x(3)² Y(3) |

在D2和D3中,它们分别是第一列和第二列。现在更容易识别吗?看起来很像使用Cramer的规则来解决线性方程式。

编辑:更确切地说:(A,B,C)是系统的解决方案:

A + x(1)*B + x(1)²*C = Y(1)
A + x(2)*B + x(2)²*C = Y(2)
A + x(3)*B + x(3)²*C = Y(3)

YR是二次方程解的平方(nb,不同的x!):

C*x² + B*x + A = 0

我觉得现在这应该是显而易见的,但我无法理解......

答案 2 :(得分:4)

我不确定这是什么语言,但很明显这是二次方程的某种求解器。 XRYR表达式是一个死的赠品:

XR = -B / (2.*C)
YR = A + B*XR + C*XR**2

然而,在不知道X(1..3)Y(1..3)表达式是什么的情况下,不可能更多地推断A / B / C系数代表什么然而。很多东西都使用二次方程 - 给定半径的圆的面积,给定距离的光强度等等。需要更多的上下文数据。


更新: OP表示,由于保密原因,他不能过于具体。这里有一些提示:

  • 子程序返回什么? 以后如何使用这些结果?这可能会带来更好的见解。

  • 看来Y(1)是这种计算结果的某种神奇下界。请注意,如果YM小于Y(1),则XMYM分别设置为X(1)Y(1)

  • “D”表达式看起来像这样,语法更自然:

d = x1 * [x2^2 - x3^2] + x2 * [x3^2 - x1^2] + x3 * [x1^1 - x2^2]
  d1 = y1 * [x2*x3^2 - x3*x2^2] + y2 * [x3*x1^2 - x1*x3^2] + y3 * [x1*x2^2 - x1*x2^2]
  d2 = y1 * [x2^2 - x3^2] + y2 * [x3^2 - x1^2] + y3 * [x1^2 - x2^2]
  d3 = x2 * [y3 - y1] + x1 * [y2 - y3] * x3 * [y1 - y2]
  • 这看起来非常像某种矩阵运算; D几乎肯定是“决定因素”。但是还有其他东西具有相同的数学关系。

答案 3 :(得分:4)

此代码表示一种在三个2d点上拟合的插值/二次曲线,以及计算间隔本身内这种拟合二次曲线的最小值或最大值的方法。我猜TRII代表三(点) - 插值,TRIM代表三(点)最小值或最大值。

为了更精确,TRII解决了这个问题: - 找到以Y = A + B 形式通过点(x1,y1),(x2,y2)和(x3,y3)的二次曲线X + C X ^ 2并计算XR点处二次曲线的Y值并返回YR。这基本上是在三个2d点之间平滑插值的方法。它通常用于找到一组离散数据点的最大值或最小值的更好近似值。

所有的D,D1,D2,D3都是为了求解矩阵方程:

(1 X1 X1 ^ 2)*(A)=(Y1)

(1 X2 X2 ^ 2)*(B)=(Y2)

(1 X3 X3 ^ 2)*(C)=(Y3)

使用其他评论中提到的Cramers规则,D是矩阵行列式,D1,D2,D3是辅因子。

TRIM再次计算二次Y = A + B X + C X ^ 2,然后找到该二次方的最大值/最小值(XM,YM)。这是通过最初找到二次方具有转折点的点来完成的:如果F(X)= A + B X + C X ^ 2,则F'(XR)= B + 2 * C * XR = 0,或XR = -B / 2 * C,YR = A + B XR + C XR ^ 2。然后有一些逻辑强制返回的XM,YM最小值或最大值位于某些范围内。

代码:

XM = XR 。 。 。 IF(YM.LT.Y(1))YM = Y(1)

有点奇怪,因为如果我们假设GT和LT意味着分别大于和小于那么我们需要假设X3'<'X1否则条件(XR.GT.X(1).OR.XR .LT.X(3))是微不足道的,XM,YM设置为X1,Y1。

因此X3'<'X1并且条件表示如果二次方最大/最小值在区间(X1,X3)之外,则如前所述将(XM,YM)设置为(X1,Y1)。如果不是,那么如果Y1高于Y中的最小值/最大值,则再次将(XM,YM)设置为(X1,Y1)。

很难理解这意味着什么,我怀疑代码可能是错的!有什么想法吗?

伊万

答案 4 :(得分:1)

这是一种解决线性方程组的方法,特别是cramers rule。另请查看rule of sarrus。在那之后,你似乎构建了一个二次方程式。