如何找到多项式作为非线性方程的近似解?

问题描述

对于我的小 FLOSS project,我想近似计算点接触的最大剪应力的 Green et al. 方程:

绘制时应该是这样的

Maxima 中的相同方程:

A: (3 / 2 / (1 + zeta^2) - 1 - nu + zeta * (1 + nu) * acot(zeta)) / 2;

现在要找到最大值 ?max,我将上述方程与 ? 进行微分:

diff(A,zeta);

尝试求解 ? 的导数:

solve(diff(A,zeta),zeta); 

我最终得到了一个我无法实际使用或测试的多页方程式。

现在我想知道是否可以找到多项式:

?max = a + b * ? + c * ?2 + ...

大致解决

diff(A,zeta) = 0

0 < ? < 0.50 < ? < 1 的等式。

解决方法

(1) 可能要尝试的第一件事就是以数字方式求解 diff(A,zeta) = 0(在这种情况下通过 find_root)。以下是一个 nu 值的近似解:

(%i2) A: (3 / 2 / (1 + zeta^2) - 1 - nu + zeta * (1 + nu) * acot(zeta)) / 2;
                                         3
        (nu + 1) zeta acot(zeta) + ------------- - nu - 1
                                          2
                                   2 (zeta  + 1)
(%o2)   -------------------------------------------------
                                2
(%i3) dAdzeta: diff(A,zeta);
                             (nu + 1) zeta      3 zeta
       (nu + 1) acot(zeta) - ------------- - ------------
                                   2              2     2
                               zeta  + 1     (zeta  + 1)
(%o3)  --------------------------------------------------
                               2
(%i4) find_root (subst ('nu = 0.25,dAdzeta),zeta,1);
(%o4)                  0.4643131929806135

这里我将绘制不同 nu 值的近似解:

(%i5) plot2d (find_root (dAdzeta,1),[nu,0.5]) $

让我们将其与方程一起绘制。 10 这是格林在论文中推导出的近似值:

(%i6) plot2d ([find_root (dAdzeta,0.38167 + 0.33136*nu],0.5]) $

(2) 我研究了一些不同的方法来获得象征性的解决方案,这里有一些可能可行的方法。请注意,这也是一个近似值,因为它源自泰勒级数。你必须看看它是否足够好。

找到 acot 的低阶泰勒级数并将其插入 dAdzeta

(%i7) acot_approx: taylor (acot(zeta),1/2,3);
                             1              1 2              1 3
                   4 (zeta - -)   8 (zeta - -)    16 (zeta - -)
                             2              2                2
(%o7)/T/ atan(2) - ------------ + ------------- + -------------- + . . .
                        5              25              375
                                                         
(%i8) dAdzeta_approx: subst (acot(zeta) = acot_approx,dAdzeta);
         (25 atan(2) - 10) nu + 25 atan(2) - 34
(%o8)/T/ --------------------------------------
                           50
                         1                            1 2
   (80 nu + 104) (zeta - -)   (320 nu + 1184) (zeta - -)
                         2                            2
 - ------------------------ + ---------------------------
             125                          625
                            1 3
   (640 nu + 11584) (zeta - -)
                            2
 - ---------------------------- + . . .
               9375

近似 dAdzeta 是 zeta 中的三次多项式,所以我们可以解决它。结果是一个大杂乱的表情。前两个解决方案很复杂,第三个是真实的,所以我想这就是我们想要的。

(%i9) zeta_max: solve (dAdzeta_approx = 0,zeta);
<large mess omitted here>

(%i10) grind (zeta_max[3]);
zeta = ((625*sqrt((22500*atan(2)^2+30000*atan(2)-41200)*nu^4
                   +(859500*atan(2)^2-1878000*atan(2)+926000)
                    *nu^3
                   +(9022725*atan(2)^2-15859620*atan(2)+7283316)
                    *nu^2
                   +(15556950*atan(2)^2-36812760*atan(2)
                                       +19709144)
                    *nu+7371225*atan(2)^2-22861140*atan(2)
                   +17716484))
     /(256*(10*nu+181)^2)
     +((3*((9375*nu+9375)*atan(2)+4810*nu+6826))/(1280*nu+23168)
      -((90*nu+549)*(1410*nu+4281))/((10*nu+181)*(80*nu+1448)))
      /6+(90*nu+549)^3/(27*(10*nu+181)^3))
     ^(1/3)
     -((1410*nu+4281)/(3*(80*nu+1448))
      +((-1)*(90*nu+549)^2)/(9*(10*nu+181)^2))
      /((625*sqrt((22500*atan(2)^2+30000*atan(2)-41200)*nu^4
                   +(859500*atan(2)^2-1878000*atan(2)+926000)
                    *nu^3
                   +(9022725*atan(2)^2-15859620*atan(2)+7283316)
                    *nu^2
                   +(15556950*atan(2)^2-36812760*atan(2)
                                       +19709144)
                    *nu+7371225*atan(2)^2-22861140*atan(2)
                   +17716484))
       /(256*(10*nu+181)^2)
       +((3*((9375*nu+9375)*atan(2)+4810*nu+6826))
        /(1280*nu+23168)
        -((90*nu+549)*(1410*nu+4281))
         /((10*nu+181)*(80*nu+1448)))
        /6+(90*nu+549)^3/(27*(10*nu+181)^3))
       ^(1/3)+(90*nu+549)/(3*(10*nu+181))$

我尝试了一些想法来简化解决方案,但没有找到任何可行的方法。它是否可以以目前的形式使用,我会让你做判断。将近似解与其他两个一起绘制似乎表明它们都非常接近。

(%i18) plot2d ([find_root (dAdzeta,0.38167 + 0.33136*nu,rhs(zeta_max[3])],0.5]) $
,

这是一种不同的方法,它是通过 find_root 计算一些近似值,然后组装一个近似函数,它是三次多项式。这利用了我编写的一个名为 polyfit 的小函数。请参阅:https://github.com/maxima-project-on-github/maxima-packages/tree/master/robert-dodier,然后查看 polyfit 文件夹。

(%i2) A: (3 / 2 / (1 + zeta^2) - 1 - nu + zeta * (1 + nu) * acot(zeta)) / 2;
                                         3
        (nu + 1) zeta acot(zeta) + ------------- - nu - 1
                                          2
                                   2 (zeta  + 1)
(%o2)   -------------------------------------------------
                                2
(%i3) dAdzeta: diff(A,zeta);
                             (nu + 1) zeta      3 zeta
       (nu + 1) acot(zeta) - ------------- - ------------
                                   2              2     2
                               zeta  + 1     (zeta  + 1)
(%o3)  --------------------------------------------------
                               2
(%i4) nn: makelist (k/10.0,k,5);
(%o4)            [0.0,0.1,0.2,0.3,0.4,0.5]
(%i5) makelist (find_root (dAdzeta,nu,nn);
(%o5) [0.3819362006941755,0.4148794361988409,0.4478096487716516,0.4808644852928955,0.5141748609122403,0.5478684611102143]

(%i7) load ("polyfit.mac");
(%o7)                      polyfit.mac
(%i8) foo: polyfit (nn,%o5,3) $
(%i9) grind (foo);

[beta = matrix([0.4643142407230925],[0.05644202066198245],[2.746081069103333e-4],[1.094924180450318e-4]),Yhat = matrix([0.3819365703555216],[0.4148782994206623],[0.4478104992708994],[0.4808650578507559],[0.5141738631047557],[0.5478688029774219]),residuals = matrix([-3.696613460890674e-7],[1.136778178534303e-6],[-8.504992477509354e-7],[-5.725578604010018e-7],[9.97807484637292e-7],[-3.418672076538343e-7]),mse = 5.987630959972099e-13,Xmean = 0.25,Xsd = 0.1707825127659933,f = lambda([X],block([Xtilde:(X-0.25)/0.1707825127659933,X1],X1:[1,Xtilde,Xtilde^2,Xtilde^3],X1 . matrix([0.4643142407230925],[1.094924180450318e-4])))]$
(%o9)                         done

不确定哪些部分最相关,所以我只返回了一些东西。可以通过 assoc 提取项目。这里我将提取构造函数。

(%i10) assoc ('f,foo);
                                        X - 0.25
(%o10) lambda([X],block([Xtilde : ------------------,0.1707825127659933
                       2        3
X1 : [1,Xtilde ],[  0.4643142407230925  ]
     [                      ]
     [ 0.05644202066198245  ]
X1 . [                      ]))
     [ 2.746081069103333e-4 ]
     [                      ]
     [ 1.094924180450318e-4 ]
(%i11) %o10(0.25);
(%o11)                 0.4643142407230925

绘制函数表明它接近 find_root 返回的值。

(%i12) plot2d ([find_root (dAdzeta,%o10],0.5]);

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...