[python] 삼각함수의 역함수 arccos, arcsin

numpy를 최대한 활용할 수 있는 함수를 짠다. 단일 변수나 numpy 배열로도 계산을 할 수 있어야 한다.

Numpy Array의 연산은 Broadcast(element-wise)연산으로 이루어진다. Array간의 연산은 각 요소별 연산이 이뤄지며 연산 함수 또는 연산자를 이용한다. Array와 Scalar간의 연산은 Scalar 값이 Array 각 요소별로 계산한다.

아니나 다를까 비베와 마찬가지로 numpy의 arcsin, arccos 함수에서 문제가 발생했다. 삼각함수에 의한 연산을 하다보면, 인자의 값이 -1보다 작거나, 1보다 큰 경우가 발생한다. 이렇게 되면 당연히 arcsin이나 arccos에서는 오류가 발생한다. 이를 해결하기 위하여 강인한 invsin(), invcos() 함수를 짰다.

def invsin(x):
    """
    robust arcsin function
    이론적 정의역 : -1 <= x <= 1
    실제 정의역 : -2 < x < 2
    치역 :-pi/2 <= y <= pi/2
    """
    arc_sin = np.where(np.abs(np.fix(x))==1, np.sign(x) * np.pi / 2, 
                       np.arctan(x / np.sqrt(-x * x * (np.abs(np.fix(x))!=1) + 1)))

    return arc_sin

def invcos(x):
    """
    robust arccos function
    이론적 정의역 : -1<= x <=1
    실제 정의역 : -2 < x <2
    치역 : 0 <= y <= 2*pi
    """
    arc_cos = np.where(np.abs(np.fix(x))==1, (np.pi * (x<0)),
                    np.arctan(-x / np.sqrt(-x*x*(np.abs(np.fix(x))!=1)+1)) + np.pi/2)
    return arc_cos