how to create a changing variable for fsolve - matlab

i want fsolve to calculate the output for different uc each time (increasing uc by 0.001 each time). each output from fsolve should be sent to a simulink model seperatly. so i set a loop to do so, but i believe that at the currenty constellation (if it will work)will just calculate 1000 different values? is there a way to send out the values seperately?
if not, how can i create a parameter uc. that goes from 0 to say 1000? i tried uc=0:0.001:1000, but again, the demension doen't seem to fit.
how do i create a function that takes the next element of a vector/matrix each time the function is called?
best regards

The general approach to iterating over an array of values and feeding them one-by-one into a series of evaluations of a function follows this form:
for ix = 0:0.1:10
func(arg1, arg2, ix)
end
See how each call to func includes the current value of ix ? On the first iteration ix==0, on the next ix==0.1 and so forth. You should be able to adapt this to your needs; in your code the loop index (which you call i) is not used inside the loop.
Now some un-asked-for criticism of your code. The lines
x0=[1,1,1];
y=x0(1);
u=x0(2);
yc=x0(3);
options=optimset('Display','off');
do not change as the loop iterations advance; they always return the same values whatever the value of the loop iterator (i in your code) may be. It is pointless including them inside the loop.
Leaving them inside the loop may even be a waste of a lot of time if Matlab decides to calculate them at every iteration. I'm not sure what Matlab does in this case, it may be smart enough to figure out that these values don't change at each iteration, but even if it does it is bad programming practice to write your code this way; lift constant expressions such as these out of loops.
It's not clear from the fragment you've posted why you have defined y, u and yc at all, they're not used anywhere; perhaps they're used in other parts of your program.

Related

Clean methodology for running a function for a large set of input parameters (in Matlab)

I have a differential equation that's a function of around 30 constants. The differential equation is a system of (N^2+1) equations (where N is typically 4). Solving this system produces N^2+1 functions.
Often I want to see how the solution of the differential equation functionally depends on constants. For example, I might want to plot the maximum value of one of the output functions and see how that maximum changes for each solution of the differential equation as I linearly increase one of the input constants.
Is there a particularly clean method of doing this?
Right now I turn my differential-equation-solving script into a large function that returns an array of output functions. (Some of the inputs are vectors & matrices). For example:
for i = 1:N
[OutputArray1(i, :), OutputArray2(i, :), OutputArray3(i, :), OutputArray4(i, :), OutputArray5(i, :)] = DE_Simulation(Parameter1Array(i));
end
Here I loop through the function. The function solves a differential equation, and then returns the set of solution functions for that input parameter, and then each is appended as a row to a matrix.
There are a few issues I have with my method:
If I want to see the solution to the differential equation for a different parameter, I have to redefine the function so that it is an input of one of the thirty other parameters. For the sake of code readability, I cannot see myself explicitly writing all of the input parameters as individual inputs. (Although I've read that structures might be helpful here, but I'm not sure how that would be implemented.)
I typically get lost in parameter space and often have to update the same parameter across multiple scripts. I have a script that runs the differential-equation-solving function, and I have a second script that plots the set of simulated data. (And I will save the local variables to a file so that I can load them explicitly for plotting, but I often get lost figuring out which file is associated with what set of parameters). The remaining parameters that are not in the input of the function are inside the function itself. I've tried making the parameters global, but doing so drastically slows down the speed of my code. Additionally, some of the inputs are arrays I would like to plot and see before running the solver. (Some of the inputs are time-dependent boundary conditions, and I often want to see what they look like first.)
I'm trying to figure out a good method for me to keep track of everything. I'm trying to come up with a smart method of saving generated figures with a file tag that displays all the parameters associated with that figure. I can save such a file as a notepad file with a generic tagging-number that's listed in the title of the figure, but I feel like this is an awkward system. It's particularly awkward because it's not easy to see what's different about a long list of 30+ parameters.
Overall, I feel as though what I'm doing is fairly simple, yet I feel as though I don't have a good coding methodology and consequently end up wasting a lot of time saving almost-identical functions and scripts to solve fairly simple tasks.
It seems like what you really want here is something that deals with N-D arrays instead of splitting up the outputs.
If all of the OutputArray_ variables have the same number of rows, then the line
for i = 1:N
[OutputArray1(i, :), OutputArray2(i, :), OutputArray3(i, :), OutputArray4(i, :), OutputArray5(i, :)] = DE_Simulation(Parameter1Array(i));
end
seems to suggest that what you really want your function to return is an M x K array (where in this case, K = 5), and you want to pack that output into an M x K x N array. That is, it seems like you'd want to refactor your DE_Simulation to give you something like
for i = 1:N
OutputArray(:,:,i) = DE_Simulation(Parameter1Array(i));
end
If they aren't the same size, then a struct or a table is probably the best way to go, as you could assign to one element of the struct array per loop iteration or one row of the table per loop iteration (the table approach would assume that the size of the variables doesn't change from iteration to iteration).
If, for some reason, you really need to have these as separate outputs (and perhaps later as separate inputs), then what you probably want is a cell array. In that case you'd be able to deal with the variable number of inputs doing something like
for i = 1:N
[OutputArray{i, 1:K}] = DE_Simulation(Parameter1Array(i));
end
I hesitate to even write that, though, because this almost certainly seems like the wrong data structure for what you're trying to do.

display variable value each n iterations with condition outside the loop

When I have to display the variable value every n iterations of a for loop I always do something along these lines:
for ii=1:1000
if mod(ii,100)==0
display(num2str(ii))
end
end
I was wondering if there is a way to move the if condition outside the loop in order to speed up the code. Or also if there is something different I could do.
You can use nested loops:
N = 1000;
n = 100;
for ii = n:n:N
for k = ii-n+1:ii-1
thingsToDo(k);
end
disp(ii)
thingsToDo(ii);
end
where thingsToDo() get the relevant counter (if needed). This a little more messy, but can save a lot of if testing.
Unless the number of tested values is much larger than the number of printed values, I would not blame the if-statement. It may not seem this way at first, but printing is indeed a fairly complex task. A variable needs to be converted and sent to an output stream which is then printing in the terminal. In case you need to speed the code up, then reduce the amount of printed data.
Normally Matlab function takes vector inputs as well. This is the case for disp and display and does only take a single function call. Further, conversion to string is unnecessary before printing. Matlab should send the data to some kind of stream anyway (which may indeed take argument of type char but this is not the same char as Matlab uses), so this is probably just a waste of time. In addition to that num2str do a lot of things to ensure typesafe conversion. You already know that display is typesafe, so all these checks are redundant.
Try this instead,
q = (1:1000)'; % assuming q is some real data in your case
disp(q(mod(q,100)==0)) % this requires a single call to disp

how to 'zero' all variables at each loop iteration

I have written a script describing a dynamic biological process in matlab; the input to which is a year of daily temperature values.The model runs for a year on this daily timestep carrying out different calculations required for the process.
I have thirty years of temperature data (matrix of size 365*30) and I intend to write a 'for loop' at the start of the script in order to use each year of daily data consecutively. I have about 5 variables that are the output from the script, which I intend to output to a txt/csv file at each iteration. My problem is that there are approximately 80 variables within the model and I would like to zero them all at each iteration of the outermost loop (the temperature input). I would like to do this in an efficient manner rather than having to individually zero all the variables. Does anyone know how to do this?
I have been looking at using the 'who' function to list all the variables and I'm thinking that it could be used somehow to zero everything. I have tried letting x = who; which seems to produce a list of all the variables in inverted commas. But obviously; trying to let x = 0 after that just redefines x. I was also thinking of just using 'clear all' but I think this would really slow the model down as it would be 'starting from scratch' redefining all the variable at each loop?
Any help would be appreciated.
First of all, if you have 80 variables you are probably doing something strange. Consider to combine them into vectors or arrays for example.
That being said, there are two situations I can think about:
You already initialize all your variables somewhere
In this case the solution is simple: move the initialization to the start of your outer loop.
You don't initialize anything (bad practice, especially if you are concerned about performance)
In this case you should put a function inside your loop, that only returns your output variables and not all these loose intermediate variables.
Perhaps a combination of these two methods can also apply, but really I would recommend not to use 80 different variables! And initialize any variable that you need to use.
A compact syntax to initialize scalars would be:
[a, b,c] = deal(0);

matlab local static variable

In order to test an algorithm in different scenarios, in need to iteratively call a matlab function alg.m.
The bottleneck in alg.m is something like:
load large5Dmatrix.mat
small2Dmatrix=large5Dmatrix(:,:,i,j,k) % i,j and k change at every call of alg.m
clear large5Dmatrix
In order to speed up my tests, i would like to have large5Dmatrix loaded only at the first call of alg.m, and valid for future calls, possibly only within the scope of alg.m
Is there a way to acheve this in matlab other then setting large5Dmatrix as global?
Can you think of a better way to work with this large matrix of constant values within alg.m?
You can use persistent for static local variables:
function myfun(myargs)
persistent large5Dmatrix
if isempty(large5Dmatrix)
load large5Dmatrix.mat;
end
small2Dmatrix=large5Dmatrix(:,:,i,j,k) % i,j and k change at every call of alg.m
% ...
end
but since you're not changing large5Dmatrix, #High Performance Mark answer is better suited and has no computational implications. Unless you really, really don't want large5Dmatrix in the scope of the caller.
When you pass an array as an argument to a Matlab function the array is only copied if the function updates it, if the function only reads the array then no copy is made. So any performance penalty the function pays, in time and space, should only kick in if the function updates the large array.
I've never tested this with a recursive function but I don't immediately see why it should start copying the large array if it is only read from.
So your strategy would be to load the array outside the function, then pass it into the function as an argument.
This note may clarify.

Slow anonymous function

Suppose you have a loop with 50000 iterations and want to calculate mean values (scalars) from alot of matrices. This is not complete, but roughly like this:
for k=1:50000
...
mean=sum(sum(matrix))/numel(matrix); %Arithmetic mean
...
end
And now want to include different mean equations to choose from. First I tried this:
average='arithmetic'
for k=1:50000
...
switch average
case 'arithmetic'
mean=sum(sum(matrix))/numel(matrix); %Arithmetic mean
case 'geometric'
mean=prod(prod(matrix)).^(1/numel(matrix)); %Geometric mean
case 'harmonic'
mean=numel(matrix)/sum(sum(1./matrix)); %Harmonic mean
end
...
end
This is obviously alot slower than the first loop because it needs to find the matching string for every iteration which feels really unnecessary. Then I tried this:
average='arithmetic'
switch average
case 'arithmetic'
eq=#(arg)sum(sum(arg))/numel(arg); %Arithmetic mean
case 'geometric'
eq=#(arg)prod(prod(arg)).^(1/numel(arg)); %Geometric mean
case 'harmonic'
eq=#(arg)numel(arg)/sum(sum(1./arg)); %Harmonic mean
end
for k=1:50000
...
mean=eq(matrix); %Call mean equation
...
end
This is still about twice as slow as the first loop and I don't get why. The two last loops are almost similar in speed.
Am I doing something wrong here? How can I achieve the same performance as the first loop with this extra feature?
Help is very much appreciated!
Having the switch inside the loop is performing a comparison 50000 times which only needs to be performed once, something I'd advise against.
The second is a little more subtle, but it's quite probable the eq function is being dynamically looked up every iteration and possibly interpreted each time as well (not sure how MATLAB does optimisation). Your best bet for performance is probably to put the for loop inside of the switch
switch average
case 'arithmetic'
for ... end
case 'geometric'
for ... end
case 'harmonic'
for ... end
end
Well, every function, even anonymous functions, can be expected to have some amount of extra overhead involved in calling it, making them slightly slower than their single-line expression counterparts in your example. However, in this case there may be extra overhead due to the fact that functions by the name eq already exist in abundance in MATLAB, since eq is the method name of the overloaded == operator. Using the WHICH command like so:
>> which eq -all
Will show you that eq is heavily overloaded, with one existing for each of the fundamental data types and most objects.
I would try using a different name for your anonymous function handle just to see if dispatching may be a factor, although I kinda doubt it based on the function precedence order (i.e. variables always appear to take precedence). Your best solution performance-wise may be to avoid the extra function call overhead by doing something like what DavW suggests.
I would like to make one other suggestion. Many of the mathematical operations you are doing can be greatly improved to make them more efficient, specifically by making use of the function MEAN and the colon operator to reshape an entire matrix into a column vector:
result = mean(matrix(:)); %# For the arithmetic mean
result = prod(matrix(:))^(1/numel(matrix)); %# For the geometric mean
result = 1/mean(1./matrix(:)); %# For the harmonic mean
Note that I didn't use the name mean for my variable since that is already used for the built-in function, and you definitely don't want to shadow it.