【问题标题】:Using the inverse sec function in Python在 Python 中使用逆秒函数
【发布时间】:2020-05-16 07:41:19
【问题描述】:

我正在创建一个程序,该程序可以计算从一系列高度和设定的初始速度发射弹丸的最佳角度。在我需要使用的最后一个等式中,存在一个反 sec 函数,它会引起一些麻烦。

我已导入数学并尝试使用 asec(whatever),但似乎数学无法计算逆秒函数?我也知道 sec(x) = 1/cos(x) 但是当我将 1/cos(x) 代入方程并代数求解 x 时,它变成了一个非真实的结果:/。

我的代码如下:

print("This program calculates the optimum angles to launch a projectile from a given range of heights and a initial speed.")
x = input("Input file name containing list of heights (m): ")
f = open(x, "r")
for line in f:
    heights = line
    print("the heights you have selected are : ", heights)
f.close()

speed = float(input("Input your initial speed (m/s): "))
print("The initial speed you have selected is : ", speed)

ran0 = speed*speed/9.8 
print(ran0)

f = open(x, "r")
for line in f:
    heights = (line)
    import math
    angle = (math.asec(1+(ran0/float(heights))))/2
    print(angle)

f.close()

所以我的主要问题是,有没有办法在 python 中找到任何东西的倒数,而无需安装和导入其他东西? 我意识到这可能是一个基于数学的问题,而不是一个编码问题,但是感谢任何帮助:)。

【问题讨论】:

    标签: python math


    【解决方案1】:

    假设我们正在寻找实数x,其反正切角为θ。然后我们有:

    θ = arcsec(x)
    sec(θ) = x
    1 / cos(θ) = x
    cos(θ) = 1 / x
    θ = arccos(1/x)
    

    因此,根据这个推理,您可以将 arcsecant 函数编写为:

    from math import acos
    
    def asec(x):
        return acos(1/x)
    

    【讨论】:

    • ...仍然导入 math
    • @norok2,由于他们在尝试中也使用了math,我猜当他们说“导入其他东西”时,OP 的意思类似于scipy
    • @RyanPeen,如果你仔细观察,你会发现你的最终等式是错误的:它应该是θ = (asec(1+R/h)) / 2。注意 h & R 的反转和 asec 的使用。如果你想写成acos,那就是θ = (acos(1 / (1+R/h))) / 2,相当于θ = (acos(h / (h+R))) / 2
    • @RyanPeen,所以你的错误在于反转1 + R/h - 它的倒数不是 1 + h/R,它是1 / (1 + R/h),即h / (h + R)
    【解决方案2】:

    “我也明白 sec(x) = 1/cos(x) 但是当我 sub 1/cos(x) ...” 你必须使用 sec 或 asec 吗?

    因为sec(x)= 1/cos(x)asec(x) = acos(1/x)。注意符号 ^-1 不明确,cos^-1(x) = acos(x)[cos(x)]^-1 不同。

    angle = (math.asec(1+(ran0/float(heights))))/2
    

    asec 不是从 -1 到 1 定义的 如果您的高度低于零,因此(ran0/float(heights)) 的结果介于 -2 和 0 之间,那么您的角度将是非实数。

    我真的不知道这是否是您要求的,但我希望它有所帮助。

    【讨论】:

    • OP 显然需要 sec 的逆(即反函数,不是倒数):角度是输出,而不是输入。
    • 如果他需要反函数,他不需要 asec(它是倒数),他只需要 1/(sec(x)),所以只需要 cos(x) ?我可能误解了你的意思,但我认为他在这里需要互惠
    • asec 不是 sec 的倒数。它是 sec 函数的反函数。
    • @RyanPeen 评论接受的答案(我无权评论):sec(2θ) = 1 + R/h 1/cos(2θ)=1+R/h1/(1+R/h)=cos(2θ) 所以θ =acos(1/(1+R/h))/2@MarkDickinson:你是对的,对不起,我'm french 和 french 这两个意思是相反的!
    【解决方案3】:

    如果math 可以导入,则可以使用:

    import math
    
    
    def asec(x):
        if x == 0:
            return 1j * math.inf
        else:
            return math.acos(1 / x)
    

    关于重写asec(x)的其他方式,请关注相关的Wikipedia article


    或者,您可以使用Taylor series 扩展,它总是以多项式形式出现,因此,虽然这只是给定点附近的近似值,但它不需要math

    对于asec(x),它的泰勒展开式在±∞(也称为Laurent seriesis given by(不使用math)的邻域内:

    def asec_taylor(x, pi=3.14159265):
        if x == 0:
            return 1j * float('inf')
        else:
            return pi / 2 - 1 / x - 1 / (6 * x ** 3) - 3 / (40 * x ** 5)
    

    您可以快速检查离 0 越远,近似值越好:

    for x in range(-10, 10):
        print(x, asec(x), asec_taylor(x))
    
    -10 1.6709637479564565 1.670963741666667
    -9 1.6821373411358604 1.6821373299281108
    -8 1.696124157962962 1.6961241346516926
    -7 1.714143895700262 1.7141438389326868
    -6 1.7382444060145859 1.7382442416666668
    -5 1.7721542475852274 1.7721536583333335
    -4 1.8234765819369754 1.823473733854167
    -3 1.9106332362490186 1.910611139814815
    -2 2.0943951023931957 2.0939734083333335
    -1 3.141592653589793 2.8124629916666666
    0 (nan+infj) (nan+infj)
    1 0 0.32912965833333346
    2 1.0471975511965979 1.0476192416666668
    3 1.2309594173407747 1.2309815101851853
    4 1.318116071652818 1.3181189161458333
    5 1.369438406004566 1.3694389916666667
    6 1.4033482475752073 1.4033484083333334
    7 1.4274487578895312 1.4274488110673134
    8 1.4454684956268313 1.4454685153483076
    9 1.4594553124539327 1.4594553200718894
    

    【讨论】:

    • 我认为这些特殊情况有点混乱。根本不需要特殊情况 1-1 - 如果通过,它们会正常工作。您可能希望将特殊情况 inf 作为输入(映射到 0)。将0 映射到inf 是错误的:asec(0) 只是未定义,就像acos(2.0) 未定义一样:0 不在sec 的范围内(甚至不在范围内) .
    • @MarkDickinson 我意识到1-1 是不需要的,我只是盲目地查看维基百科的文章,说该公式不适用于10,和-1,但我想它需要修复。就asec(0) 而言,这实际上是复无穷大。 acos(2.0) 也不是未定义的,只是不在实数域中。
    • 在复杂情况下(很确定这 不是 OP 想要的),您需要在复平面上从 -1 到 1 进行分支切割。其他切割选择是可能,但这是最明显的选择。然后在0 处有一个奇点,因此很难在那里给出合理的结果。例如,如果您沿着虚轴接近,您将得到 pi/2 的实部,而虚部将接近 +/- 无穷大,这取决于您在分支切口的哪一侧。但是如果从 1+1j 的方向接近 0,就会得到不同的极限。 complex(nan, +/-inf) 是我们能做的最好的了。
    【解决方案4】:

    如果您可以尝试 sec 的倒数,那么它将与

    >>>from mpmath import *
    >>> asec(-1)
    
     mpf('3.1415926535897931')
    

    这里是您可以更好地理解的链接 - [http://omz-software.com/pythonista/sympy/modules/mpmath/functions/trigonometric.html]

    【讨论】:

    • 来自 OP:“无需安装和导入其他内容”。我认为使用mpmath 与此相反(有一个简单的答案,不涉及任何第三方库)。
    猜你喜欢
    • 1970-01-01
    • 2017-07-17
    • 2017-07-11
    • 2012-04-23
    • 2015-09-24
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多