I am trying to run an optimization problem on some equations simultaneously, and need to find a way to accomplish it without using eval. I have a function (layerEq) with parameter N which creates a cell array of N anonymous functions, describing the problem I am optimizing. Each of these equations anonymous equations recieves a vector of length N, and returns a real number.
function [eqCArray] = layerEq(numLayers, Int, T)I = int2str(Int);B = sprintf('%.3f',T);N = numLayers;eqCArray = cell(1, N);for i = N:-1:1 %
% Synthesis of my equations based on N, not relevant to optimization question
%endeqCArray = cellfun(@str2func,eqCArray,'UniformOutput',false); end
In a script, I want to call this function, and make a statement like the following.
exposureEqs = layerEq(numLayers, I, B);E = @(A) [exposureEqs{1}(A), exposureEqs{2}(A), exposureEqs{3}(A), exposureEqs{4}(A)];
When numLayers = 4, this line executes correctly, and I get the desired result. However, instead of hard coding this vector E, I want to make it of length numLayers (AKA: N, as I described it earlier), with all the elements from the cell array exposureEqs.
So far, I have been unable to accomplish this without the use of eval. I tried using the help section in the documentation "Alternatives to the Eval Function", but wasn't able to find anything relevant to my question. Currently, my script looks as such:
I = 33.6; B = 0.75; numLayers = 4; exposureMax = 3025; exposureMin = 2975;%Starter Vector
t0 = linspace(2, 10, numLayers);%Create equations using layerEq
exposureEqs = layerEq(numLayers, I, B);%Setup for automatic data separation
arrayStr = '';elementStr = '';v = ones(1, numLayers);%Automatic Data Separation Loop: executes as if I have hardcoded the values
%into anonymous functions myself, but for the appropriate number of layers.
for i = 1:numLayers dataStr = ['e' int2str(i) ' = @(A) exposureEqs{' int2str(i) '}(A)']; elementStr = [elementStr 'e' int2str(i) '(A) ']; eval(dataStr); %Executes each line of code assigning a function
endeval(['E = @(A) [' elementStr '];'])% E = @(A) [exposureEqs{1}(A), exposureEqs{2}(A), exposureEqs{3}(A), exposureEqs{4}(A)]; %LINE RUNS
%Standard Deviation function to be minimized in the optimizer
stdDev = @(A) std(E(A));%Writing out bounds
lb = zeros(size(t0));ub = inf(size(t0));%Calculating and storing nonlinear constraints
nonlcon = @(A) avgCon(E, A, exposureMin, exposureMax);%Optimizer Function
x = fmincon(stdDev, t0, [], [], [], [], lb, ub, nonlcon);%Values by Layer
y = E(x);z = stdDev(x);disp(x)disp(y)disp(['Standard Deviation: ' sprintf(sprintf('%.3f', z))])function [c, ceq] = avgCon(E, A, exposureMin, exposureMax) c(1) = mean(E(A)) - exposureMax; c(2) = -1 * mean(E(A)) + exposureMin; ceq = [];end
To make things more clear, I am trying to minimize the standard deviation of my equations by optimizing the vector of variables they recieve. I also have a non-linear constraint to make sure the mean of my equations is between the two variables exposureMin and exposureMax.
In summary: how can I create that anonymous function E correctly, based on the value of numLayers, without using the eval command?
Best Answer