Использование структуры внутри Manipulate для управления управляющими переменными, как инициализировать - PullRequest
5 голосов
/ 20 ноября 2011

Я не уверен, как инициализировать структуру в Mathematica для использования с Manipulate, чтобы помочь мне лучше организовать многие управляющие переменные, которые у меня есть.

Я приведу несколько примеров, которые помогут показать проблему.

Вот самый основной манипуляция:

метод 1

Clear["Global`*"]
Manipulate[process[a, b],

 {{a, 1, "a"}, -10, 10, 1},
 {{b, 2, "b"}, -10, 10, 1},

 Initialization :> 
  {
   process[a_, b_] := Module[{}, Row[{"a=", a, " b=", b}]]
   }
 ]

В демо, которое я пишу, у меня есть еще много элементов управления. Некоторые функции (например, функция под названием process [] в приведенном выше примере) должны вызываться с 15 и более аргументами, что затрудняет их поддержку. (У меня нет выбора по этому поводу, я не могу это выделить).

Итак, я пытаюсь использовать структуру для сбора этих переменных. Смежный вопрос:

Безопасная настройка структуры в Mathematica

Итак, затем я попробовал это ниже: (Я знаю, что выбор структуры в Mathematica не самый лучший, но я сначала хотел посмотреть, будет ли он работать)

метод 2

Clear["Global`*"]
Manipulate[process[myData],

 {{myData["a"], 1, "a"}, -10, 10, 1},
 {{myData["b"], 1, "b"}, -10, 10, 1},

 Initialization :> 
  {
   process[myData_] := 
    Module[{}, Row[{"a=", myData["a"], " b=", myData["b"]}]]
   }
 ]

Но вышеописанное не работает. Я получаю

Manipulate::vsform does not have the correct form for a variable specification

Итак, я подумал, хорошо, позвольте мне самому заполнить структуру перед вызовом функции process [], поэтому я сделал это:

метод 3

Clear["Global`*"]
Manipulate[
 (
  myData["a"] = a;
  myData["b"] = b;

  process[myData]
  ),

 {{a, 1, "a"}, -10, 10, 1},
 {{b, 1, "b"}, -10, 10, 1},

 Initialization :> 
  {
   process[myData_] := 
    Module[{}, Row[{"a=", myData["a"], " b=", myData["b"]}]]
   }
 ]

И это работает. Хорошо, но теперь, поскольку я на самом деле использую макро-метод Leonid для настройки своих элементов управления, объяснил здесь

Как определить часть определения управляющей переменной Manipulate для уменьшения дублирования кода

Теперь я попробовал метод (2) выше, используя метод макросов, и теперь он работает! но проблема остается в том, как инициализировать поля struct. Вот метод (2) выше, с использованием макроса

метод (2) с использованием макроэкономического метода Леонида для настройки элементов управления

Clear["Global`*"]
Manipulate[process[myData],

 (*-- define 2 control variables, using the macro method --*)
 Evaluate@With[{s1 = Function[{struct},
      Grid[{
        {Manipulator[Dynamic[struct["a"]], {-20, 20, 0.1}]},
        {Manipulator[Dynamic[struct["b"]], {-2, 2, .5}]}
        }],
      HoldAll]
    },
   s1[myData]
   ],

 Initialization :> 
  {
   process[struct_] := Module[{},
     Text[Grid[{
        {"a=", struct["a"]},
        {" b=", struct["b"]}
        }]]
     ]
   }
 ]

Выше работает, но myData не инициализируется. И это вопрос, который у меня есть. Мне нужно инициализировать его так, чтобы начальное отображение на экране имело правильные значения.

Я могу использовать раздел «Инициализация» для этого, но теперь myData станет глобальным, и это может вызвать проблему, когда я сделаю снимки Манипуляции позже, так как глобальные данные будут распределены между снимками:

метод (2) выше, инициализированный с использованием глобальной секции

Clear["Global`*"]
Manipulate[process[myData],

 (*-- define 2 control variables, using the macro method --*)
 Evaluate@With[{s1 = Function[{struct},
      Grid[{
        {Manipulator[Dynamic[struct["a"]], {-20, 20, 0.1}]},
        {Manipulator[Dynamic[struct["b"]], {-2, 2, .5}]}
        }],
      HoldAll]
    },
   s1[myData]
   ],

 Initialization :> 
  {

   myData["a"] = 1;   (* now OK, but mydata is global *)
   myData["b"] = 1;

   process[struct_] := Module[{},
     Text[Grid[{
        {"a=", struct["a"]},
        {" b=", struct["b"]}
        }]]
     ]
   }
 ]

Когда я пытаюсь инициализировать myData внутри Манипулятора, он не работает, может быть, есть хитрость, чтобы сделать это?

метод (2) выше, попробуйте инициализировать внутри Манипуляции с помощью элемента управления Нет

Clear["Global`*"]
Manipulate[process[myData],

 (*-- define 2 control variables, using the macro method --*)
 Evaluate@With[{s1 = Function[{struct},
      Grid[{
        {Manipulator[Dynamic[struct["a"]], {-20, 20, 0.1}]},
        {Manipulator[Dynamic[struct["b"]], {-2, 2, .5}]}
        }],
      HoldAll]
    },
   s1[myData]
   ],

 {{myData["a"], 1}, None}, (*invalid syntax*)
 {{myData["b"], 1}, None},

 Initialization :> 
  {
   process[struct_] := Module[{},
     Text[Grid[{
        {"a=", struct["a"]},
        {" b=", struct["b"]}
        }]]
     ]
   }
 ]

Итак, мой вопрос: как я могу инициализировать myData в методе (2) выше, но не делая его глобальным?

Я просто хотел добавить, что это для демонстрации, поэтому правило состоит в том, что он должен начинаться с Manipulate [..]. Нет модуля снаружи. Все должно быть внутри Манипулировать [...]

спасибо

обновление:

Я остановился на схеме в (3) выше, где сам заполняю структуру в начале.

Кажется, что это работает хорошо, и теперь стало проще вызывать многие функции, которые у меня есть, поскольку число аргументов значительно уменьшилось (у меня были функции, вызываемые с 20 аргументами!, Теперь оно уменьшено до 5 аргументов, поскольку Я «упаковал» связанные переменные управления в одну структуру, теперь с ней легче работать). Не идеальное решение, но, по крайней мере, оно помогло мне облегчить работу с кодом.

Вот так выглядит «шаблон»:

Manipulate[
 Module[{myData},

  (*fill in the struct *)
  myData["a"] = a;
  myData["b"] = b;
  myData["c"] = c;

  process[myData]
  ],
 (*-- define  control macro  --*)
 Evaluate@With[{s1 = Function[{var},
      Manipulator[Dynamic[var], {-20, 20, 0.1}], HoldAll]
    },
   Column[{s1[a], s1[b], s1[c]}]
   ],

 (*initialize fields of the struct, or the control variables*)
 {{a, 1}, None}, 
 {{b, 2}, None},
 {{c, 3}, None},

 Initialization :> 
  {
   process[myData_] := Module[{},
     Text[Grid[{
        {"a=", myData["a"]},
        {" b=", myData["b"]},
        {" c=", myData["c"]}
        }]]
     ]
   }
 ]

Я думаю, что Mathematica нужна реальная структура / запись, чтобы помочь организовать переменные в больших программах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...