I have 40 structures in my Workspace. I Need to write a script to calculate the directional derivatives of all the elements. Here is the code :
[dx,dy] = gradient(Structure_element_1.value);
dxlb = min(min(dx));
dxub = max(max(dx));
dylb = min(min(dy));
dyub = max(max(dy));
[ddx,ddy] = gradient(gradient(Structure_element_1.value));
ddxlb = min(min(ddx));
ddxub = max(max(ddx));
ddylb = min(min(ddy));
ddyub = max(max(ddy));
This is the code for one element. I Need to find out the same for all the 40 elements and then use it later. Can anyone help with this.
To answer your literal question, you should store the variables in a structure array or at least a cell array. If all of your structures have the same fields, you can access all of them by indexing a single array variable, say Structure_element:
for i = 1:numel(Structure_element)
field = Structure_element(i).value
% compute gradients of field
end
Now to address the issue of the actual gradient computation. The gradient function computes an approximation for , where is your matrix of data. Normally, a MATLAB function is aware of how many output arguments are requested. When you call gradient(gradient(F)), the outer gradient is called on the first output of the inner gradient call. This means that you are currently getting an approximation for .
I suspect that you are really trying to get . To do this, you have to get both outputs from the inner call to gradient, pass them separately to the
outer call, and choose the correct output:
[dx,dy] = gradient(F);
[ddx, ~] = gradient(dx);
[~, ddy] = gradient(dy);
Note the separated calls. The tilde was introduced as a way to ignore function arguments in MATLAB Release 2009b. If you have an older version, just use an actual variable named junk or something like that.
Related
Is there any natural way to define a MATLAB function with multiple outputs that cannot or are inappropriate to "stack" into a matrix? For example, what if I want a function f that returns a 3x3 matrix A and a 4x4 matrix B?
I'm really surprised that this would even be an issue in MATLAB. Because in Python, all we need to do is return A, B which returns a tuple of the two. However it seems that MATLAB doesn't quite support the idea of containers. As a non-elegant workaround, I can use a struct to put the two pieces of data in, and the function goes something like:
function re = f(x)
%f: returns two dimensional-inconsistent matrices A and B
% function body as follows
....
A = ...;
B = ...;
% put data into the struct 're'
re.A = A;
re.B = B;
end
Apart from possible performance issues, this approach looks very unnatural and clumsy. Is there any better approach?
In MATLAB you can return any number of outputs with this syntax:
function [A,B] = f(x)
A = ...;
B = ...;
end
that is an even elegant solution than tuples used in python.
You can even control the behavior with the number of inputs and outputs (nargin and nargout) and discard outputs with a tilde. More information here.
I cannot think of a more elegant syntax.
Usually when having several outputs, one should declare the function as follows:
function [out1, out2, ... , outN] = funcName(in1,...,inM)
...
end
MATLAB also allows you to alter the behavior of your function based on the amount of requested inputs/outputs via the nargin/nargout functions, respectively (you can think of this as a form of overloading).
For example, you can specify as one of the inputs an array indicating which outputs you want the function to give, then populate the varargout cell array accordingly:
function varargout = funcName(in1,...,whichOut)
...
for indO = 1:numel(whichOut)
switch whichOut{indO}
case 'out1'
varargout{indO} = out1;
case 'out2'
... etc
case 'out6'
varargout{indO} = out6;
end
end
then call it using [out6, out1] = funcName(inp, {'out6','out1'});
See also varargin.
First of all, I just want to say that I'm not that used to using matlab, but I need for an assignment, I'm supposed to create a "brownian movement". My code is currently looking like this:
clf
hold on
prompt = 'Ge ett input';
size = input(prompt) ;
numParticles = input('Ange antal partiklar');
axis([-size size -size size]);
Part = [];
color = 'brkgmyco';
for i = drange(1:numParticles)
Part = [Part [0;0]];
end
for i = drange(1:200)
dxdy = randn(2,numParticles);
k = Part
Part = Part + dxdy;
My concern is how to print, I would even want like a small delay on every print, so you really can see what's happening for the assignment, is this possible to achieve from the code I've written for now or should anything be changed? Thanks in advance!
Here are some basic problems with your code, regardless of what you are trying to do:
You use size as a variable name. Doing so overrides MATLAB's function size.
The function zeros creates an array initialized by zeros, no need for a loop for that.
Instead of calculating randn for 200 times in a loop, you can do it once, with dxdy = randn(2,numParticles,200) and then simply refer to dxdy(:,:,i) within the loop.
The same holds for summation. Instead of summing within a loop to get the cumulative sum, use cumsum like Part = cumsum(randn(2,numParticles,200),3); and then refer to Part(:,:,i), within the loop.
Now to your task. You said you want to know how to print, but I believe you want to plot because you use some commands like axis, clf and hold, that refer to graphic objects. However, you never really do plot anything.
The basic and general function for plotting in 2D is plot, but there are many other more specific functions. One of them is scatter, and it has a sister function gscatter, that takes triples of x, y and groupand plot each (x(k),y(k)) colored by their group(k).
This code plots the particles on an axes, and animate their movement:
prompt = 'Ge ett input';
scope = input(prompt) ;
numParticles = input('Ange antal partiklar');
N = 500;
Part = cumsum(randn(2,numParticles,N)*scope/100,3);
h = gscatter(Part(1,:,1),Part(2,:,1),1:numParticles);
axis([-scope scope -scope scope]);
legend off
for k = 2:N
for p = 1:numParticles
h(p).XData = Part(1,p,k);
h(p).YData = Part(2,p,k);
end
drawnow
end
Is this what you look for?
I have 40 structures in my Workspace. I Need to write a script to calculate the directional derivatives of all the elements. Here is the code :
[dx,dy] = gradient(Structure_element_1.value);
dxlb = min(min(dx));
dxub = max(max(dx));
dylb = min(min(dy));
dyub = max(max(dy));
[ddx,ddy] = gradient(gradient(Structure_element_1.value));
ddxlb = min(min(ddx));
ddxub = max(max(ddx));
ddylb = min(min(ddy));
ddyub = max(max(ddy));
This is the code for one element. I Need to find out the same for all the 40 elements and then use it later. Can anyone help with this.
To answer your literal question, you should store the variables in a structure array or at least a cell array. If all of your structures have the same fields, you can access all of them by indexing a single array variable, say Structure_element:
for i = 1:numel(Structure_element)
field = Structure_element(i).value
% compute gradients of field
end
Now to address the issue of the actual gradient computation. The gradient function computes an approximation for , where is your matrix of data. Normally, a MATLAB function is aware of how many output arguments are requested. When you call gradient(gradient(F)), the outer gradient is called on the first output of the inner gradient call. This means that you are currently getting an approximation for .
I suspect that you are really trying to get . To do this, you have to get both outputs from the inner call to gradient, pass them separately to the
outer call, and choose the correct output:
[dx,dy] = gradient(F);
[ddx, ~] = gradient(dx);
[~, ddy] = gradient(dy);
Note the separated calls. The tilde was introduced as a way to ignore function arguments in MATLAB Release 2009b. If you have an older version, just use an actual variable named junk or something like that.
I am working on a code to extract my AR(1)-GARCH(1) parameter, which I estimated using an AR(1)-GJR(1,1) model to individual matrices so that I can use them as variables in my calculations. As I have 16 time series variables, I combine the code with a loop in the following way:
for i=1:nIndices
AA_ARCH(:,i) = cell2mat(fit{i}.Variance.ARCH)';
end;
My problem is that for some variables is are no for AA_ARCH(:,i) the dimension is lower than nIndices. Naturally, when I try to export the estimates in the loop which specified the dimension of (:,i) and nIndices matlab reports a dimension mismatch. I would like to tell Matlab to replace the NaN with 0 instead of leaving the spot empty so that it is able to produce a (1,nIndices) matrix from AA_ARCH.
I thought of something like the this:
fit{i}.Variance.Leverage(isnan(fit{i}.Variance.Leverage))=0
but I wasn't able to combine this part with the previous code.
I would be very happy about any hints!
Best, Carolin
UPDATE:
Here is a fully a runnable version of my code which produces my problem. Notice that the code produces a dimension mismatch error because there is no ARCH and GARCH estimate in the fit.gjr(1,1) for time series 1. For these missing values I would like to have 0 as a placeholder in the extracted matrix.
returns = randn(2,750)';
T = size(returns,1);
nIndices = 2;
model = arima('AR', NaN, 'Variance', gjr(1,1));
residuals = NaN(T, nIndices);
variances = NaN(T, nIndices);
fit = cell(nIndices,1);
options = optimset('fmincon');
options = optimset(options, 'Display' , 'off', 'Diagnostics', 'off', ...
'Algorithm', 'sqp', 'TolCon' , 1e-7);
for i = 1:nIndices
fit{i} = estimate(model, returns(:,i), 'print', false, 'options', options);
[residuals(:,i), variances(:,i)] = infer(fit{i}, returns(:,i));
end
for i=1:nIndices
AA_beta(:,i) = cell2mat(fit{i}.AR)';
AA_GARCH(:,i) = cell2mat(fit{i}.Variance.GARCH)';
AA_ARCH(:,i) = cell2mat(fit{i}.Variance.ARCH)';
AA_Leverage(:,i) = cell2mat(fit{i}.Variance.Leverage)';
end;
I have some general things to say about the code, but first a solution to your problem:
You can put a simple if/else structure in your loop to handle the case of an empty array:
for ind1=1:nIndices
AA_beta(:,ind1) = cell2mat(fit{ind1}.AR)'; %//'
%// GARCH
if isempty(cell2mat(fit{ind1}.Variance.GARCH)') %//'
AA_GARCH(1,ind1) = 0;
else
AA_GARCH(:,ind1) = cell2mat(fit{ind1}.Variance.GARCH)'; %//'
end
%// ARCH (same exact code, should probably be exported to a function)
if isempty(cell2mat(fit{ind1}.Variance.ARCH)') %//'
AA_ARCH(1,ind1) = 0;
else
AA_ARCH(:,ind1) = cell2mat(fit{ind1}.Variance.ARCH)'; %//'
end
AA_Leverage(:,ind1) = cell2mat(fit{ind1}.Variance.Leverage)'; %//'
end;
Side note: I initially tried something like this: soz = #(A)isempty(A)*0+~isempty(A)*A; as an inline replacement for the if/else, but it turns out that MATLAB doesn't handle [] + 0 the way I wanted (it results in [] instead of 0; unlike other languages like JS).
As for the other things I have to say:
I am a firm supporter of the notion that one shouldn't use i,j as loop indices, as this may cause compatibility problems in some cases where complex numbers are involved (e.g. if you loop index is i then 1*i now refers to the loop index instead of to the square root of -1).
Part of your problem was that the arrays you were writing into weren't preallocated - which also means the correct datatype was unknown to MATLAB at the time of their creation. Besides the obvious performance hit this entails, it could also result in errors like the one you encountered here. If, for example, you used cells for AA_beta etc. then they could contain empty values, which you could later replace with whichever placeholder your heart desired using a combination of cellfun and isempty. Bottom line: lint (aka the colorful square on the top right of the editor window) is your friend - don't ignore it :)
I am trying to figure out how to combine the input and output data into the ARX model and then apply it into the BIC (Bayesian Information Criterion) formula. Below is the code that I am currently working on:
for i=1:30; %% Set Model Order
data=iddata(output,input,1);
model = arx(data,[8 9 i]);
yp = predict(model,data);
ye = regress(data,yp{1,1}(1:4018,1));
M(i) = var(yp);
BIC(i)=(N+i*(log(N)-1))/(N-i)*log(M(i));
end
But it does not work. It keeps on giving me an error that's something like below:
"The syntax "Data{...}" is not supported. Use the "getexp" command to
extract individual experiments from an IDDATA object."
I did not understand what does that mean. Can someone explain it to me and where do I do wrong on my piece of code?
Update:
I tried to do it something like below, so far, there is no error. But then the graph for this BIC will be always straight line. Is something wrong with my regression part? how should I do for the regression?
N=length(rainfall_model);
for i=1:20; % Set Model Order
data=iddata(rainfall_model,tmax_model,1);
%d1 = getexp(data,1);
model = arx(data,[50 9 i]);
yp=predict(model,data);
y = yp.y ;
d1 = data.y ;
ye = (d1).^2 - (y).^2;
M(i)= mse(ye);
BIC(i)=(N+i*(log(N)-1))/(N-i)*log(M(i));
end
In your code example, yp returned from the 'predict' command is an iddata object and the cell notation '{...}' cannot be used with it. If you want to do regression, you have to extract the input (yp.u) or the output (yp.y) data from it.
Also, the command 'regress' does not work with idddata objects, since it is not a system identification toolbox function. Again you have to extract input or output data from the 'data' and 'yp' variables before calling it.
Update: To see what's in the iddata objects (data and yp), do
get(data)
get(yp)
You would see that you can extract the output data in two equivalent ways:
yp.y
yp.OutputData
Similarly, for the input data.