2011-08-31 2 views
3

Manipulate 문에서 계산해야하는 변수에 할당 된 코드로 Manipulate을 처리하는 데 문제가 있습니다. 여기에 내부 연산 식 평가

Manipulate output 1

test1={a,b,c}; 
Manipulate[test1,{a,0,10,.1},{b,0,10,.1},{c,0,10,.1}] 

그래서 {a, b, c}가 업데이트되지 않습니다 ... 어떻게되는지입니다. 좋아, 무엇이든의이

enter image description here

Manipulate[Evaluate[test1],{a,0,10,.1},{b,0,10,.1},{c,0,10,.1}] 
지금 작동 TEST1의 평가를 시행 할 수 있습니다. 나는이

Manipulate[ListPlot[Evaluate[test1]],{a,0,10,.1},{b,0,10,.1},{c,0,10,.1}] 
Manipulate[Evaluate[ListPlot[test1]],{a,0,10,.1},{b,0,10,.1},{c,0,10,.1}] 

처럼, 조작 요소의 목록을 플롯하려면하지만 모두 추격전에서

enter image description here

와 끝까지.

저는 Mathematica의 설명서에서 'Evaluate Expressions inside Dynamic or Manipulate'을 알고 있습니다. 그러나 제 문제에 대한 해결책을 제공하지 못한다고 확신합니다. 여기

+1

매우 비슷한 질문 : [매개 변수 변경 업데이트 조작 된 플롯] (http://stackoverflow.com/q/7126532/211232) – WReach

답변

8

그래서 문제 test1이 전역 변수 Global`a, 의 관점에서 정의되지만이 DynamicModule 의해 생성되므로 로컬이다 조작하는 상기 a 정의된다는 것이다. 이것은 그의 Hold[a] 예제로 보여준 acl입니다.

은 어쩌면이 문제를 해결하는 가장 쉬운 방법은에 test1를 삽입 With을 사용하는 것입니다 조작 :

Clear[a, b, c] 
test1 = {a, b, c}; 
With[{test1 = test1}, 
    Manipulate[test1, {a, 0, 10, .1}, {b, 0, 10, .1}, {c, 0, 10, .1}]] 

Manipulate 결코 실제로 test1을 볼 수 없습니다이 방법이보고 모두가 {a,b,c}입니다 그 다음 제대로을 위하여 계속하는 지방화하다. 비록 Manipulate이 실행되기 전에 a,b,c에 값이 주어지면 문제가 발생합니다. 따라서 Clear[a,b,c] 명령을 사용하십시오.

나는 모범 사례이 모든 로컬 변수를 조작에 완전히 명시한다고 생각합니다. 그래서 당신은 다음과 같이해야합니다.

Clear[a, b, c, test1] 
test1[a_, b_, c_] := {a, b, c}; 
Manipulate[test1[a, b, c], {a, 0, 10, .1}, {b, 0, 10, .1}, {c, 0, 10, .1}] 

이렇게하면 글로벌 vs 로컬 변수에 문제가 발생하지 않습니다. 다시 돌아와서 자신의 코드를 다시 읽어야 할 때도 쉽게 사용할 수 있습니다.


편집는 의견 의 질문에 대답 "나는 정말 이해하려는 이유는 다소 중첩 ListPlot 작동하지 않습니다 평가?". IANLS (나는 Leonid Shifrin이 아닙니다.) 그래서 완벽한 Mathematica (non) standard 평가 시퀀스가 ​​내 뇌에서 실행되지는 않지만, 무슨 일이 일어나는지 설명하려고 노력할 것입니다.

그래, Plot과 달리 ListPlot은 변수를 지역화 할 필요가 없으므로 AttributeHoldAll이 없습니다.

의 당신의 예와 비슷한 정의 할 수 있습니다 다음 Trace 살펴보면

ClearAll[a, test] 
test = {a, a + 1}; 

당신이 준 마지막 예제

Manipulate[Evaluate[ListPlot[test]], {a, 0, 1}] 

등을이 첫 번째는 첫 번째 인수를 평가하는 것을 볼 수 이고 a이 아직 현지화되지 않았으므로 빈 목록 플롯이 생성됩니다. 이를 참조하려면

ListPlot[{a, a + 1}]//InputForm 

가 빈 그래픽 밖으로 던져 된 a 상징적 값으로

Graphics[{}, {AspectRatio -> GoldenRatio^(-1), Axes -> True, AxesOrigin -> {0, 0}, PlotRange -> {{0., 0.}, {0., 0.}}, PlotRangeClipping -> True, PlotRangePadding -> {Scaled[0.02], Scaled[0.02]}}] 

객체 얻기 위해, 그들이 Manipulate 현지화되지 및 다른 일이 너무 많은 수 없습니다 실행 .

Manipulate이 변수를 현지화 할 때까지 ListPlot을 호출하지 않고도 첫 번째 인수를 계속 평가하면이 문제를 해결할 수 있습니다. 예를 들어, 다음과 같은 작업을 모두 ListPlot가 조금이라도 불평없이 숫자가 아닌 값을 버린다는 사실은, 아마 기능

Manipulate[Evaluate[listPlot[test]], {a, 0, 1}] /. listPlot -> ListPlot 
Manipulate[Evaluate[Hold[ListPlot][test]], {a, 0, 1}] // ReleaseHold 

입니다

하지만, 같은 버그 (추적하는 일부 성가 시게 하드로 이어질 수 이 질문은에 관련된다). 플롯 값이 숫자가 아니면 ListPlot으로 평가되지 않은 값을 반환하는 것이 더 일관성있는 (그러나 덜 유용할까요?) 행동 일 수도 있습니다. 또는 적어도 숫자가 아닌 일부 지점이 삭제되었다는 경고를 발행하십시오.

마지막 두 번째 부분은입니다.Manipulate 이후 지금

Manipulate[ListPlot[Evaluate[test]], {a, 0, 1}] 

이 속성 HoldAll을 가지고 같은) 흥미, 그것이 수행하는 첫 번째 일은 당신이 Trace 보면, 당신은 Hold[ListPlot[Evaluate[test]]]이 주위에 실시되는 볼 수 있도록 Hold에 인수를 마무리하고, 보인다. Possible Issues 섹션에 설명되어 있듯이 "평가는 첫 번째 레벨에서만 작동하며 보류 된 함수 내에서 직접 작동합니다"입니다. Evaluate으로 표시되지 않습니다. 즉, test은 변수가 현지화 될 때까지 평가되지 않으므로 로컬 변수 (DynamicModule) a이 아닌 a 전역 변수가됩니다.

그것은 다음과 같은 변화가 어떻게 작동하는지에 대해 생각 가치가

ClearAll[a, test, f, g] 
SetAttributes[g, HoldAll]; 
test = {a, a + 1}; 

Grid[{ 
    {Manipulate[test, {a, 0, 1}], Manipulate[Evaluate[test], {a, 0, 1}]}, 
    {Manipulate[f[test], {a, 0, 1}], 
    Manipulate[f[Evaluate[test]], {a, 0, 1}]}, 
    {Manipulate[g[test], {a, 0, 1}], 
    Manipulate[g[Evaluate[test]], {a, 0, 1}]} 
    }] 

brainpain

+0

+1'With' 솔루션과 유사한 맥락에서, [Manipulate [Evaluate @ test1, ...]'을 사용할 수 있습니다. 그러나 로컬 변수를 사용하는 것이 가장 좋습니다. – WReach

+0

@WReach : 예,하지만'Evaluate'는'ListPlot' 버전의 질문에서 작동하지 않습니다 ... (btw +1 to [your answer] (http://stackoverflow.com/questions/7126532/update- 매개 변수 변경/7126947 # 7126947)을 거의 동일한 질문으로 변경) – Simon

+0

문제를 설명하기 위해 최소한의 예를 게시했음을 강조하고자합니다. 실제로 나는 훨씬 더 많은 매개 변수를 다루고 있으므로 명시 적으로 쓰고 싶지는 않습니다. +1 With the 솔루션 (변수를 지우는 것은 문제가되지 않습니다). 그러나, 나는 왜 Evaluate가 다소 중첩 된 ListPlot에서 작동하지 않는지 이해하고 싶습니다. – phantomas1234

3

가 작동하지 않는 이유입니다 :

Manipulate[ 
{ 
    Hold[a] 
    }, 
{a, 0, 10, .1}, 
{b, 0, 10, .1}, 
{c, 0, 10, .1} 
] 

enter image description here

하나는 다양한 방법으로이 문제를 해결할 수 있습니다. 하나는 단순히과 같이, 지역화 된 변수 test1을 정의하는 것입니다 : 다음

ClearAll[test1, a, b, c]; 
Manipulate[ 
test1 = {a, b, c}; 
{ 
    test1 
    }, 
{a, 0, 10, .1}, 
{b, 0, 10, .1}, 
{c, 0, 10, .1} 
] 

및 예

ClearAll[test1, a, b, c]; 
Manipulate[ 
test1 = {a, b, c}; 
[email protected], 
{a, 0, 10, .1}, 
{b, 0, 10, .1}, 
{c, 0, 10, .1} 
] 

작품.

당신은 세계적으로 test1을 정의하려는 경우

ClearAll[test1, a, b, c]; 
test1 = {a, b, c}; 
Manipulate[ 
test1, 
{a, 0, 10, .1}, 
{b, 0, 10, .1}, 
{c, 0, 10, .1}, 
LocalizeVariables -> False, 
TrackedSymbols -> test1 
] 

작품.

+0

+1하지만 첫 번째 해결 방법은 변경 될 때마다 'test1'을'Set '해야합니다. 이 경우 오버 헤드가 많지 않지만 피하는 것이 가장 좋습니다. 두 번째 솔루션은 {a, b, c}가 원치 않는 결과를 초래할 수있는 전역 변수가되는 "문제"를 가지고 있습니다. – Simon

+1

@Simon 나는 두 가지 모두에 동의한다. (답은 "올바른 길"은 전역 변수를 사용하지 않고 "With"라는 문자 그대로 정의를 주입하는 것이다. 여기에있는 아이디어는 질문에 주어진 접근 방식을 최소한으로 변경하여 작동하도록하는 것이 었습니다. – acl