Using the inverse sec function in Python

天涯浪子 提交于 2020-06-16 17:01:40

问题


I am creating a program that calculates the optimum angles to fire a projectile from a range of heights and a set initial velocity. Within the final equation I need to utilise, there is an inverse sec function present that is causing some troubles.

I have imported math and attempted to use asec(whatever) however it seems math can not calculate inverse sec functions? I also understand that sec(x) = 1/cos(x) but when I sub 1/cos(x) into the equation instead and algebraically solve for x it becomes a non real result :/.

The code I have is as follows:

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()

So my main question is, is there any way to find the inverse sec of anything in python without installing and importing something else? I realise this may be more of a math based problem than a coding problem however any help is appreciated :).


回答1:


Let's say we're looking for real number x whose arcsecant is angle θ. Then we have:

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

So with this reasoning, you can write your arcsecant function as:

from math import acos

def asec(x):
    return acos(1/x)



回答2:


"I also understand that sec(x) = 1/cos(x) but when I sub 1/cos(x) ..." Do you have to use sec or asec ?

Because sec(x)= 1/cos(x) and asec(x) = acos(1/x). Be careful the notation ^-1 is ambiguous, cos^-1(x) = acos(x) is different of [cos(x)]^-1.

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

asec is not defined from -1 to 1 If you have a height lower than zero, and so the result of (ran0/float(heights)) is between -2 and 0, your angle will be non real.

I don't really know if this is what you asked for, but I hope it helps.




回答3:


If math is OK for you to import, then you can use:

import math


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

For some other ways of of re-writing asec(x), feast your eyes on the relevant Wikipedia article.


Alternatively, you could use Taylor series expansions, which always come in polynomial form, so, although that is only an approximation in a neighborhood of a given point, it would not require math.

For asec(x), its Taylor expansion in a neighborhood of ±∞ (also known as Laurent series) is given by (without using 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)

You can quickly check that the farther you are from 0, the better the approximation holds:

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



回答4:


If you can try of inverse of sec then it will be same as

>>>from mpmath import *
>>> asec(-1)

 mpf('3.1415926535897931')

Here are the link in where you can better understand - [http://omz-software.com/pythonista/sympy/modules/mpmath/functions/trigonometric.html]



来源:https://stackoverflow.com/questions/61833460/using-the-inverse-sec-function-in-python

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!