«относительные глобальные» переменные в matlab или других языках - PullRequest
4 голосов
/ 18 ноября 2011

Я занимаюсь научной обработкой изображений в MATLAB, которая требует решения странных задач оптимизации со многими параметрами, которые используются функцией «эксперимента», которая имеет много разных «вспомогательных функций», которые используют различные подмножества параметров.Передача этих параметров является трудной задачей, и мне бы хотелось элегантное расширяемое решение.

Мое предпочтительное решение - это «относительная глобальная» переменная - общая для рабочего пространства «основной» функции, а также любые подфункции, которыевызовы основных функций и которые указывают, что они хотят разделить эту переменную.Но относительная глобальная переменная не будет существовать вне функции, которая ее объявляет, и исчезнет, ​​как только вернется основная функция.

Код будет выглядеть следующим образом, за исключением того, что будет много других дополнительных_переменных_переменных, каждый из которых использует параметры вразличные способы:

function y = experiment(p1,p2,p3,...)

% declare relative global variables.
% these will not change value within this experiment function,
% but this experiment will be reused several times in the calling function,
% each time with different parameter values.
relative global p1, p2, p3 ...

% load and process some data based on parameters
...

% call the helper + return
y = experiment_helper(y,z);

end

function y = experiment_helper(y,z)

relative global p1, p3

%% do some stuff with y, z, possibly using p1 and p3, but not changing either of them.
...

end

Я понимаю, что вы можете получить желаемое поведение несколькими другими способами - вы можете передать параметры подфункциям, вызванным в эксперименте, вы можете поместить параметры в параметрструктурировать и передавать их подфункциям и т. д.Первое ужасно, потому что мне приходится менять аргументы всех подфункций каждый раз, когда я хочу изменить использование параметров.Во-вторых, все в порядке, но мне нужно включать префикс структуры каждый раз, когда я хочу использовать переменные.

Полагаю, что «правильное» решение моей проблемы состоит в том, чтобы использовать структуры опций, аналогичные тем, что делает Matlab в своих собственныхкод оптимизации.Мне просто интересно, не существует ли более ловкого способа, при котором я не буду вводить «paramStruct.value» каждый раз, когда я хочу использовать параметр «значение».

Я понимаю, что относительные глобальные переменные могут вызывать всеКошмары отладки, но я не думаю, что они обязательно будут хуже, чем те, которые вызваны существующими глобальными переменными.И они, по крайней мере, имели бы больше локальности, чем неквалифицированные глобалы.

Так как же настоящий программист справится с этой проблемой?Существует ли элегантный, простой в создании и обслуживании дизайн для такого рода проблем?Это можно сделать в Matlab?Если нет, как бы вы сделали это на другом языке?(Я всегда чувствую себя виноватым из-за использования Matlab, так как это не совсем поощряет хороший дизайн. Я всегда хочу переключиться на Python, но не могу оправдать переучивание вещей и перенос базы кода - если только это не сделает меня намного более быстрым и лучшим программистомв течение нескольких недель, и специфичные для Matlab инструменты, такие как вейвлет и наборы инструментов для оптимизации, могут быть быстро + легко найдены или продублированы в Python.)

Ответы [ 2 ]

2 голосов
/ 18 ноября 2011

Нет, я не думаю, что у Matlab есть именно то, что вы ищете.

Лучший ответ зависит от того, связана ли ваша основная задача с количеством набираемых текстов, необходимых для передачи параметров, или с озабоченностью по поводу использования памяти при передаче больших наборов данных. Есть несколько подходов, которые я выбрал, и у всех есть свои плюсы и минусы.

  1. Параметры в структуре. Вы уже упоминали об этом в своем вопросе, но я хотел бы подтвердить это как отличный ответ в большинстве случаев. Вместо того, чтобы вызывать мою структуру параметров paramStruct, я обычно просто называю это p. Он всегда локально ограничен функцией, которую я использую, и тогда мне нужно набрать p.value вместо value. Я считаю, что дополнительные два символа вполне заслуживают возможности легко обойти весь набор параметров.

  2. InputParser. Я часто использую класс InputParser при разработке функций, которые требуют большого количества входных данных. На самом деле это хорошо согласуется с (1) тем, что можно передать структуру параметров или использовать пары «параметр / значение», и yuo может позволить вашей функции определять значения по умолчанию. Очень полезно.

  3. Вложенные функции могут помочь в ограниченных случаях, но только тогда, когда все ваши функции могут быть определены иерархически. Это ограничивает повторное использование кода, если одна из ваших внутренних функций может быть достаточно универсальной для поддержки нескольких родительских функций.

  4. Передача по ссылке с использованием классов дескрипторов. Если тебя беспокоит память. новая форма классы на самом деле позволяют вам определить структуру paraemter, которая передается по ссылке. Код выглядит примерно так:

    classdef paramStructure < handle
        properties (SetAccess = public, GetAccess = public)
            param1 = [];  
            param2 = [];
            % ...
            param100 = [];
        end
    end
    

    Затем вы можете создать новую структуру передачи по ссылке, как эта

    p = paramStructure;
    

    И заданные значения

    p.param1 = randn(100,1);
    

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

  5. global переменные. Я очень стараюсь избегать этого, но это вариант.

1 голос
/ 18 ноября 2011

То, что вы описываете, в точности доступно в MATLAB с использованием вложенных функций.У них есть собственное рабочее пространство, но они также имеют доступ к рабочему пространству родительской функции, в которую они вложены.Таким образом, родительская функция может определять ваши параметры, а вложенные функции смогут видеть их, поскольку они имеют общую область видимости.

Это довольно элегантный способ программирования, который вызывает гораздо меньше проблем с отладкой, чем глобальные.Последние версии MATLAB даже выделяют общие переменные в редакторе голубым, чтобы помочь с этим.

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