如何提高有限元计算的数值表示精度?

2024-05-13 23:50:55 发布

您现在位置:Python中文网/ 问答频道 /正文

对于我的硕士论文,我正在做一个有限元程序,需要很多精度-超过30个小数位,我想-但我不能这样做,因为NumPy的float64数据类型只允许16位。你知道吗

我尝试过NumPy longdoull,但是当我尝试使用他们的求解方法时,它给了我一个错误。你知道吗

你们知道更简单的方法来提高精度吗?就像MATLAB甚至Maple一样。提前谢谢!你知道吗


Tags: 方法程序numpy错误精度数据类型有限元maple
1条回答
网友
1楼 · 发布于 2024-05-13 23:50:55

上述FEM/HPC从业人员提出的几乎所有反对意见都是合法的,但也暴露在长期/低退化传热模拟(在大的、细粒度的时间尺度上)和/或其他数值处理相关退化的情况下,主要来自IEEE-754表示法的固有限制(在deep-re-iterations等人)仅仅需要标准数值处理的一步下,
+我也尊重OP的需要/希望为她/他的进一步努力找到一些方向。

可行:但要付出代价……

在条件恶劣的数值分析中使用了以下方法,这起到了很好的效果。你知道吗

pure_DEC的方式实现了新的代价函数和梯度函数,然后使用LSQ最小化求解器。你知道吗

问题不是精度本身,而是一个聪明的问题-(重新)公式化,以便以最小的[时间]域代价利用高级的decimal-类内置操作。你知道吗

>>> with decimal.localcontext() as locCTX:
       ...      for aPREC in range( 20, 31 ):
       ...          locCTX.prec = aPREC
       ...          ( pure_dec_LSQ_5DoF( locCTX, dec_fmin_x0_SEARCH_TRIM_TO_BE_PRECISE, decX, decY ), pure_dec_RESi( locCTX, dec_fmin_x0_SEARCH_TRIM_TO_BE_PRECISE, decX, decY ) )
       ...
       (Decimal('0.038471115298826195147'),           (Decimal('0.023589050081780503'),           Decimal('-0.082605913918299990'),           Decimal('0.150647690402532134'),           Decimal('-0.091630826566012630')))
       (Decimal('0.0384711152988261953165'),          (Decimal('0.0235890500817804889'),          Decimal('-0.0826059139182999933'),          Decimal('0.1506476904025321349'),          Decimal('-0.0916308265660126301')))
       (Decimal('0.03847111529882619531420'),         (Decimal('0.02358905008178048823'),         Decimal('-0.08260591391829999331'),         Decimal('0.15064769040253213501'),         Decimal('-0.09163082656601263007')))
       (Decimal('0.038471115298826195324048'),        (Decimal('0.023589050081780488368'),        Decimal('-0.082605913918299993309'),        Decimal('0.150647690402532135021'),        Decimal('-0.091630826566012630071')))
       (Decimal('0.0384711152988261953231489'),       (Decimal('0.0235890500817804883582'),       Decimal('-0.0826059139182999933087'),       Decimal('0.1506476904025321350199'),       Decimal('-0.0916308265660126300707')))
       (Decimal('0.03847111529882619532322276'),      (Decimal('0.02358905008178048835950'),      Decimal('-0.08260591391829999330863'),      Decimal('0.15064769040253213501998'),      Decimal('-0.09163082656601263007070')))
       (Decimal('0.038471115298826195323213788'),     (Decimal('0.023589050081780488359358'),     Decimal('-0.082605913918299993308625'),     Decimal('0.150647690402532135019974'),     Decimal('-0.091630826566012630070702')))
       (Decimal('0.0384711152988261953232136753'),    (Decimal('0.0235890500817804883593541'),    Decimal('-0.0826059139182999933086251'),    Decimal('0.1506476904025321350199740'),    Decimal('-0.0916308265660126300707023')))
       (Decimal('0.03847111529882619532321367314'),   (Decimal('0.02358905008178048835935336'),   Decimal('-0.08260591391829999330862505'),   Decimal('0.15064769040253213501997413'),   Decimal('-0.09163082656601263007070231')))
       (Decimal('0.038471115298826195323213665675'),  (Decimal('0.023589050081780488359353229'),  Decimal('-0.082605913918299993308625043'),  Decimal('0.150647690402532135019974132'),  Decimal('-0.091630826566012630070702306')))
       (Decimal('0.0384711152988261953232136649869'), (Decimal('0.0235890500817804883593532187'), Decimal('-0.0826059139182999933086250437'), Decimal('0.1506476904025321350199741307'), Decimal('-0.0916308265660126300707023064')))

从技术上讲,精确的“扩展”是没有限制的,但是,时间…:

# [PERF] @ .prec ==    40               ~         4,000 [us] ~     4 [ms]
#        @ .prec == 10000 !!!     - ~   991,875,234 [us] ~ 1,000 [ s]

这是为获得预期的(主要是无限制的本身)精度而支付的成本。你知道吗

import decimal
import numpy as np
import zmq

try:
    if  isinstance( decCTX, decimal.Context ):
        pass      # decCTX  already exists
except:
                    decCTX      = decimal.getcontext()
                    decCTX.prec = 60

decX = np.asarray( ( decimal.Decimal(  3.4 ), decimal.Decimal(  3.5 ), decimal.Decimal(  3.7 ), decimal.Decimal(   4.3 ), ) )
decY = np.asarray( ( decimal.Decimal( 65   ), decimal.Decimal( 85   ), decimal.Decimal( 97   ), decimal.Decimal( 100   ), ) )

...

dec_fmin_x0_SEARCH_ADAPTIVE = np.asarray( (                     decimal.Decimal( -101000000010553.05594055493064099456356276561617988943684402001075635                                                                                                                                                                                        ),
                                                                decimal.Decimal(               -8.660605201193546246                                                                                                                                                                                                                           ),
                                                                decimal.Decimal(                0.00021842459768549                                                                                                                                                                                                                            ),
                                                                decimal.Decimal(               99.9259163119085989057939988625810620201012857893012816197730189907743792931209843327426339987914746365315172977942868845721827684076717423116961495794648319380554868846324870276029626886129186998300662535940937605435069739237317269895772  ),
                                                                decimal.Decimal(                2.64971757369295002249999999827154484100152060917026952223212241653783649669777780217778380697777777796977777777969777777777969777777779697777777796977777805877778058777780587777777800577777780057777778005777777800577777774817774778285740 ),
                                                                )
                                           )

相关问题 更多 >