2011-12-25 57 views
6

hãy xem xét:Nested Thao tác trong Mathematica

Function[subID, 
     pointSO[subID] = RandomInteger[{1, 4}, {5, 2}]] /@ {"subA", "subB"}; 

Manipulate[ 
      Manipulate[ 
         Graphics[{ 
           Black, Rectangle[{0, 0}, {5, 5}], 
           White,[email protected][subID][[i]] 
           }, 
           ImageSize -> {400, 300}], 
      {i,Range[[email protected][subID]]}], 
{subID, {"subA", "subB"}}] 

enter image description here

Với điều kiện là pointSO[subID] thực sự mang lại cho danh sách có độ dài khác nhau, có cách nào để tránh việc 2 Manipulate cho rằng một trong những biến thao tác phụ thuộc mặt khác?

+0

Như vậy, cả hai danh sách đều có cùng độ dài. Có lẽ sử dụng 'listlength [" subA "] = 5; listlength ["subB"] = 9; Chức năng [subID, pointSO [subID] = RandomInteger [{1, 4}, {listlength [subID], 2}]]/@ {"subA", "subB"}; 'minh họa vấn đề phát sinh Thao tác đơn lẻ. – kglr

+0

Giải pháp của tôi hoạt động tốt với các danh sách có độ dài khác nhau. Người thao túng cho tôi điều chỉnh động. Tôi nghĩ rằng các porblem chính có thể là từ không xác định một giá trị mặc định cho i. – Timo

+0

... Bạn cần đặt rõ ràng 'ControlType -> SetterBar'in Thao tác bên trong để tránh các điều khiển khác nhau trong thao tác bên trong cho' subA' và 'subB'. – kglr

Trả lời

5

Tôi không chắc chắn rằng tôi có chính xác những gì bạn đang yêu cầu, nhưng tôi đã tìm những gì bạn muốn là một cái gì đó như sau:

Cho một giao diện người dùng với một biến, nói một mảng có thể thay đổi trong kích thước, và một biến (phụ thuộc) khác, đại diện cho một chỉ mục vào mảng hiện tại mà bạn muốn sử dụng từ giao diện người dùng đến chỉ mục vào mảng. Tuy nhiên, bạn không muốn sửa bố cục biến chỉ mục trong giao diện người dùng, vì nó phụ thuộc vào thời gian chạy, trên kích thước của mảng, có thể thay đổi bằng biến thứ hai.

Dưới đây là một thao tác, trong đó có giao diện người dùng có biến kiểm soát chỉ mục, cập nhật động trên giao diện người dùng khi kích thước của mảng thay đổi.

Tôi đã sử dụng SetterBar cho chỉ mục (biến phụ thuộc) nhưng bạn cũng có thể sử dụng thanh trượt. SetterBar làm cho nó rõ ràng hơn trên giao diện người dùng những gì đang thay đổi.

Khi bạn thay đổi độ dài của mảng, biến điều khiển chỉ mục sẽ tự động cập nhật chỉ mục tối đa cho phép được sử dụng để phù hợp với độ dài hiện tại của mảng.

Khi bạn thu hẹp mảng, chỉ mục cũng sẽ co lại.

Tôi không chắc chắn nếu điều này là những gì bạn muốn, nhưng nếu điều đó, bạn có thể điều chỉnh phương pháp này để phù hợp với vấn đề của bạn

Manipulate[ 

Grid[{ 
    {Style[Row[{"data[[", i, "]]=", data[[i]]}], 12]}, 
    {MatrixForm[data], SpanFromLeft} 
    }, 
    Alignment -> Left, Spacings -> {0, 1} 
    ], 

[email protected][{ 
    {Text["select index into the array = "], 
    SetterBar[Dynamic[i, {i = #} &], Range[1, Length[data]], 
     ImageSize -> Tiny, 
     ContinuousAction -> False] 
    }, 

    { 
    Text["select how long an array to build = "], 
    Manipulator[ 
     Dynamic[n, {n = #; If[i > n, i = n]; 
     data = Table[RandomReal[], {n}]} &], 
     {1, 10, 1}, ImageSize -> Tiny, ContinuousAction -> False] 
    , Text[Length[data]], SpanFromLeft 
    } 
    }, Alignment -> Left 
    ], 

{{n, 2}, None}, 
{{i, 2}, None}, 
{{data, Table[RandomReal[], {2}]}, None}, 
TrackedSymbols -> {n, i} 
] 

enter image description here

enter image description here

cập nhật 8: 30 PM fyi, chỉ cần sửa một mã ở trên để thêm một logic bổ sung cần thiết.

+0

Dunno nếu đây là những gì OP muốn hay không, nhưng nó rất hữu ích cho tôi! : D – telefunkenvf14

+0

@Nasser, Cảm ơn bạn, nhiều, rất hữu ích thủ đoạn! – 500

2

Để tránh sự cố i quá lớn khi chuyển danh sách, bạn có thể thêm câu lệnh If[] vào đầu số Manipulate, ví dụ:

Clear[pointSO]; 
MapThread[(pointSO[#] = RandomInteger[{1, 4}, {#2, 2}]) &, 
    {{"subA", "subB"}, {5, 7}}]; 

Manipulate[ 
If[i > Length[pointSO[subID]], i = Length[pointSO[subID]]]; 
Graphics[{Black, Rectangle[{0, 0}, {5, 5}], White, 
    [email protected][subID][[i]]}, ImageSize -> {400, 300}], 
{{subID, "subA"}, {"subA", "subB"}, SetterBar}, 
{{i, {}}, Range[[email protected][subID]], SetterBar}] 

Có thể đẹp hơn là đặt lại i khi chuyển đổi giữa các danh sách.Điều này có thể được thực hiện bằng cách làm một cái gì đó giống như

Manipulate[ 
Graphics[{Black, Rectangle[{0, 0}, {5, 5}], White, 
    [email protected][subID][[i]]}, ImageSize -> {400, 300}], 
{{subID, "subA"}, 
    SetterBar[Dynamic[subID, (i = {}; subID = #) &], {"subA", "subB"}] &}, 
{{i, {}}, Range[[email protected][subID]], SetterBar} 
] 
+0

Cảm ơn bạn rất nhiều! – 500

2

An thực hiện thay thế mà bảo thiết lập lựa chọn cho mỗi tập dữ liệu:

listlength["subA"] = 5; listlength["subB"] = 9; 
Function[subID, 
pointSO[subID] = 
RandomInteger[{1, 4}, {listlength[subID], 2}]] /@ {"subA", "subB"}; 

Manipulate[ 
Graphics[{Black, Rectangle[{0, 0}, {5, 5}], 
Dynamic[If[subID == "subA", Yellow, Cyan]], PointSize -> .05, 
[email protected]@pointSO[subID][[k]]}, ImageSize -> {400, 300}], 
Row[{Panel[ 
SetterBar[ 
Dynamic[subID, 
(subID = #; k = If[subID == "subA", j, i]) &],{"subA", "subB"}, 
Appearance -> "Button", Background -> GrayLevel[.8]]], "  ", 
PaneSelector[{"subA" -> 
    [email protected][ 
    SetterBar[Dynamic[j, (k = j; j = #) &], 
    Range[[email protected]["subA"]], Appearance -> "Button", 
    Background -> Yellow]], 
"subB" -> 
    [email protected][ 
    SetterBar[Dynamic[i, (k = i; i = #) &], 
    Range[[email protected]["subB"]], Appearance -> "Button", 
    Background -> Cyan]]}, Dynamic[subID]]}]] 

Output ví dụ:

data set subB

data set subA

+0

@MrW cảm ơn bạn; vừa sửa lỗi. – kglr

+0

Downvote vui vẻ đảo ngược! –