>

Sympy를 사용하여 복잡한 제곱근을 복잡한 숫자로 변환하는 사용자 정의 함수를 만들고 있습니다. -sqrt(-2 + 2*sqrt(3)*I) 를 입력하면   -1 - sqrt(3)*I 의 예상 출력을 얻습니다. 그러나 -sqrt(-2.0 + 2*sqrt(3)*I) 입력  ( -2.0 가있다   -2 대신 ), 나는 출력 -1.0 - 0.707106781186547*sqrt(6)*I 를 얻는다 .

입력 식을 문자열로 변환하려고했는데 '.0 ' 를 제거했습니다.  그런 다음 코드를 실행하여 sympy.core.add.Mul 유형으로 리턴하십시오. 일반적으로 다른 문자열과 작동하지만 변수 expression  여전히 문자열입니다.

expression = str(input_expression).replace('.0 ', '')
exec(f'expression = {expression}')

sympy.core.add.Mul 의 유형을 유지하면서 식에서 float의 중복 사용을 제거하는 방법 , 내 기능이 좋은 결과를 줄 수 있습니까?

P.S.숫자 0.707106781186547   1/sqrt(2) 의 근사값입니다 . 이 숫자가 두 번째 출력에 있다는 것은 내 기능이 제대로 실행 중임을 의미하며 원하는 방식으로 출력되지 않습니다.

수정 : 어떤 이유로 든 들여 쓰기를하지 않고 함수 전체를 제거하면 코드를 자체 프로그램으로 실행하면 예상되는 결과를 얻을 수 있습니다. 코드가 작동하지 않는 함수 형태 일 때만 가능합니다.

요청한 코드 :

from IPython.display import display, Math
from sympy.abc import *
from sympy import *
def imaginary_square_root(x, y):
    return(sqrt((x + sqrt(x**2 + y**2)) / (2)) + I*((y*sqrt(2)) / (2*sqrt(x + sqrt(x**2 + y**2))))) # calculates the square root of a complex number
def find_imaginary_square_root(polynomial): # 'polynomial' used because this function is meant to change expressions including variables such as 'x'
    polynomial = str(polynomial).replace('.0 ', ' ')
    exec(f'polynomial = {polynomial}')
    list_of_square_roots = [] # list of string instances of square roots and their contents
    list_of_square_root_indexes = [] # list of indexes at which the square roots can be found in the string
    polynomial_string = str(polynomial)
    temp_polynomial_string = polynomial_string # string used and chopped up, hence the prefix 'temp_...'
    current_count = 0 # counter variable used for two seperate jobs
    while 'sqrt' in temp_polynomial_string: # gets indexes of every instance of 'sqrt'
        list_of_square_root_indexes.append(temp_polynomial_string.index('sqrt') + current_count)
        temp_polynomial_string = temp_polynomial_string[list_of_square_root_indexes[-1] + 4:]
        current_count += list_of_square_root_indexes[-1] + 4
    for square_root_location in list_of_square_root_indexes:
        current_count = 1 # second job for 'current_count'
        for index, char in enumerate(polynomial_string[square_root_location + 5:]):
            if char == '(':
                current_count += 1
            elif char == ')':
                current_count -= 1
            if not current_count: # when current_count == 0, we know that the end of the sqrt contents have been reached
                list_of_square_roots.append(polynomial_string[square_root_location:square_root_location + index + 6]) # adds the square root with contents to a list
                break
    for individual_square_root in list_of_square_roots:
        if individual_square_root in str(polynomial):
            evaluate = individual_square_root[5:-1]
            x = re(evaluate)
            y = im(evaluate)
            polynomial = polynomial.replace(eval(individual_square_root), imaginary_square_root(x, y)) # replace function used here is Sympy's replace function for polynomials
    return polynomial
poly = str(-sqrt(-2.0 + 2*sqrt(3)*I))
display(Math(latex(find_imaginary_square_root(poly))))

  • 답변 # 1

    무엇을 성취하려고합니까? 난 여전히 이해 못 하겠어. 코드 전체가 있습니다. 이것을 시도하십시오 :

    from sympy import *
    def parse(expr): print(simplify(expr).evalf().nsimplify())
    parse(-sqrt(-2.0 + 2*sqrt(3)*I))
    -1 - sqrt(3)*I
    
    

  • 답변 # 2

    여기서 싸워야 할 모든 것이 sympy가 내장 된 것을 통해 더 쉬워 질 수 있다고 생각합니다. 먼저, 사용자가 지정한 문자열을 사용한다고 가정하면 내장을 사용하는 것이 좋습니다 파서의 sympy. 두 번째로, sympy는주의해야 할 정확한 계산을 수행합니다.

    from sympy.parsing.sympy_parser import parse_expr
    def simplify_string(polynomial_str):
        polynomial = parse_expr(polynomial_str)
        return polynomial.powsimp().evalf()
    
    

    사용 예 :

    >>>simplify_string('-sqrt(-2 + 2*sqrt(3)*I)')
    -1.0 - 1.73205080756888*I
    >>>simplify_string('sqrt(sqrt(1 + sqrt(2)*I) + I*sqrt(3 - I*sqrt(5)))')
    1.54878147282944 + 0.78803305913*I
    >>>simpify_string('sqrt((3 + sqrt(2 + sqrt(3)*I)*I)*x**2 + (3 + sqrt(5)*I)*x + I*4)'
    (x**2*(3.0 + I*(2.0 + 1.73205080756888*I)**0.5) + x*(3.0 + 2.23606797749979*I) + 4.0*I)**0.5
    
    

    문제는 sympy가 수레에서 작동하거나 정확하게 작동한다는 것입니다. sympy가 제곱근의 숫자 값을 계산하기를 원한다면 명확성을 위해 float로 int가 될 수있는 것을 표시합니다. 타이핑을 고칠 수는 없지만 많은 노력을 기울이고 있지만 sympy는 기본적으로 내장되어 있습니다.

    편집

    .nsimplify() 를 사용할 수 있습니다  다항식을 사용하면 가능하면 멋진 숫자로 되돌릴 수 있지만 근사와 근사한 형식을 모두 같은 형식으로 표시 할 수는 없습니다.

관련 자료

  • 이전 c# - 정현파 운동에서 벡터를 따라 움직이는 물체
  • 다음 glob에서 os로 파일 스위치를 읽는 파이썬