How to configure fgoalattain correctly for a multiple functions multiple variables problem?
34 次查看(过去 30 天)
显示 更早的评论
I am trying to design an operational amplifier (OpAmp) and prepared some functions that gives me the [Gain, Phase Margin (PM), Bandwidth (BW)] of an OpAmp given some devices as input. The devices affect the OpAmp parameters (Gain, PM, BW), and the devices are affected by changing 4 variables [Compensation Capacitors/Resistor (Cc/Rc), OpAmp Load Capacitance (C_Load), OpAmp Total Bias Current (Ib)].
Without going into details; I need to setup the following:
Make => [Gain > 71 dB, PM > 45 degrees, BW > 6.24e5], by minimizing (Ib), and choosing any bounded values for Cc/Rc and C_Load.
I am using fgoalattain to solve my problem, but I am not getting any solutions. However, trial and error shows me that if I set [Cc=150e-15, Rc=80e3, C_Load=10e-15, Ib=4.3e-6], I get [Gain = 71.2 dB, PM = 47 degrees, BW = 6.27e5]. This means that a solution exists, but I think I am not configuring my problem correctly. My code is shown below:
%% CMOS Fully-Differential Two-Stage Amplifier Analysis Optimization Module:
% -------------------------------------------------------------------------
% Clear workspace data:
clear;clc;close all;
% Load and prepare PDK devices data (gm/Id curves):
pdk_devices = get_pdk_devices();
%% -----------------------------------------
% Prepare required devices init parameters:
% -----------------------------------------
% Initialize devices structure:
% -----------------------------
devices = struct('M2',{0}, 'M4',{0}, 'M5',{0}, 'M6',{0}, 'M8',{0}, 'M10',{0});
%% --------------------
% Optimization Module:
% --------------------
fun = @(parameters)[get_2s_gain(pdk_devices, devices, parameters); get_2s_pm(pdk_devices, devices, parameters); get_2s_bw(pdk_devices, devices, parameters)];
goal = [71, 45, 6.24e5]; % [Gain >= 71 dB, PM >= 45 degrees, BW >= 6.24e7]
weight = [1 1 1e3];
parameters0 = [20e-15 1e3 200e-15 3e-6]; % [CC Rc C_Load Ib]
lb = [0 0 0 100e-9];
ub = [20e-12 10e6 40e-12 30e-6];
options = optimoptions('fgoalattain');
options.MaxFunctionEvaluations = 60000;
options.MaxIterations = 60000;
options.ConstraintTolerance = 0*1e-15;
options.OptimalityTolerance = 1e-15;
options.StepTolerance = 0*1e-15;
options.FunctionTolerance = 1e-15;
options.FiniteDifferenceStepSize = 1e-15;
options.UseParallel = 1;
[parameters, fval, attainfc, exitflag] = fgoalattain(fun,parameters0,goal,weight,[],[],[],[],lb,ub,[],options);
fprintf('\nCc: %d \nRc: %d \nC_Load: %d\nIb: %d',parameters(1), parameters(2), parameters(3), parameters(4));
fprintf('\n\nGain: %f \nPM: %f \nBW: %d\n',fval(1), fval(2), fval(3));
fprintf('\nAttain_factor: %f\nExit Flag: %d\n',attainfc, exitflag);
My outputs are usually, no matter how large I change the limits:
Solver stopped prematurely.
fgoalattain stopped because it exceeded the function evaluation limit,
options.MaxFunctionEvaluations = 6.000000e+04.
Cc: 2.000000e-14
Rc: 1000
C_Load: 2.000000e-13
Ib: 3.000000e-06
Gain: 71.161912
PM: -7.906930
BW: 1.556654e+05
Attain_factor: 0.161912
Exit Flag: 0
My questions are:
1) How do I program fgoalattain to know that I care about minimizing (Id) only and it can choose any values for (Rc, Cc, & C_Load)?
2) Is there a better way to address this optimization problem?
0 个评论
回答(1 个)
Shishir Reddy
2025-5-28
Hi Nader,
The main limitation with ‘fgoalattain’ is that it attempts to balance multiple objectives by minimizing a weighted sum of goal deviations. As such, it does not strictly enforce constraints but instead tries to get as close as possible to the targets based on the specified weights. This explains why your solution satisfies Gain but violates 'PM' or 'BW', because it is not prioritizing those constraints strictly enough.
A more appropriate approach would be to use ‘fmincon’, which is designed to minimize a single objective function subject to nonlinear constraints. Kindly refer to the following example which would help you to reformulate your problem using ‘fmincon’ to minimize 'Ib', while treating Gain, 'PM', and 'BW' as inequality constraints.
fun = @(parameters) parameters(4);
nonlcon = @(p) deal([], [71 - get_2s_gain(pdk_devices, devices, p);
45 - get_2s_pm(pdk_devices, devices, p);
6.24e5 - get_2s_bw(pdk_devices, devices, p)]);
% Initial guess and variable bounds
parameters0 = [150e-15, 80e3, 10e-15, 4.5e-6]; % [Cc, Rc, C_Load, Ib]
lb = [0, 0, 0, 100e-9];
ub = [20e-12, 10e6, 40e-12, 30e-6];
% Optimization settings
options = optimoptions('fmincon', 'Display', 'iter', 'MaxFunctionEvaluations', 60000, 'MaxIterations', 60000,'UseParallel', true);
% Run optimization
[parameters, fval, exitflag, output] = fmincon(fun, parameters0, [], [], [], [], lb, ub, nonlcon, options);
This configuration directly minimizes Ib, while ensuring that Gain, PM, and BW meet your specified thresholds.
However, if you prefer to continue with ‘fgoalattain’, you can still prioritize ‘Ib’ by adding it as an additional goal and assigning it full weight, as follows
fun = @(p)[get_2s_gain(), get_2s_pm(), get_2s_bw(), p(4)];
goal = [71, 45, 6.24e5, 0]; % Desired specs and Ib → 0
weight = [0, 0, 0, 1]; % Only minimize Ib
For more information regarding ‘fmincon’, kindly refer the following documentation - https://www.mathworks.com/help/optim/ug/fmincon.html
I hope this helps.
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!