MATLAB Class Efficiency - PullRequest
       106

MATLAB Class Efficiency

0 голосов
/ 28 сентября 2018

Я пытаюсь сделать это коротким.У меня возникла проблема, связанная с численным моделированием потока в газовой трубе.Я моделирую, используя разные модели для воздушного потока (транспортные уравнения), проходящего от одной границы к другой (то есть справа налево).Вопрос в том, что, поскольку я использую разные модели для представления упомянутого потока газа и граничных условий, я получил много функций, таких как:

boundary_left_model_1
boundary_right_model_1
boundary_left_model_2
boundary_right_model_2
boundary_left_model_2b
boundary_right_model_2b
....
flux_model_1
flux_model_2
....
source_model_1
source_model_2
.....

Я выделяю необходимую функцию перед числовой схемой через (например):

boundary_left = @[needed function];
boundary_right=@ [needed function];
flux = @[needed function];
source=@ [needed function];

То, что следует, выглядит примерно так:

Solution = numerical_scheme_#1(boundary_left,boundary_right,flux,source,parameters);

Вы получаете точку.

Теперь, каков наиболее эффективный (при структурировании) способ создания программы?Насколько я могу судить, у меня есть три варианта:

1) Я определяю каждую функцию в файле функций Matlab (будет много файлов)

2) Я определяю каждую функцию вскрипт для числовой схемы (приведет к длинному файлу, который менее понятен для настройки / чтения)

3) Я создаю класс для граничных условий с методами, содержащими все модели, один класс для потоков и источниковсодержащие соответствующие функции.В своем распределении функций для числовой схемы я затем называю нужные мне методы.(кажется сложным и неэффективным, не уверен в том, сколько времени потребуется для вызова методов в matlab, но для меня это наиболее структурированный способ)Я также спрашиваю о том, как вообще решается такая проблема.Заранее спасибо!Также в качестве бонуса: если кто-то увлекается практическим моделированием PDE-систем с помощью Matlab - у меня возникают вопросы типа «Как мне выбрать числовую схему - какие критерии мне следует учитывать?»

Еще раз спасибо, желаю всем приятного дня!

1 Ответ

0 голосов
/ 28 сентября 2018

Предполагая, что методы, связанные с моделью 1, всегда используются вместе, а не смешиваются с методами для модели 2 или 3, вы можете настроить код со всеми функциями для одной модели в одном файле:

% MODEL1   Methods that implement model 1
function [boundary_left,boundary_right,flux,source] = model1
boundary_left = @boundary_left_method;
boundary_right = @boundary_right_method;
flux = @flux_method;
source = @source_method;

function [out, args] = boundary_left_method(input, args)
  % [implementation]
end

function [out, args] = boundary_right_method(input, args)
  % [implementation]
end

function [out, args] = flux_method(input, args)
  % [implementation]
end

function [out, args] = source_method(input, args)
  % [implementation]
end

end

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

Теперь вы можете делать:

[boundary_left,boundary_right,flux,source] = model1;
Solution = numerical_scheme_1(boundary_left,boundary_right,flux,source,parameters);

Это решение довольно похоже на решение пользовательского класса, предложенное OP, но несколько проще.Я не думаю, что будет большая разница в производительности, но единственный способ узнать наверняка - это реализовать и синхронизировать различные варианты.Что наиболее эффективно со временем меняется, так как улучшается JIT MATLAB.

Обратите внимание, что предложенная здесь схема также позволяет включать данные (parameters) в следующие функции:

% MODEL1   Methods that implement model 1
function [boundary_left,boundary_right,flux,source] = model1(parameters)
boundary_left = @boundary_left_method;
boundary_right = @boundary_right_method;
flux = @flux_method;
source = @source_method;

function [out, args] = boundary_left_method(input, args)
  out = input * parameters; % You can use PARAMETERS here, note that it is not
                            % an input argument to this nested function, it is
                            % found in the parent scope.
end

% ...

end % This end here is important now, this way `boundary_left_method` is an
    % nested function, not simply a separate function within the same file.

Теперьвозвращаемый дескриптор функции boundary_left содержит данные parameters.См. соответствующую документацию .


Если вы также управляете кодом функций числовой схемы, которые используют эти функции, вы можете написать method1 et al.вместо этого возвращать массив ячеек, а numerical_scheme_1 и др.функции, чтобы взять массив ячеекЗатем вы можете просто сделать:

numerical_scheme_1(method1,parameters);
numerical_scheme_1(method2,parameters);
numerical_scheme_1(method3,parameters);
numerical_scheme_2(method1,parameters);
numerical_scheme_2(method2,parameters);
numerical_scheme_2(method3,parameters);
% etc.

Затем вы можете использовать цикл для прохождения всех комбинаций:

schemes = {@numerical_scheme_1, @numerical_scheme_2, ... };
methods = {method1, method2, method3, ... };
for ii=1:numel(schemes)
   for jj=1:numel(methods)
      schemes{ii}(methods{jj},parameters);
   end
end

[Отказ от ответственности: этот код не проверен, но я не вижупочему это не сработает ...]

...