2012-06-03 1 views
1

vpa MatLab에서 기호식을 평가하는 데 사용할 수있는 명령에 관한 간단한 질문이 있습니다.MatLab - 가변 정밀도 산술

내 교과서는 말한다 다음.

는 "당신은 당신이 그런 배정 밀도의 기본 결과로 부동 소수점 숫자 당신은 입력을 전달해야 숫자에 sqrt, 같은 기능을 사용할 때주의해야 vpa을 올바른 평가를위한 기호화 된 문자열로 사용하십시오 : vpa('sqrt(5)/pi'). "

여기서는 전문 용어를 이해하지 못합니다. 대부분의 입력에 대해 vpa(input) 또는 vpa('input')을 입력 했는데도 제곱근이 아닌 정확히 동일한 대답을 얻는 이유는 무엇입니까? 예를 들어 vpa(sin(pi/4)) 또는 vpa('sin(pi/4)')을 입력하면 똑같은 답변을 얻을 수 있지만 vpa(sqrt(5)/pi)으로 위의 문제를 입력하면 vpa('sqrt(5)/pi')을 입력 할 때와 같은 대답을 얻지 못합니다.

누군가 내 책에서 설명한 것보다 더 자세히 설명 할 수 있다면 매우 감사 할 것입니다.

+0

이 질문을 읽는 것이 좋습니다. [MATLAB에서는 기본적으로 변수가 배정도입니까?] (http://stackoverflow.com/q/4227145/97160) – Amro

답변

4

나는 더 매트랩 전문가는 아니지만, 따옴표없이, 당신은 vpa()결과 sqrt(5)/pi 전달되고 있습니다

따옴표와 함께
vpa(sqrt(5)/pi) 
= vpa(0.7117625434171772) 

, 당신이 전달하고있는 표현sqrt(5)/pi (평가되지 않은 및 정확한 형식)을 vpa()으로 변환 한 다음 Matlab에 가변 정확도의 sqrt(5)/pi을 계산하도록 알려줍니다.

+0

감사! 그건 의미가 있습니다. 그러나, 내가 왜 단순히 죄 (pi/4)를 vpa에 입력 할 때, 나는 따옴표를 사용하는지의 여부는 중요하지 않습니까? – Kristian

+0

중요합니다. @Ben Volgt가 지적했듯이, 'sin (pi/4) = sin (45 deg) = sqrt (2)/2'는 비합리적이며 배정도 수레에 의해 정확하게 근사되지 않습니다. – Blender

+0

[docs] (http://www.mathworks.com/help/toolbox/symbolic/vpa.html)를 읽은 후'vpa'는 배정도 결과를 반환합니다.이 경우 중간 값의 정밀도 개선되었습니다. –

1

정확히 같은 대답을 얻으려면 먼저 가변 정밀도 산술 연산이 필요하지 않습니다.

그러나 sin(pi/4)은 정확히 sqrt(2)/2이어야합니다. 이는 비합리적입니다. 다른 정밀도에서 정확히 같은 대답을 얻지 않아야합니다. 아마도 결과를 어떻게 표시하고 (그리고 반올림하는지) 확인해야합니다.

+0

고마워. 나는 이것을 지금 얻는다 :). 고맙습니다! – Kristian

10

MATLAB은 일반적으로 부동 소수점 산술을 사용하여 vpa 호출 내에서 숫자를 계산하기 때문에 vpa (sin (pi/4))와 같은 숫자는 완전 정밀도와 정확히 일치한다고 가정하지 마십시오. 따라서 약 16 자리 .

그러나 여기에서 정확한 것으로 보입니다. 예를 들어, 우리는 그 사실을 알고 있습니다.

sin(pi/4) == sqrt(2)/2 

그 결과를 테스트 할 수 있습니다. 저는 100 자릿수의 정밀도를 사용하여 vpa와 내 HPF 도구를 비교합니다.

>> vpa(sin(pi/4),100) 
ans = 
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864 

>> vpa(sqrt(sym(2))/2,100) 
ans = 
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864 

>> sqrt(hpf(2,100))/2 
ans = 
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864 

>> sin(hpf('pi',100)/4) 
ans = 
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864 

필자는 파서가 입력을 입력하여 도구 상자가 더 정확하게 계산할 수 있다고 생각합니다. 전에 말했듯이, 조심하십시오. 죄란 무엇입니까 (파이/12)?

>> vpa(sin(pi/12),100) 
ans = 
0.25881904510252073947640383266843855381011962890625 

>> vpa('sin(pi/12)',100) 
ans = 
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655 

>> vpa(sin(sym('pi')/12),100) 
ans = 
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655 

>> sin(hpf('pi',100)/12) 
ans = 
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655 

첫 번째 경우에는 파서가 우리를 저장하지 않았습니다. 나머지에서는 MATLAB이 올바른 값을 계산하도록했습니다. 사실, 약간의 노력으로 sqrt (2) * (sqrt (3) - 1)/4와 같이 sin (pi/12) 값을 얻을 수 있습니다.

>> DefaultNumberOfDigits 100 
>> (sqrt(hpf(3)) - 1)*sqrt(hpf(2))/4 
ans = 
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655 

요점은, 여기 당신을 저장 파서를 신뢰하지 않습니다.

편집 : Amro의 의견을 테스트 한 결과, 저는 MATLAB이 여기에 관심의 대상이되고 있다고 진심으로 말합니다. pi가 배정도 숫자로 전달 된 경우에도 vpa가 pi의 올바른 처음 100 자리를 반환 할 수 있는지 확인하십시오. 16 진수 인 16 진수에 대한 pi (double로 사용)가 올바르지 않으므로 계속해서 문제가 발생합니다.

>> vpa(pi,100) 
ans = 
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068 

>> vpa('pi',100) 
ans = 
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068 

vpa('pi',100) - vpa(pi,100) 
ans = 
0.0 

사실을 테스트하기 위해 HPF가 찾은 것을 살펴볼 수 있습니다. HPF는 실제로 double에 저장된대로 IEEE 754 값을 가져와 HPF 번호로 변환합니다.

>> hpf(pi,100) 
ans = 
3.141592653589793115997963468544185161590576171875 

>> hpf('pi',100) 
ans = 
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068 

>> hpf('pi',100) - hpf(pi,100) 
ans = 
0.0000000000000001224646799147353177226065932275001058209749445923078164062862089986280348253421170679821480800000000 

그래서 명확하게, MATLAB은로 전달됩니다 단지 배정 밀도 값보다 더 무언가로 파이를 인식 할 수있다.

Edit2가 :

는 사실, 플레이의 비트가 여기에 무슨 일이 일어나고 있는지 알려줍니다. VPA는 파서가 아닌 까다로운 도구입니다. 분수 7/13을 고려하십시오. 우리가 이중으로 구축하고, 그 영광에 저장되어있는 부동 소수점 값을 출력한다면, 그것이 실제로 정확하지는 않다는 것을 알 수 있습니다. 이것은 예상대로입니다.

>> sprintf('%.100f',7/13) 
ans = 
0.5384615384615384359179302009579259902238845825195312500000000000000000000000000000000000000000000000 

7/13은 반복되는 10 진수 값입니다. 올바른 자릿수는 다음과 같습니다.

>> vpa('7/13',100) 
ans = 
0.5384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615385 

이제 동일한 숫자를 만들려고한다고 가정합니다. 여기에 내가 두 번 ASA의 7/13을 통과 하겠지만, 우리는 VPA 어획량과는 '오류'내가 만든 것을 인식 한을 보정 것을 볼

다음
>> sprintf('%.100f',0.538461538461538461777777777) 
ans = 
0.5384615384615384359179302009579259902238845825195312500000000000000000000000000000000000000000000000 

나는 바닥 소수점 자리에서 실수를합니다 내가 통과 한 것은 실제로 7/13에 통과했을 때와 똑같은 값입니다.

>> vpa(0.538461538461538461777777777,100) 
ans = 
0.5384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615385 

물론이 값을 문자열로 전달하면 vpa가 잘못 처리합니다. VPA 물었다 전체 정밀도에서, (죄 (PI/4), 100) VPA를 잡아 정확하게 계산할 수있는 이유

>> vpa('0.538461538461538461777777777',100) 
ans = 
0.538461538461538461777777777 

이 설명합니다. sin (pi/4)는 double로 계산되지만 vpa에서는이를 sqrt (2)/2의 배정도 버전과 동일한 수로 간주합니다.

물론주의하십시오. 예를 들어, vpa는 pi의 간단한 이동을 파악할만큼 똑똑하지 않습니다.

>> vpa(pi + 1,100) 
ans = 
4.141592653589793115997963468544185161590576171875 

>> vpa(pi,100) 
ans = 
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068 
+0

혼란을 없애기 위해 파서는 다른 함수'myFcn (sin (pi/4)) '를 호출하는 것과는 다른 vpa (sin (pi/4))의 입력을 처리하지 않습니다 ... MATLAB은 먼저 결과를 함수에 건네주기 전에 배정 밀도의 식 유한 정밀도를 사용하면 VPA가 표현할 수있는 가장 가까운 십진수 값으로 반올림됩니다. VPA는 정확한 값으로 취급합니다. 그 시점에서 그것은 당신이 원하는만큼 소수점을 계산할 수 있습니다 ... 나는 [@AndrewJanke] (http://stackoverflow.com/a/4227530/97160) 내가 연결된 질문에 좋은 설명을 준 것으로 믿습니다. – Amro

+0

대단히 감사합니다! 나는 진심으로 상세한 답변을 부탁드립니다. – Kristian

+1

@ woodchips : 당신도 맞습니다. 숫자 식으로'vpa'를 호출하면 내부적으로'vpa (sym (expr))'를 호출합니다. 이제는 'sym'가 숫자와 함께 호출 될 때, 반올림 오류 ([flag = 'r'] (http://www.mathworks.com/)를 보상하기 위해 숫자를 "합리적인"형식으로 변환하려고 시도합니다. help/toolbox/symbolic/sym.html # inputarg_flag) 인수), 이는 VPA가 표시 한대로 오류를 "수정"한 이유를 설명합니다. HPF 도구와 같은 결과를 얻고 싶다면 다음과 같을 것입니다 :'vpa (sym ('pi') - sym (pi, 'd'), 100)' – Amro

1

numeric to symbolic의 최신 문서는 해답이 있습니다.

sym 부동 소수점 입력의 반올림 오류를 수정하여 으로 수정하려고하면 정확한 기호 양식이 반환됩니다. 특히 sym는 p/q, p/q, (p/q)^(1/2), 2^q, 및 10^q 형식과 일치하는 숫자 입력에서 오류를 반올림합니다. 알맞은 크기의 정수입니다.

따라서 sin(pi/4)2^(1/2)/2 또는 (1/2)^(1/2)이 때문에 vpa 명령을 인식한다. 그러나 sqrt(5)/pi은 문서에 따라 인식 된 입력 양식이 아닙니다.