Логарифмический слайдер в Mathematica

Я делаю небольшой интерфейс для расчета делителей напряжения в Mathematica. У меня есть два ползунка (z1 и z2), которые представляют значения резистора, и пара ползунков, чтобы представить Vin как синусоиду.

Проблема в том, что диапазон доступных значений резисторов (в реальном мире) примерно логарифмический на {r, 100, 1,000,000}. Однако, если я установлю диапазон ползунка на r, будет непрактично выбирать общие низкие значения резисторов в прибл. {100, 10,000}.

Можно ли создать ползунок, который перемещается по логарифмическому диапазону?

Manipulate[
 Grid[{{Plot[(VinRCos[t] + VinC), {t, -3, 9}, 
     PlotRange -> {-1, VMax}, AxesLabel -> {t, Vin}]}, {Plot[
     z2/(z1 + z2)(VinR*Cos[t] + VinC), {t, -3, 9}, 
     PlotRange -> {-1, VMax}, AxesLabel -> {t, Vout}]}}, 
  ItemSize -> 20],
 {{z1, 10000}, 10, 1000000, 10}, {z1}, {{z2, 10000}, 10, 
  1000000}, {z2}, Delimiter, {{VinR, 2.5}, 0, 
  5}, {VinR}, {{VinC, 2}, -VMax, VMax}, {VinC}]
Графика Mathematica


person terrace    schedule 15.03.2011    source источник
comment
Обратите внимание, что ползунком можно более точно управлять, цитируя Slider: получившимся ползунком можно точно манипулировать, удерживая клавишу Alt (или Option на Macintosh) при перетаскивании мышью. Это заставляет ползунок двигаться со скоростью 1/20 скорости мыши. Ползунок можно еще более точно манипулировать, удерживая клавиши Shift и/или Ctrl.   -  person Simon    schedule 15.03.2011
comment
@Simon, этот комментарий достоин включения в ваш ответ, ИМХО.   -  person Mr.Wizard    schedule 15.03.2011
comment
@ Саймон, спасибо, я этого не знал!   -  person terrace    schedule 15.03.2011


Ответы (4)


Простое исправление состоит в том, чтобы просто заставить ползунок манипулировать показателем степени и подключить, например. 10^z1 где вам нужно фактическое значение:

Manipulate[10^z1, {{z1, 5}, 2, 6}] (* 100 to 1M *)

В вашем конкретном случае вы, конечно, также можете ввести список стандартных значений резисторов на выбор:

Manipulate[z1, {z1, {100, 110, 120, 130, 150, 160, 180, 200, 220, 240, 270}}]

ХТХ!

person Michael Pilat    schedule 15.03.2011
comment
+1 Да, сдвиг экспоненты кажется подходящим вариантом. Этот подход обычно полезен для увеличения или уменьшения масштаба на несколько порядков. - person DavidC; 15.03.2011
comment
nvm, разобрался: Item[Dynamic[10^Z1]] - person terrace; 15.03.2011

Ответ Майкла, вероятно, лучший, т.е. просто попросите пользователя указать показатель степени. Альтернативное решение — создать команду типа LogSlider. Вот простой пример:

LogSlider[{v:Dynamic[var_], v0_?Positive}, {min_?Positive, max_?Positive}, 
   base_:10, options___] := DynamicModule[{ev}, Dynamic[
                              var = base^ev; 
                              Slider[Dynamic[ev], Log[base, {min, max}]]]]
LogSlider[v:Dynamic[var_], {min_?Positive, max_?Positive}, 
   base_:10, options___] :=  LogSlider[{v, min}, {min, max}]

Функция имеет только подмножество гибкости Slider и должна быть расширена, если вам нужны пользовательские размеры шага и т. д.

Затем вы изменяете свой Manipulate, указывая переменные, используя {{z1, 10000}, 10, 1000000, LogSlider[##]&} и т.д...

person Simon    schedule 15.03.2011
comment
Спасибо за ваше решение. Но есть проблема. Вот что я обнаружил после тестирования вашего кода: независимо от того, указано ли начальное значение для аргумента Manipulate z1, LogSlider будет получать аргументы в этом формате Dynamic[z1], {min, max}. Таким образом, первая форма LogSlider, указанная выше, не нужна, и v0 никогда не назначается. Чтобы ползунок журнала учитывал начальное значение, нужно добавить ev = Log[base, var]; в DynamicModule непосредственно перед объектом Dynamic. - person ricecakebear; 14.02.2018

Вот мой окончательный результат:

Manipulate[
 Evaluate[Round[10^Z2]/(Round[10^Z1] + Round[10^Z2])*Vin] "V",
 {{Z1, 5}, 2, 6},
 Pane["Z1  = " Dynamic[Round[10^Z1] "[CapitalOmega]"], 
  ImageMargins -> {{2.5, 0}, {3, 0}}],
 {{Z2, 5}, 2, 6},
 Pane["Z2  = " Dynamic[Round[10^Z2] "[CapitalOmega]"], 
  ImageMargins -> {{2.5, 0}, {0, -5}}], {{Vin, 2.5}, 0, VMax}, 
 Pane["Vin  = " Dynamic[Vin "V"], ImageMargins -> {{0, 0}, {0, -5}}]]
введите здесь описание изображения

person terrace    schedule 15.03.2011

Вот начало LogSlider, которое производит стандартное двустороннее поведение, как и другие элементы управления.

LogSlider[Dynamic[x_], max_] := 
 Module[{exp}, 
  Dynamic[exp = Log[max, x]; 
   Slider[Dynamic[exp, (exp = #; x = max^exp) &]]]]

{LogSlider[Dynamic@x, 10^6], Dynamic@x}
person Michael Hale    schedule 31.01.2014