Вычислите рабочие точки Используя пользовательские ограничения и целевые функции

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

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

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

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

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

Можно задать пользовательские оптимизационные функции при обрезке модели:

  • В командной строке: Создайте спецификацию рабочей точки с помощью operspec, и задайте пользовательские функции с помощью CustomConstrFcn, CustomCostFcn, и CustomMappingFcn свойства спецификации.

  • Используя Steady State Manager: На вкладке Specification нажмите Trim Options. В Окне параметров Для обрезки, в разделе Custom Optimization Functions, задают имена функций.

  • Используя Model Linearizer: На вкладке Linear Analysis, в Рабочей точке выпадающий список, нажимают Trim Model. В Обрезке диалоговое окно модели, на вкладке Options, в разделе Custom Optimization Functions, задают имена функций.

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

Модель Simulink

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

mdl = 'scdTanks';
open_system(mdl)

Поток между Tank1 и Tank2 желаем. Поток между Tank2 и Tank3 является нежелательной неизбежной утечкой.

В ожидаемом устойчивом состоянии этой системы:

  • Tank1 и Tank2 имеют то же давление.

  • Tank2 и Tank3 имеют почти различие в постоянном давлении 1 это компенсирует загрузку.

Из-за слабой возможности соединения между Tank1 и Tank2, это затрудняет, чтобы обрезать модель, таким образом, что давления в Tank1 и Tank2 равны.

Модель для обрезки без индивидуальных настроек

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

opspec = operspec(mdl);

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

opt = findopOptions('OptimizerType','lsqnonlin');
opt.DisplayReport = 'off';

Обрежьте модель и просмотрите обрезанные давления бака.

[op0,rpt0] = findop(mdl,opspec,opt);
op0.States
ans = 

     <strong>x</strong>  
    <strong>____</strong>

(1.) scdTanks/Inertia
       0
(2.) scdTanks/Tank1
       9
(3.) scdTanks/Tank2
     9.5
(4.) scdTanks/Tank3
    10.5

Обрезанные давления в Tank1 и Tank2 не соответствуют. Таким образом спецификации рабочей точки по умолчанию не удается найти рабочую точку, которая удовлетворяет ожидаемые установившиеся требования. Если вы уменьшаете допуск ограничения, opt.OptimizationOptions.TolCon, вы не можете достигнуть выполнимого установившегося решения из-за утечки между Tank2 и Tank3.

Добавьте пользовательские ограничения

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

  • x - Спецификация рабочей точки утверждает в виде вектора.

  • u - Спецификация рабочей точки вводит в виде вектора.

  • y - Спецификация рабочей точки выходные параметры в виде вектора.

и выходные аргументы:

  • c_ineq - Ограничения неравенства, которые должны удовлетворить c_ineq <= 0 во время обрезки, возвращенной как вектор.

  • c_eq - Ограничения равенства, которые должны удовлетворить c_eq = 0 во время обрезки, возвращенной как вектор.

Каждый элемент c_ineq и c_eq задает одно ограничение. Задайте определенные ограничения для своего приложения как алгебраические комбинации состояний, входных параметров и выходных параметров. Если нет никакого пользовательского равенства или ограничений неравенства, возвратите соответствующий выходной аргумент как [].

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

function [c_ineq,c_eq] =  myConstraints(x,u,y)
    c_ineq = [];
    c_eq = [x(2)-x(3);     % Tank1 pressure - Tank2 pressure
            x(3)-x(4)+1];  % Tank2 pressure - Tank3 pressure + 1
end

Первая запись c_eq ограничивает давления Tank1 и Tank2 быть тем же значением. Второе ограничение равенства задает перепад давления между Tank2 и Tank3.

Добавьте пользовательскую ограничительную функцию в спецификацию рабочей точки.

opspec.CustomConstrFcn = @myConstraints;

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

[op1,rpt1] = findop(mdl,opspec,opt);
op1.States
ans = 

      <strong>x</strong>   
    <strong>______</strong>

(1.) scdTanks/Inertia
         0
(2.) scdTanks/Tank1
    9.3333
(3.) scdTanks/Tank2
    9.3333
(4.) scdTanks/Tank3
    10.333

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

Чтобы исследовать окончательные значения заданных ограничений, можно проверять CustomEqualityConstr и CustomInequalityConstr свойства рабочей точки ищут отчет.

rpt1.CustomEqualityConstr
ans =

   1.0e-06 *

   -0.0001
   -0.1540

Почти нулевые значения указывают, что ограничениям равенства удовлетворяют.

Добавьте пользовательскую целевую функцию

Чтобы задать пользовательскую целевую функцию, задайте функцию с теми же входными параметрами как пользовательская ограничительная функция (xU, и y), и выходной аргумент FF значение целевой функции должно быть минимизировано во время обрезки, возвращенной как скаляр.

Задайте целевую функцию для своего приложения как алгебраическая комбинация состояний, входных параметров и выходных параметров.

В данном примере примите, что вы хотите сохранить давление в Tank3 в области значений [16,20]. Однако это условие не всегда выполнимо. Поэтому, а не наложите трудные ограничения, добавьте целевую функцию, чтобы подвергнуться штрафу, если давления не находятся в эти [16,20] область значений. Для этого задайте следующую пользовательскую целевую функцию.

function F =  myObjective(x,u,y)
    F = max(x(4)-20, 0) + max(16-x(4), 0);
end

Добавьте пользовательскую целевую функцию в объект спецификации рабочей точки.

opspec.CustomObjFcn = @myObjective;

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

[op2,rpt2] = findop(mdl,opspec,opt);
op2.States
ans = 

    <strong>x</strong> 
    <strong>__</strong>

(1.) scdTanks/Inertia
     0
(2.) scdTanks/Tank1
    15
(3.) scdTanks/Tank2
    15
(4.) scdTanks/Tank3
    16

В обрезанной рабочей точке давление в Tank3 в [16,20] диапазон, указанный в пользовательской целевой функции.

Чтобы просмотреть окончательное значение скалярной целевой функции, проверяйте CustomObj свойство рабочей точки ищет отчет.

rpt2.CustomObj
ans =

     0

Добавьте пользовательское отображение

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

Чтобы задать пользовательское отображение, задайте функцию со своей спецификацией рабочей точки, opspec, как входной параметр и выходные аргументы:

  • indx - Индексы сопоставленных состояний

  • indu - Индексы сопоставленных входных параметров

  • indy - Индексы сопоставленных выходных параметров

Чтобы получить состояние, введите, и выведите индексы на основе путей к блоку и утвердите, что имена используют getStateIndex, getInputIndex, и getOutputIndex. Используя эти команды устойчиво к будущим изменениям модели, таков как сложение состояний модели. В качестве альтернативы можно вручную задать индексы. Для получения дополнительной информации о формате indx, indu, и indy, смотрите getStateIndex, getInputIndex, и getOutputIndex.

Если нет никаких состояний, входных параметров, или выходные параметры, используемые пользовательским ограничением и целевыми функциями, возвращают соответствующий выходной аргумент как [].

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

function [indx,indu,indy] = myMapping(opspec)
    indx = [getStateIndex(opspec,'scdTanks/Tank1');
            getStateIndex(opspec,'scdTanks/Tank2');
            getStateIndex(opspec,'scdTanks/Tank3')];
    indu = [];
    indy = [];
end

Добавьте пользовательское отображение со спецификацией рабочей точки.

opspec.CustomMappingFcn = @myMapping;

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

function [c_ineq,c_eq] =  myConstraintsMap(x,u,y)
    c_ineq = [];
    c_eq = [x(1)-x(2);     % Tank1 pressure - Tank2 pressure
            x(2)-x(3)+1];  % Tank2 pressure - Tank3 pressure + 1
end

function F =  myObjectiveMap(x,u,y)
    F = max(x(3)-20, 0) + max(16-x(3), 0);
end

Здесь, xU, и y векторы из сопоставленных состояний, входных параметров и выходных параметров, соответственно. Эти векторы содержат сопоставленные значения, заданные в indx, indu, и indy, соответственно.

Добавьте обновленные пользовательские функции в спецификацию рабочей точки.

opspec.CustomConstrFcn = @myConstraintsMap;
opspec.CustomObjFcn = @myObjectiveMap;

Обрежьте модель с помощью пользовательского отображения и просмотрите обрезанные состояния, которые совпадают с предыдущими результатами в op2.

[op3,rpt3] = findop(mdl,opspec,opt);
op3.States
ans = 

    <strong>x</strong> 
    <strong>__</strong>

(1.) scdTanks/Inertia
     0
(2.) scdTanks/Tank1
    15
(3.) scdTanks/Tank2
    15
(4.) scdTanks/Tank3
    16

Добавьте аналитические градиенты в пользовательские функции

Для более быстрых или более надежных расчетов можно добавить аналитические градиенты в пользовательское ограничение и целевые функции. Добавление градиентов может сократить количество вызовов функции во время оптимизации и потенциально улучшить точность результата оптимизации. Если вы задаете градиенты, необходимо задать их и для пользовательского ограничения и для целевых функций. (Градиенты для пользовательской обрезки не поддерживаются для моделей Simscape™.)

Чтобы задать градиент данного ограничения или целевой функции, возьмите производную функции относительно данного состояния, введите или выведите. Например, если целевая функция

F = (u(1)+3)^2 + y(1)^2

затем градиент F относительно u(1)

G = 2*(u(1)+3)

Чтобы добавить градиенты в вашу пользовательскую ограничительную функцию, задайте следующие дополнительные выходные аргументы:

  • G_ineq - Массив градиента для ограничений неравенства

  • G_eq - Массив градиента для ограничений равенства

Каждый столбец G_ineq и G_eq содержит градиенты для одного ограничения, и порядок столбцов совпадает с порядком строк в соответствующем ограничительном векторе. Количество строк в обоих G_ineq и G_eq равно общему количеству состояний, входных параметров и выходных параметров в xU, и y. Каждый столбец содержит градиенты относительно состояний в x, сопровождаемый входными параметрами в u, затем выходные параметры в y.

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

function [c_ineq,c_eq,G_ineq,G_eq] =  myConstraintsGrad(x,u,y)
    c_ineq = [];
    c_eq = [x(1)-x(2);     % Tank1 pressure - Tank2 pressure
            x(2)-x(3)+1];  % Tank2 pressure - Tank3 pressure + 1
    
    G_ineq = [];
    G_eq = [1  0;
            -1 1;
            0 -1]; 
end

В этой функции, строка i из G_eq содержит градиенты относительно x(i) состояния.

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

function [F,G] = myObjectiveGrad(x,u,y)
    F = max(x(3)-20, 0) + max(16-x(3), 0);
    
    if x(3) >= 20
        G = [0 0 1]';
    elseif x(3) <= 16
        G = [0 0 -1]';
    else
        G = [0 0 0]';
    end
end

Поскольку целевая функция в этом примере кусочна дифференцируемый, значение G зависит от значения давления в Tank3.

Добавьте обновленные пользовательские функции в спецификацию рабочей точки.

opspec.CustomConstrFcn = @myConstraintsGrad;
opspec.CustomObjFcn = @myObjectiveGrad;

Чтобы включить градиенты в алгоритме оптимизации, включите Jacobian опция оптимизации.

opt.OptimizationOptions.Jacobian = 'on';

Чтобы использовать аналитические Якобианы при обрезке моделей с помощью Steady State Manager или Model Linearizer, выберите Enable аналитическая якобиевская опция обрезки.

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

[op4,rpt4] = findop(mdl,opspec,opt);
op4.States
ans = 

    <strong>x</strong> 
    <strong>__</strong>

(1.) scdTanks/Inertia
     0
(2.) scdTanks/Tank1
    15
(3.) scdTanks/Tank2
    15
(4.) scdTanks/Tank3
    16

Результат оптимизации совпадает с результатом для решения для неградиента.

Чтобы видеть, повышают ли градиенты эффективность оптимизации, просмотрите отчеты поиска рабочей точки. Например, сравните вычисления функции номера для решения:

  • Без градиентов:

rpt3.OptimizationOutput.funcCount
ans =

    25

  • С градиентами:

rpt4.OptimizationOutput.funcCount
ans =

     5

В данном примере добавление аналитических градиентов сокращает число вызовов функции во время оптимизации.

Смотрите также

| | | |

Похожие темы