I am looking optimisation method in Matlab, where I can apply constraints on a parameter which is a function of another constrained parameter.
The error function to minimise is:
errfun = Ltrue - Lref(x1,x2) - Lemm(x1,x2,x3)
The optimisation parameters are x1,x2,x3 with their respective lower and upper bounds. Ltrue, Lref, Lemm are vectors of size 8. Ltrue is the vector containging the constant "true" values which are already defined. I am currently using the Matlab function "lsqnonlin".
However, the problem is that I also require a constraint on the value of Lemm(8).
In excel solver, this is easy to do since I can just add a specific constraint to the cell containing Lemm(8). I can't find any equivalent in any of the Matlab optimsation functions though. Is there any function I am not aware of which can do this, or some workaround to make use of existing Matlab functions?
Related
I have a matrix (type:double) of size 106 x 103. The matrix represents European gridded temperature data for one timestep (a day).
For every day, I want to calculate the degree days (thermal time) for a species, based on the temperature recorded for each 'cell' (i,j element) in the matrix using a formula that I have coded in Matlab based on a sinewave approach.
So, ultimately, what I want to do is being able to apply a calculation to my matrix, that will provide individual output for each grid cell (i,j element) dependent on the temperature data that is recorded there.
I could do this with a loop, but I have to accumulate these degree days for multiple years, so I would prefer to find a way of applying the calculation to each element in a daily matrix simultaneously (and then looping through the days (matrices)).
From what I have read, you can use a cellfun if your matrix is a cell array (mine is not).
Then I was also looking at the bsxfun option, but it seems like the functions are just standard functions..like mean, max etc.
So now, I'm looking at using arrayfun in conjunction with a function I create from my algorithm to calculate degree days.
I have been trying to write a test function but Matlab keeps throwing up the same error:
I type:
function output=degreedays(x)
and Matlab throws back:
Error: Function definitions are not permitted in this context.
Can someone tell me what I'm doing wrong? Why is it not accepting the declaration of the function name?
MATLAB does not allow you to define named functions like this at the command line. You need to place your function definition in a file. MATLAB then can call that function by the name of the file - so in your case, put your function definition in a file called degreedays.m.
See the doc for more: https://uk.mathworks.com/help/matlab/matlab_prog/create-functions-in-files.html .
This question may initially appear similar to this other question but my situation is a little bit different.
I have a function 'deriv' that takes a symbolic expression as its input, then takes the first derivative of that symbolic expression. That derivative is then converted into an anonymous function using matlabFunction(), and is then evaluated over an array of points. I also use the anonymous function later in some other code.
The problem I'm having is that sometimes the input symbolic expression happens to be linear, and thus the derivative is constant; therefore the anonymous function is also a constant. When I evaluate the anonymous function over the array of points, I only get one output instead of an array of outputs.
Here's some code showing what I'm doing. For the sake of simplicity here, let's assume that the symbolic input expressions will involve only one symbolic variable called q.
function[derivFun,derivVals] = deriv(input)
derivSym = diff(input,q);
derivFun = matlabFunction(derivSym,'vars',q);
evalPoints = [1;2;3;4;5]; %in my true application, a much larger array
derivVals = derivFun(evalPoints);
end
So if the input is q^2, then the output derivVals will be [2;4;6;8;10]. But if the input happens to be, say, 3*q, then derivVals will be 3 (just a single scalar). What I'd like is for derivVals to be [3;3;3;3;3].
That is, I'd like derivVals to be the same size as evalPoints even if the input function happens to be linear (or constant). And I don't know ahead of time what the input expression will be.
Can anyone give suggestions for a scheme that would do that? I understand that a constant anonymous function will just return a single constant scalar, regardless of the size of its input. What I'm hoping for is perhaps some way to recognize when the anonymous function is constant and then still cause derivVals to be the same size as evalPoints.
I know that I could use a for loop to evaluate derivFun for every row of evalPoints, but I'd like to avoid using such a loop if possible.
Thank you for your time and consideration.
I think that this is a slightly simpler solution. The issue is that you're using matlabFunction, which simplifies down the equations and doesn't allow much customization. However, you can create an anonymous function of an anonymous function. Just add the this line right after your matlabFunction line:
derivFun = #(evalPoints)derivFun(evalPoints)+zeros(size(evalPoints));
This only evaluates the original derivFun once. However, I do like you symvar solution (just remember that adding zeros is always better than multiplying ones).
Not 100% sure I got the problem correctly.
Would this solve your issue?:
if isscalar(derivVals)
derivVals = repmat(derivVals, size(evalPoints));
end
I have the following problem: When using fmincon I need to supply it with constraints. The constrain .M file looks like this:
function [c,ceq]=podmienky_L(qL)
global podmL zL
c=[podmL+0.0001-zL]
ceq=[];
zL is a constant while podmL is a symbolic variable that contains this expression:
(22.1*cos(qL(4))(sin(qL(3))(0.35*sin(qL(1))
When I try to run fmincon I get an error: User function returned a complex value when evaluated;
But when I replace the variable podmL with (22.1*cos(qL(4))(sin(qL(3))(0.35*sin(qL(1)) everything works fine.
The equation in podmL is supplied by another script and can wary from use to use and can attain hideous proportions, so it is very impractical for me to simply hardwrite it into the constraints function. Does anybody have any ideas?
Thanks
I'm trying to parameterize one of my Simulink models, so that I will have a gain in the model whose value is equal to an element of a MATLAB workspace vector indexed by the model parameter. That is, I want to define a model argument WheelIndex and have a gain inside the model with a value AxelLoads(WheelIndex).
When I do it exactly as I've described above, I get "vector indices must be real and positive integers" error. When I change the model argument to AxelLoad(To be used directly in the gain component) and assign its value to be AxelLoads(1)(for the first wheel) I get:
Error in 'Overview/Wheel1'. Parameter '18000.0, 15000.0, 17000.0,
21000.0' setting: "18000.0, 15000.0, 17000.0, 21000.0" cannot be evaluated.
I've also tried importing the vector as a constant block into the model, and use a selector block parameterized by the WheelIndex argument to direct the right element to a multiplication block (thereby making an ugly gain block), but then Simulink complains that I'm trying to use a model argument to define an "un-tunable value".
I just want to somehow define the parameters in the MATLAB workspace to be used in each model instance, so that I can, say, calculate the total weight by adding the loads on each wheel. Simulink seems to block all workarounds I've been trying.
Thanks
Could you use a lookup table to obtain AxelLoads vs. WheelIndex?
The easiest way is if I just came over? :P
Perhaps this explaination of tunable parameters helps a little?
I'm having a problem sending a value from a GUI to an Embedded MATLAB Function (EMF) in a Simulink model. I get this value from a slider in my GUI and send it to an EMF block in my model. I can confirm that the value is being transferred correctly from my GUI to my Simulink block, since I can display the value with a display block in my model and see the value change when I change the slider position in my GUI. However I keep getting this error when I run my model:
Could not determine the size of this expression.
Function 'Kastl' (#18.282.283), line 14, column 1:
"f"
This is part of my EMF block code:
function y = input_par(u,fstart)
...
f_end = 1000;
f = fstart:f_end;
...
I believe MikeT is correct: you can't redefine the size of a variable in an embedded function. If you look at this Embedded MATLAB Function documentation page under the subsection Defining Local Variables, it says:
Once you define a variable, you cannot
redefine it to any other type or size
in the function body.
You will have to rework your embedded function such that the variables you declare are not changing size. Since I don't know what you are subsequently doing with the variable f, there's not much more specific help I can give you.
In general, if you absolutely need to use data that changes size, one solution is to pad the data with "garbage" values in order to maintain a constant size. For example:
MAX_ELEMS = 1000; % Define the maximum number of elements in the vector
f = [fstart:MAX_ELEMS nan(1,fstart-1)]; % Create vector and pad with NaNs
In the above example, the variable f will always have 1000 elements (assuming the value of fstart is an integer value less than or equal to 1000). The value NaN is used to pad the vector to the appropriate constant size. Any subsequent code would have to be able to recognize that a value of NaN should be ignored. Depending on what calculations are subsequently done in the embedded function, different pad values might be needed in place of NaN (such as 0, negative values, etc.).
I believe the issue you are running into is that you can't change a parameter during simulation that will cause the dimension of a signal to change. In your example, the code,
f = fstart:f_end;
changes size whenever fstart changes. I think this is what EMF block is complaining about. I don't have any easy workaround for this particular issue, but maybe there's an equivalent way of doing what you want that avoids this issue.