how to apply iddata into calculation? - matlab

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.

Related

Directional Derivatives of a Matrix

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.

Loopin through all the structures in a workspace [duplicate]

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.

Converting mixed empty/non-empty cells into a numeric matrix

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 :)

integrating simulink into a matlab script

I have the following problem. I want to integrate a simulink model into a matlab script, to do different things in a loop with the simulink part of the program.
The program below actually does what I was hoping for when I defined the parameters I used into the simulink model in the workspace. But this solution does not satisfy me. I want to pass the parameters as the second value of the sim function. Unfortunately I can't get my head around this. I literally copied the part to create a structure from the matlab site where the following code sample has been given.
myStruct = Simulink.Parameter;
myStruct.Value = struct('number',1,'units',24);
myStruct.CoderInfo.StorageClass = 'ExportedGlobal';
Unfortunately I get the following error Input argument "m_startSpeed" is undefined. because in my script the parameter m_startSpeed is a value which I input when running the script.
function [optBreakPoint] = computeBreakPoint(m_startSpeed, m_endSpeed, m_length)
myStruct = Simulink.Parameter;
myStruct.Value = struct('m' , 1500, 'R' , 0.25, 'mi' , 1, 'f' , 0.1, 'F' , 50000,'BreakForce' , -10, 'startSpeed' , m_startSpeed, 'breakPoint' , m_length);
myStruct.CoderInfo.StorageClass = 'ExportedGlobal';
endSpeed = m_endSpeed;
while(1)
[T, X, Y] = sim('car', myStruct);
optBreakPoint = breakPoint;
break;
end
plot(T, X);
end
How should I solve this problem?
The input structure (i.e. the second input to the sim function), contains information about how to simulate the model (i.e. information from the Model Configuration dialog, or Configuration Set), not parameters of the blocks in the model.
Look at either
>> doc sim
or http://www.mathworks.com/help/simulink/slref/sim.html
for an example of what that structure should look like.
Block parameters are obtained from a workspace - by default the Base Workspace, but you can specify this by changing the models 'SrcWorkspace" parameter.
This property is also discussed on the above documentation pages.

How can I create/process variables in a loop in MATLAB?

I need to calculate the mean, standard deviation, and other values for a number of variables and I was wondering how to use a loop to my advantage. I have 5 electrodes of data. So to calculate the mean of each I do this:
mean_ch1 = mean(ch1);
mean_ch2 = mean(ch2);
mean_ch3 = mean(ch3);
mean_ch4 = mean(ch4);
mean_ch5 = mean(ch5);
What I want is to be able to condense that code into a line or so. The code I tried does not work:
for i = 1:5
mean_ch(i) = mean(ch(i));
end
I know this code is wrong but it conveys the idea of what I'm trying to accomplish. I want to end up with 5 separate variables that are named by the loop or a cell array with all 5 variables within it allowing for easy recall. I know there must be a way to write this code I'm just not sure how to accomplish it.
You have a few options for how you can do this:
You can put all your channel data into one large matrix first, then compute the mean of the rows or columns using the function MEAN. For example, if each chX variable is an N-by-1 array, you can do the following:
chArray = [ch1 ch2 ch3 ch4 ch5]; %# Make an N-by-5 matrix
meanArray = mean(chArray); %# Take the mean of each column
You can put all your channel data into a cell array first, then compute the mean of each cell using the function CELLFUN:
meanArray = cellfun(#mean,{ch1,ch2,ch3,ch4,ch5});
This would work even if each chX array is a different length from one another.
You can use EVAL to generate the separate variables for each channel mean:
for iChannel = 1:5
varName = ['ch' int2str(iChannel)]; %# Create the name string
eval(['mean_' varName ' = mean(' varName ');']);
end
If it's always exactly 5 channels, you can do
ch = {ch1, ch2, ch3, ch4, ch5}
for j = 1:5
mean_ch(j) = mean(ch{j});
end
A more complicated way would be
for j = 1:nchannels
mean_ch(j) = eval(['mean(ch' num2str(j) ')']);
end
Apart from gnovice's answer. You could use structures and dynamic field names to accomplish your task. First I assume that your channel data variables are all in the format ch* and are the only variables in your MATLAB workspace. The you could do something like the following
%# Move the channel data into a structure with fields ch1, ch2, ....
%# This could be done by saving and reloading the workspace
save('channelData.mat','ch*');
chanData = load('channelData.mat');
%# Next you can then loop through the structure calculating the mean for each channel
flds = fieldnames(chanData); %# get the fieldnames stored in the structure
for i=1:length(flds)
mean_ch(i) = mean(chanData.(flds{i});
end