I have the following code
for i = 1:8760
A = [PVtech(i,:) WTtech(i,:)];
b = demand(i);
f = [CRF * PVtechcost(i,:) .* PVcap(i,:) ./ PVtech(i,:) CRF*WTtechcost(i,:) .* WTcap(i,:) ./ WTtech(i,:)];
x(i) = linprog(f, A,b,[], [], lb);
end
I'm trying to optimize linprog over the 8760 data set but can't seem to get the loop going for each row.
When I run it I get a size of `A to be 1x30 (when it should be 8760 by 30).
Does anyone see where I have coded wrongly?
Yes, every time you run it you are overwriting A with the single row [PVtech(i,:) WTtech(i,:)]
Try this: A = [A; PVtech(i,:) WTtech(i,:)]; i.e. vertical concatenation
With preallocation your code would look like this:
numRows = 8760;
A = zeros(numRows, 30);
for i = 1:numRows
A(i,:) = [PVtech(i,:) WTtech(i,:)];
b = demand(i);
f = [CRF*PVtechcost(i,:).*PVcap(i,:)./PVtech(i,:) CRF*WTtechcost(i,:).*WTcap(i,:)./WTtech(i,:)];
x(i) = linprog(f, A,b,[], [], lb);
end
Related
I would like to write a Matlab code to calculate the following:
\sum_{k=0}^{N-1} \frac{1}{k!} \sum_{i=0}^{k} {k \choose i}(a-1)^{k-i} a^k
and my code is:
N = 3;
a = [3 4];
for k = 0:N-1
f = 0;
for i = 0:k
f = f + nchoosek(k,i).* a.^k .* (a-1).^(k-i);
end
sumoff = sum(f);
all = (( 1./ (factorial(k))).*sumoff);
end
overall= sum(all);
'all' variable gives different value when it is inside the for loop rather than outside. But I want it to calculate when k = 0:N-1. What am I doing wrong?
Thank you.
The issue is your current code overwrites all on every iteration. Moving it outside the loop also doesn't work because you'll only save the result of the last iteration.
To save the all of every iteration, define all as a vector and then assign each intermediate result into that vector:
N = 3;
a = [3 4];
% preallocate a vector for `all`
all = nan(N-1, 1);
for k = 0:N-1
f = 0;
for i = 0:k
f = f + nchoosek(k,i) .* a.^k .* (a-1).^(k-i);
end
sumoff = sum(f);
% assign your intermediate result into the `all` vector
all(k+1) = ((1./(factorial(k))) .* sumoff);
end
overall = sum(all);
I have a loop
for i = 2:K
T(K,i) = ((4^(i-1))*T(K,i-1)-T(K-1,i-1))/(4^(i-1)-1);
end
where T is a two dimensional matrix (first element in given row, and all elements in rows above are already there) and K is a scalar.
I have tried to vectorize this loop to make it faster like this:
i = 2:K;
T(K,i) = ((4.^(i-1)).*T(K,i-1)-T(K-1,i-1))./(4.^(i-1)-1);
it compiles, but it yields improper results. Can you tell me where am I making mistake?
#EDIT:
I have written this, but still the result is wrong
i = 2:K;
i2 = 1:(K-1);
temp1 = T(K,i2)
temp2 = T(K-1,i2)
T(K,i) = ((4.^(i2)).*temp1-temp2)./(4.^(i2)-1);
First, let's re-index your loop (having fewer i-1 expressions):
for i=1:K-1
T(K,i+1) = ( 4^i*T(K,i) - T(K-1,i) ) / (4^i-1);
end
Then (I'll leave out the loop for now), we can factor out 4^i/(4^i-1):
T(K,i+1) = ( T(K,i) - T(K-1,i)/4^i ) * (4^i/(4^i-1));
Let's call a(i) = (4^i/(4^i-1)), b(i) = - T(K-1,i)/4^i, then expanding the first terms we get:
T(K,1) = T(K,1)
T(K,2) = T(K,1)*a(1) + b(1)*a(1)
T(K,3) = T(K,1)*a(1)*a(2) + b(1)*a(1)*a(2) + b(2)*a(2)
T(K,4) = T(K,1)*a(1)*a(2)*a(3) + b(1)*a(1)*a(2)*a(3) + b(2)*a(2)*a(3) + b(3)*a(3)
Then with c = [1, a(1), a(1)*a(2), ...] = [1, cumprod(a)]
T(K,i) = (T(K,1) + (b(1)/c(1) + b(2)/c(2) + ... + b(i-1)/c(i-1) ) * c(i)
So with d = b ./ c, e = cumsum(d), summarizing all calculations:
i=1:K-1;
a = 4.^i./(4.^i-1);
b = -T(K-1,1:end-1) ./ 4.^i;
c = [1, cumprod(a)];
d = b ./ c(1:end-1);
e = cumsum(d);
T(K,2:K) = (T(K,1) + e) .* c(2:end);
To further optimize this, note that 4^14/(4^14 - 1) equals 1, when calculated with double-precision, so actually T(K,14:K) could be optimized drastically -- i.e., you actually just need to calculate a, c, 1./c up to index 13. (I'll leave that as an exercise).
I'm trying to figure out a way to make a plot of a function in Matlab that accepts k parameters and returns a 3D point. Currently I've got this working for two variables m and n. How can I expand this process to any number of parameters?
K = zeros(360*360, number);
for m = 0:5:359
for n = 1:5:360
K(m*360 + n, 1) = cosd(m)+cosd(m+n);
K(m*360 + n, 2) = sind(m)+sind(m+n);
K(m*360 + n, 3) = cosd(m)+sind(m+n);
end
end
K(all(K==0,2),:)=[];
plot3(K(:,1),K(:,2),K(:,3),'.');
end
The code you see above is for a similar problem but not exactly the same.
Most of the time you can do this in a vectorized manner by using ndgrid.
[M, N] = ndgrid(0:5:359, 1:5:360);
X = cosd(M)+cosd(M+N);
Y = sind(M)+sind(M+N);
Z = cosd(M)+sind(M+N);
allZero = (X==0)&(Y==0)&(Z==0); % This ...
X(allZero) = []; % does not ...
Y(allZero) = []; % do ...
Z(allZero) = []; % anything.
plot3(X,Y,Z,'b.');
A little explanation:
The call [M, N] = ndgrid(0:5:359, 1:5:360); generates all combinations, where M is an element of 0:5:359 and N is an element of 1:5:360. This will be in the form of two matrices M and N. If you want you can reshape these matrices to vectors by using M = M(:); N = N(:);, but this isn't needed here.
If you were to have yet another variable, you would use: [M, N, P] = ndgrid(0:5:359, 1:5:360, 10:5:1000).
By the way: The code part where you delete the entry [0,0,0] doesn't do anything here, because this value doesn't appear. I see you only needed it, because you were allocating a lot more memory than you actually needed. Here are two versions of your original code, that are not as good as the ndgrid version, but preferable to your original one:
m = 0:5:359;
n = 1:5:360;
K = zeros(length(m)*length(n), 3);
for i = 1:length(m)
for j = 1:length(n)
nextRow = (i-1)*length(n) + j;
K(nextRow, 1) = cosd(m(i)) + cosd(m(i)+n(j));
K(nextRow, 2) = sind(m(i)) + sind(m(i)+n(j));
K(nextRow, 3) = cosd(m(i)) + sind(m(i)+n(j));
end
end
Or simpler, but a bit slower:
K = [];
for m = 0:5:359
for n = 1:5:360
K(end+1,1:3) = 0;
K(end, 1) = cosd(m)+cosd(m+n);
K(end, 2) = sind(m)+sind(m+n);
K(end, 3) = cosd(m)+sind(m+n);
end
end
This is a follow-up question to How to append an element to an array in MATLAB? That question addressed how to append an element to an array. Two approaches are discussed there:
A = [A elem] % for a row array
A = [A; elem] % for a column array
and
A(end+1) = elem;
The second approach has the obvious advantage of being compatible with both row and column arrays.
However, this question is: which of the two approaches is fastest? My intuition tells me that the second one is, but I'd like some evidence for or against that. Any idea?
The second approach (A(end+1) = elem) is faster
According to the benchmarks below (run with the timeit benchmarking function from File Exchange), the second approach (A(end+1) = elem) is faster and should therefore be preferred.
Interestingly, though, the performance gap between the two approaches is much narrower in older versions of MATLAB than it is in more recent versions.
R2008a
R2013a
Benchmark code
function benchmark
n = logspace(2, 5, 40);
% n = logspace(2, 4, 40);
tf = zeros(size(n));
tg = tf;
for k = 1 : numel(n)
x = rand(round(n(k)), 1);
f = #() append(x);
tf(k) = timeit(f);
g = #() addtoend(x);
tg(k) = timeit(g);
end
figure
hold on
plot(n, tf, 'bo')
plot(n, tg, 'ro')
hold off
xlabel('input size')
ylabel('time (s)')
leg = legend('y = [y, x(k)]', 'y(end + 1) = x(k)');
set(leg, 'Location', 'NorthWest');
end
% Approach 1: y = [y, x(k)];
function y = append(x)
y = [];
for k = 1 : numel(x);
y = [y, x(k)];
end
end
% Approach 2: y(end + 1) = x(k);
function y = addtoend(x)
y = [];
for k = 1 : numel(x);
y(end + 1) = x(k);
end
end
How about this?
function somescript
RStime = timeit(#RowSlow)
CStime = timeit(#ColSlow)
RFtime = timeit(#RowFast)
CFtime = timeit(#ColFast)
function RowSlow
rng(1)
A = zeros(1,2);
for i = 1:1e5
A = [A rand(1,1)];
end
end
function ColSlow
rng(1)
A = zeros(2,1);
for i = 1:1e5
A = [A; rand(1,1)];
end
end
function RowFast
rng(1)
A = zeros(1,2);
for i = 1:1e5
A(end+1) = rand(1,1);
end
end
function ColFast
rng(1)
A = zeros(2,1);
for i = 1:1e5
A(end+1) = rand(1,1);
end
end
end
For my machine, this yields the following timings:
RStime =
30.4064
CStime =
29.1075
RFtime =
0.3318
CFtime =
0.3351
The orientation of the vector does not seem to matter that much, but the second approach is about a factor 100 faster on my machine.
In addition to the fast growing method pointing out above (i.e., A(k+1)), you can also get a speed increase from increasing the array size by some multiple, so that allocations become less as the size increases.
On my laptop using R2014b, a conditional doubling of size results in about a factor of 6 speed increase:
>> SO
GATime =
0.0288
DWNTime =
0.0048
In a real application, the size of A would needed to be limited to the needed size or the unfilled results filtered out in some way.
The Code for the SO function is below. I note that I switched to cos(k) since, for some unknown reason, there is a large difference in performance between rand() and rand(1,1) on my machine. But I don't think this affects the outcome too much.
function [] = SO()
GATime = timeit(#GrowAlways)
DWNTime = timeit(#DoubleWhenNeeded)
end
function [] = DoubleWhenNeeded()
A = 0;
sizeA = 1;
for k = 1:1E5
if ((k+1) > sizeA)
A(2*sizeA) = 0;
sizeA = 2*sizeA;
end
A(k+1) = cos(k);
end
end
function [] = GrowAlways()
A = 0;
for k = 1:1E5
A(k+1) = cos(k);
end
end
I am currently trying to run a script that calls a particular function, but want to call the function inside a loop that halfs one of the input variables for roughly 4 iterations.
in the code below the function has been replaced for another for loop and the inputs stated above.
the for loop is running an Euler method on the function, and works fine, its just trying to run it with the repeated smaller step size im having trouble with.
any help is welcomed.
f = '3*exp(-x)-0.4*y';
xa = 0;
xb = 3;
ya = 5;
n = 2;
h=(xb-xa)/n;
x = xa:h:xb;
% h = zeros(1,4);
y = zeros(1,length(x));
F = inline(f);
y(1) = ya;
for j = 1:4
hOld = h;
hNew = hOld*0.5;
hOld = subs(y(1),'h',hNew);
for i = 1:(length(x)-1)
k1 = F(x(i),y(i));
y(i+1,j+1) = y(i) + h*k1;
end
end
disp(h)
after your comment, something like this
for j = 1:4
h=h/2;
x = xa:h:xb;
y = zeros(1,length(x));
y(1) = ya;
for i = 1:(length(x)-1)
k1 = F(x(i),y(i));
y(i+1,j+1) = y(i) + h*k1;
end
end