Я не уверен, как инициализировать структуру в 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 нужна реальная структура / запись, чтобы помочь организовать переменные в больших программах.