Use Seasonal ARIMA model parameters in Matlab - matlab

I have the hourly electricity demand of a household for a year. I determined the ARIMA order by using auto.arima in R and now I want to use the received ARIMA order to estimate and forecast the next 24 hours in a MATLAB program.
Lets assume the fitted model is of order: p = 2, d = 0, q = 2; P = 2, D = 1, Q = 0 (frequency = 24). So an arima (2,0,2)(2,1,0)[24] model. How do I insert these parameters into the arima function in Matlab? So far i got:
%Create arima model
Mdl = arima(p,d,q);
Mdl.Seasonality = frequency;
%Estimate the coefficients
EstMdl = estimate(Mdl,past_data);
%Run the forecast for the next 24 hours
[yF,yMSE] = forecast(EstMdl,24,'Y0',past_data);
But that does not include the seasonal parameters so far. Indeed, I am quite confused by the documentation provided by mathworks.
Thankful for any suggestions!
Max

I have no experience in matlab, but looking at the documentation for arima it might be possible to specify the model as
c = 0;
p = 2;
d = 0;
q = 2;
S = 24;
P = 2;
D = 1;
Q = 0;
arima('constant', c, ...
'ARLags', p, ...
'D', d, ...
'MALags', q, ...
'Seasonality', D * S, ...
'SARLags', D * P * S) %, ...
% 'SMALags', D * Q * S) %commented seasonal MA because D * Q * S = 0
This is based on the Create SARIMA Model Template example from the link above, and seems to execute properly in their online IDE. Note due to my lack of any experience in matlab, i have not checked the results comparing model estimates. Note as well that 'Seasonality', 'SARLags' and 'SMALags' must be positive integers (or lacking), Otherwise an error seems to be returned.

Related

How do I make modulo and logical indexing work faster?

Consider the following command:
c(c>A | c<1) = mod(c(c>A | c<1),A);
where c is a column vector, and A is a scalar.
In short: Is there any way to make this work faster?
Explanation:
c(i) represents a column number in an A-by-A matrix. However, it may have values greater than A or smaller than 1, and this command should fix it in a sort of 'PAC-MAN' way. If c(i) is greater than A then when you reach A start counting back from 1, if you reach A again start again from 1, and so forth, until you count to the value of c(i). This should work in the same way for c(i)<1, so the counting will be reversed.
Examples:
If A = 10 and c(i) = 17, then c(i) after this command
should be 7.
If A = 10 and c(i) = -8, then c(i) after this command
should be 2.
If A = 10 and c(i) = 213, then c(i) after this command
should be 3.
The motivation: This command is a part of a simulation model I have, and currently it is the slowest part in it. This specific row is called millions(!) of times in each realization of the model, and there are a lot, so any improvement will be helpful. BTW, the typical size of c is about 10K-by-1.
p.s.: if you have a better suggestion for the title, I'll be happy to change it, I couldn't find a good one.
You don't need to actually do any logical indexing here because any values excluded by c > A | c < 1 will not be touched by mod and it will likely be faster to just pass everything to mod rather than doing comparisons and indexing to determine which values to pass to mod.
c = [17 -8 213, 7];
c = mod(c, A);
% 7 2 3 7
In general though, for other functions in which you need logical indexing on the input and output of a function, you'll want to store the logical array in a temporary variable rather than computing it twice:
touse = c < 1 | c > A;
c(touse) = mod(c(touse), A);
Here is a quick little benchmark showing the relative performance of each method:
function timemod()
sizes = round(linspace(100, 100000, 10));
[times1, times2, times3] = deal(zeros(numel(sizes), 1));
A = 10;
for k = 1:numel(sizes)
data = round(rand(sizes(k), 1) * A * 100);
times1(k) = timeit(#()indexing(data, A));
data = round(rand(sizes(k), 1) * A * 100);
times2(k) = timeit(#()indexing_temp(data, A));
data = round(rand(sizes(k), 1) * A * 100);
times3(k) = timeit(#()mod(data, A));
end
figure
plot(sizes, 1000 * cat(2, times1, times2, times3))
legend({'Indexing', 'Indexing w/ temp', 'No Indexing'})
xlabel('Number of Elements')
ylabel('Execution Time (ms)')
fprintf('Indexing: %0.2f ms\n', mean(times1 * 1000))
fprintf('Indexing with temp: %0.2f ms\n', mean(times2 * 1000))
fprintf('No Indexing or temp: %0.2f ms\n', mean(times3 * 1000))
end
function data = indexing(data, A)
data(data > A | data < 1) = mod(data(data > A | data < 1), A);
end
function data = indexing_temp(data, A)
inds = data > A | data < 1;
data(inds) = mod(data(inds), A);
end

Custom-made linspace and logspace in MATLAB

I decided to take a look at two functions linspace and logspace. Below I give two examples, one using MATLAB's built-in linspace and one for logspace along with their hand made implementation. In the first case both the built-in function linspace and the handmade code give the same results. However, this is not true when examining the logspace function. Could you please help me to found the error in the handmade code?
a = 1; b = 5; n = 7;
y = linspace(1,5,7);
yy = zeros(1,n); yy(1) = a;
for i=2:n
yy(i) = yy(i-1) + (b-a)/(n-1);
end
x = logspace(1,5,7);
xx = zeros(1,n); xx(1) = 10^a;
for i=2:n
xx(i) = xx(i-1) + (10^b-10^a)/(n-1);
end
Thank you!
The only difference between linspace and logspace is that they go one step further and take the power of 10 for every element in the linspace array.
As such, you'd simply take your equation for linspace you generated, take the result and raise it to the power of 10. However, with your code, you are relying on the previous result and that is already raised to the power of 10. Therefore, you'll need to take the anti-log to convert the previous result back to a linear form, then use the same logic was used to generate the linspace, then raise it back to the power of 10. Therefore, the relationship is:
xx[n] = 10^(log10(xx[n-1]) + ((b-a)/(n-1)))
You can certainly simplify this, taking advantage of the fact that 10^(log10(z)) = z, as long as z > 0. We can also split up the terms in the power using the property that 10^(m + n) = (10^m) * (10^n). Therefore:
xx[n] = xx[n-1] * (10^((b-a)/(n-1)))
As such, simply take your previous result multiply with 10^((b-a)/(n-1))
a = 1; b = 5; n = 7;
x = logspace(1,5,7);
xx = zeros(1,n); xx(1) = 10^a;
for i=2:n
xx(i) = xx(i-1)*(10^((b-a)/(n-1))); %// Change
end
We get for both x and xx:
>> format long g;
>> x
x =
Columns 1 through 4
10 46.4158883361278 215.443469003188 1000
Columns 5 through 7
4641.58883361278 21544.3469003189 100000
>> xx
xx =
Columns 1 through 4
10 46.4158883361278 215.443469003188 1000
Columns 5 through 7
4641.58883361278 21544.3469003188 100000

avoid the 'for' loop in matlab script by permuting

I have a code as follows:
Ne = 100;
H = rand(Ne,Ne);
g = zeros(Ne,1);
for e =1:Ne
hue = H(:,e);
ss1 = bsxfun(#times, hue', hue) .* M; % M is a Ne*Ne matrix
g(e) = sum(ss1(:));
end
when Ne > 1000, it runs very slowly.
I read the matlab documents, and find permute function is a possible way to speed up.
But I tried a whole day and failed.
Here is my code, and I do not know what is wrong.
C = permute(bsxfun(#times, permute(H, [1 3 2]), permute(H', [1 3 2])), [1 3 2]);
g = sum(sum(C))
If you do the math, you'll see that all you have to do is this:
g = sum(H) .^ 2;
Run speed: 0.000681 seconds, with Ne = 1000 (the original code took 3.047315 seconds).
EDIT:
Now, for your edited code, all you have to do is this:
g = diag(H.' * M * H);
Run speed: 0.072273 seconds, with Ne = 1000.
A speedup can be obtained if you notice that if you rearrange the terms, you can avoid a second matrix multiplication (which changes to a dot product) and all you have to do is sum the columns, like this:
g = sum(M.' * H .* H);
Run speed: 0.044190 seconds, with Ne = 1000.
It's always a good idea to do the math. We spend some time, but the code gains a good speedup. :)
NOTE: Run speeds were measured by averaging the time of a hundred runs.
For your edited code, this would work -
H1 = permute(H,[1 3 2]);
H2 = permute(H,[3 1 2]);
p1 = bsxfun(#times,H2,H1);
p1 = bsxfun(#times,p1,M);
g = sum(reshape(p1,Ne*Ne,[]),1)';
There isn't a great performance improvement with this though, as it's a bit faster only on a limited range of small datasizes.

MATLAB Discretizing Sine Function with +/-

Hello I am relatively new to MATLAB and have received and assignment in which we could use any programming language. I would like to continue MATLAB and have decided to use it for this assignment. The questions has to do with the following formula:
x(t) = A[1+a1*E(t)]*sin{w[1+a2*E(t)]*t+y}(+/-)a3*E(t)
The first question we have is to develop an appropriate discretization of x(t) with a time step h. I think i understand how to do this using step but because there is a +/- in the end I am running into errors. Here is what I have (I have simplified the equation by assigning arbitrary values to each variable):
A = 1;
E = 1;
a1 = 1;
a2 = 2;
a3 = 3;
w = 1;
y = 0;
% ts = .1;
% t = 0:ts:10;
t = 1:1:10;
x1(t) = A*(1+a1*E)*sin(w*(1+a2*E)*t+y);
x2(t) = a3*E;
y(t) = [x1(t)+x2(t), x1(t)-x2(t)]
plot(y)
The problem is I keep getting the following error because of the +/-:
In an assignment A(I) = B, the number of elements in B and I must be the same.
Error in Try1 (line 21)
y(t) = [x1(t)+x2(t), x1(t)-x2(t)]
Any help?? Thanks!
You can remove the (t) from the left-hand side of all three assignments.
y = [x1+x2, x1-x2]
MATLAB knows what to do with vectors and matrices.
Or, if you want to write it out the long way, tell MATLAB there will be two columns:
y(t, 1:2) = [x1(t)'+x2(t)', x1(t)'-x2(t)']
or two rows:
y(1:2, t) = [x1(t)+x2(t); x1(t)-x2(t)]
But this won't work when you have fractional values of t. The value in parentheses is required to be the index, not a dependent variable. If you want the whole vector, just leave it out.

How to write a generalized code

I write a code for linear feedback shift register.My code is in below:
X=5712;
D1(1)=0;
D2(1)=0;
D3(1)=0;
D4(1)=0;
D5(1)=0;
D6(1)=1;
for i=1:X-1
D6(i+1)=D1(i);
D5(i+1)=xor(D1(i),D6(i));
D4(i+1)=D5(i);
D3(i+1)=D4(i);
D2(i+1)=D3(i);
D1(i+1)=D2(i);
end
In my code i can only use 6 shift register.I know for degree,n=2,3,4,6,7,15,22, the polynomial is x^n+x+1.As the polynomial is same for those degrees so i want to write a common code for all.
Matlab experts Please need your help.
Your problem is that you are making separate vectors for each register. Rather make a single matrix (i.e. D replaces all of your D1, D2, ..., Dn) so that you can loop:
X = 20;
n = 6;
D = zeros(X, n);
D(1,n) = 1;
for ii = 1:X-1
D(ii+1, 1:n-2) = D(ii, 2:n-1);
D(ii+1, n-1) = xor(D(ii,1), D(ii,n));
D(ii+1, n) = D(ii, 1);
end
E = D(:, end:-1:1)