从pickle加载缓慢/失败

2024-05-23 20:30:57 发布

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

我用高斯-勒让德积分来计算积分。为了得到勒让德多项式的必要根,我遵循了here概述的步骤,并且它是有效的。为了节省生成高阶多项式根的时间,我添加了try:except:例程来存储和加载以前运行时生成的根。然而,在一些根以上,这变得非常缓慢。对于20根,加载延迟几乎不存在,对于25根,加载延迟是可以注意到的(大约几秒钟),对于30根,加载延迟根本没有进展(CPU为100%,但没有输出到控制台,没有错误消息。)为什么会这样,我能做得更好吗?毕竟,它应该只是从一个文件中读取一个浮动列表

import math
import pickle

def Legendre(position, order):
    # calculates the value of the Legendre polynomial of any order at a position
    # has to be a separate function because of recursion
    if order == 0:
        return 1.0
    elif order == 1:
        return position
    else:
        return ((2 * order - 1.0) * position * Legendre(position, order - 1) - (order - 1) * Legendre(position,
                                                                                                      order - 2)) / float(
            order)


def Legendrederivative(position, order):
    # calculates the value of the derivative of the Legendre polynomial of any order at a position
    if order == 0:
        return 0.0
    elif order == 1:
        return 1.0
    else:
        return order / (math.pow(position, 2) - 1) * (
        position * Legendre(position, order) - Legendre(position, order - 1))


def Legendreroots(order, tolerance=10):
    try:
        with open('rootsfile' + str(order) + 't' + str(tolerance) + '.txt', 'r+') as filecontents:
            roots = pickle.load(filecontents)
        return roots
    except:
        if order == 0 or order == 1:
            raise ValueError('No roots possible')
        roots = []
        for counter in range(1, order + 1):
            x = math.cos(math.pi * (counter - 0.25) / (float(order) + 0.5))
            iterationcounter = 0
            dx = 10 * 10 ^ (-tolerance)
            while (abs(dx) > tolerance) and iterationcounter < 1000:
                dx = - Legendre(x, order) / Legendrederivative(x, order)
                x += dx
                iterationcounter += 1
                if iterationcounter == 999:
                    print 'Iteration warning!', dx
            roots.append(x)
            print 'root' + str(counter) + 'found!'
        with open('rootsfile' + str(order) + 't' + str(tolerance) + '.txt', 'w+') as filecontents:
            pickle.dump(roots, filecontents)
        return roots

roots = Legendreroots(20)

前两个函数分别是多项式及其一阶导数的函数定义,第三个函数生成根并处理文件I/O


Tags: ofthereturnifpositionordermathtolerance