I need the following code to plot the range of values of C(i) against the values of x. So based on the code at the x = 1, I need C(1), at x = 2, C(2) and so on... A simple problem Im sure, please help!
clear all; clc;
n = 15
x = 1:(n-1)
T = 500;
D = T./(n-x)
for i=1:13
C(i) = D(i+1) - D(i)
end
plot(x, C(i), 'rx')
I guess what you want is this,
clear
clc
close all
n = 15;
x = 1:(n-1);
T = 500;
D = T./(n-x);
C = zeros(length(x) - 1, 1);
for i=1:13
C(i) = D(i+1) - D(i);
end
figure, plot(C, 'rx')
It is better to preallocate the C variable, so you can plot it then.
The C(i) only gave you the last number because after the for i is 13 and C(i)as you had it only gives you C in the 13th position.
Change:
plot(x, C(i), 'rx')
To:
plot(x(1:end-1), C, 'rx')
Actually, you could replace your for loop with this:
C = diff(D);
Which calculates the difference between consecutive elements.
Related
I'm trying to plot a piecewise function as an interpolation for the function f(x) = 1/(1+25x^2). This is how I plotted two functions previously when I wasn't dealing with piecewise.
z = linspace(-1,1,200);
yexact = 1./(1+25.*z.^2);
plot(z,yexact)
N=2;
x = size(N+1);
for i = 1:(N+1)
x(i) = -1+(1+cos(((2*i+1)*pi)/(2*(N+1))));
end
a = polyfit(x,1./(1+25.*x.^2),N);
yinter = polyval(a,z);
plot(z,yexact,z,yinter);
title('N = 2');
legend('exact','interpolation');
This was done for N = 2, 5, 10, 15, 20, 30. Now I need to change this to work for piecewise with the same N values. The x(i)'s are the intervals and the P(i)'s are the slopes of the piecewise function. So for N = 2, I need to plot P(1) from x(1) to x(2) and P(2) from x(2) to x(3).
N=2;
x = size(N+1);
P = size(N);
for i = 1:(N+1)
x(i) = -1 + 2*i/N;
end
for i = 1:N
P(i) = (1/(1+25*(x(i)).^2)) + ((i-1-x(i))/(x(i+1)-x(i)))*((1/(1+25*(x(i+1)).^2))-(1/(1+25*(x(i)).^2)));
end
All you have to do is to define your N values as a vector and, then, iterate over it. Into each iteration, the result returned by the computation over the current N value is plotted over the existing axis (for more information, visit this link of the official Matlab documentation).
Here is an example:
z = linspace(-1,1,200);
yexact = 1./(1+25.*z.^2);
plot(z,yexact);
hold on;
for n = [2 5 10]
x = size(n+1);
for i = 1:(n+1)
x(i) = -1+(1+cos(((2*i+1)*pi)/(2*(n+1))));
end
a = polyfit(x,1./(1+25.*x.^2),n);
yinter = polyval(a,z);
plot(z,yinter);
end
hold off;
And here is the resulting output:
When I execute this plot function trying to plot my data as a solid red line it will not plot anything.
plot(1:n, exp(x), '-r')
However, if I change the specification from a solid red line to a green line of circles still using the exact same data as so,
plot(1:n, exp(x), 'og')
it will plot! Why??
Here is all the code if needed.
clear all;
close all;
fprintf('\n\nJustin White Th-9\n\n')
x = input('Input the value of x to be approximated: ');
se = input('Input the target approximate perecent relative error, se: ');
[apre, macexp, n] = f_macexpF15(x, se);
macexp = macexp(1:end-1);
plotyy( 1:n, macexp, 1:n, apre);
hold on;
plot(1:n, exp(x), '-r')
And function it calls here
function[apre, macexp, n] = f_macexpF15(x, se)
fprintf('\nJustin White Th-9\n')
apre = 100*ones(1,3);
ms = [36 22 10];
macexp(1) = 1;
j = 1;
n = 1;
%% comments
while apre >= se
macexp(j+1) = macexp(j) + x^j/factorial(j);
apre(j) = 100 * ((macexp(j+1)-macexp(j))/macexp(j+1));
j = j + 1;
n = n + 1;
end
n = n - 1;
end
Thanks in advance
Easy, 1:n is a vector of length n, whereas x is only a scalar value if not entered correctly. So first of all check whether or not both vectors (1:n and x) are of same size.
Why? If you have two entries for the plot command, and one entry is a vector and the other is a scalar, then MATLAB treats that as if you entred n different plot commands (n for the length of the vector).
I am making a "movie" where the dots should move each X time
Here is the code (not copy paste so dont fix typos)
loop:
scatter(x,y,[],colors)
axies (a b c d)
pause(0.01);
end loop;
This is working great, but how can i add a LINE for the X axise (1:140)
At height 150?
I tired hold on but it just make a mess... or what is the command to clean grough when its in hold on?
Could this work for you?
N = 1000;
X = 1:N;
M = 160;
Y = randi(M, N);
figure
for i = 1:N
x = X(i);
y = Y(i);
scatter(x,y,[])
hold on
line([1 N], [150 150])
hold off
axis([1 N 0 200])
pause(0.01);
end
I have a matlab function that contain some constant parameter, I want to draw that function, on say same figure, using hold on (probably) while changing the value of that constant.
This my code:
close all
clear all
clc
m = 5;
x = 1:1:10;
y = m*x + 10;
h1 = figure;
plot(x,y)
m = 10;
figure(h1);
hold on
plot(x,y,': r')
When I tried using this code, I got two lines coincident on each others; and it looks matlab just used last value for the parameter m how can I make it use different values.
I found some stuff here, but doesn't fulfill my needs.
Any suggestions?
You need to recalculate y as well:
m = 5;
x = 1:1:10;
y = m*x + 10;
h1 = figure;
plot(x,y); hold on;
m = 10;
y = m*x + 10;
figure(h1);
plot(x,y,': r')
Or create an anonymous function:
x = 1:1:10;
f = #(m) m*x + 10;
%// and then:
h1 = figure;
plot(x,f(5) ); hold on;
plot(x,f(10),': r');
Currently, you're only updating m but you also have to calculate y again. This is why it plots exactly the same y (i.e. m is still 5) function when you issue the second plot.
You might want to use a simple for loop for that, like:
m = 5;
x = 1:1:10;
figure;
hold on;
for m=1:1:10
y = m*x + 10;
plot(x,y,': r')
end
In addition to the short answer - improving the plot..
%% Data Preparations
x = 1:10;
ms = 3; % number of different slopes
%% Graph Preparations
hold on;
% Prepare the string cell array
s = cell(1, ms);
% Handle storage
h = zeros(1, ms);
% Plot graphs
for m=1:ms
y = m*x + 10;
h(m)= plot(x,y,'Color',[1/m rand() rand()]);
s{m} = sprintf('Plot of y(m=%d)', m);
end
% Plot all or select the plots to include in the legend
ind = [ms:-1:1] .* ones(1,ms); % plot all
%ind = [ 1 3 4 ]; % plot selected
% Create legend for the selected plots
legend(h(ind), s{ind});
Additional advice: When working with MATLAB and you try to improve the performance of your code, you shoud try to avoid using for-loops since MATLAB is MATrix manipulation and that's what it can do best. Ones you've taken this philosophy in, you'll create the most beautiful code one-liners! ;)
This script is an adoption of Steve Lord's post.
I've got a vector and I want to calculate the moving average of it (using a window of width 5).
For instance, if the vector in question is [1,2,3,4,5,6,7,8], then
the first entry of the resulting vector should be the sum of all entries in [1,2,3,4,5] (i.e. 15);
the second entry of the resulting vector should be the sum of all entries in [2,3,4,5,6] (i.e. 20);
etc.
In the end, the resulting vector should be [15,20,25,30]. How can I do that?
The conv function is right up your alley:
>> x = 1:8;
>> y = conv(x, ones(1,5), 'valid')
y =
15 20 25 30
Benchmark
Three answers, three different methods... Here is a quick benchmark (different input sizes, fixed window width of 5) using timeit; feel free to poke holes in it (in the comments) if you think it needs to be refined.
conv emerges as the fastest approach; it's about twice as fast as coin's approach (using filter), and about four times as fast as Luis Mendo's approach (using cumsum).
Here is another benchmark (fixed input size of 1e4, different window widths). Here, Luis Mendo's cumsum approach emerges as the clear winner, because its complexity is primarily governed by the length of the input and is insensitive to the width of the window.
Conclusion
To summarize, you should
use the conv approach if your window is relatively small,
use the cumsum approach if your window is relatively large.
Code (for benchmarks)
function benchmark
clear all
w = 5; % moving average window width
u = ones(1, w);
n = logspace(2,6,60); % vector of input sizes for benchmark
t1 = zeros(size(n)); % preallocation of time vectors before the loop
t2 = t1;
th = t1;
for k = 1 : numel(n)
x = rand(1, round(n(k))); % generate random row vector
% Luis Mendo's approach (cumsum)
f = #() luisMendo(w, x);
tf(k) = timeit(f);
% coin's approach (filter)
g = #() coin(w, u, x);
tg(k) = timeit(g);
% Jubobs's approach (conv)
h = #() jubobs(u, x);
th(k) = timeit(h);
end
figure
hold on
plot(n, tf, 'bo')
plot(n, tg, 'ro')
plot(n, th, 'mo')
hold off
xlabel('input size')
ylabel('time (s)')
legend('cumsum', 'filter', 'conv')
end
function y = luisMendo(w,x)
cs = cumsum(x);
y(1,numel(x)-w+1) = 0; %// hackish way to preallocate result
y(1) = cs(w);
y(2:end) = cs(w+1:end) - cs(1:end-w);
end
function y = coin(w,u,x)
y = filter(u, 1, x);
y = y(w:end);
end
function jubobs(u,x)
y = conv(x, u, 'valid');
end
function benchmark2
clear all
w = round(logspace(1,3,31)); % moving average window width
n = 1e4; % vector of input sizes for benchmark
t1 = zeros(size(n)); % preallocation of time vectors before the loop
t2 = t1;
th = t1;
for k = 1 : numel(w)
u = ones(1, w(k));
x = rand(1, n); % generate random row vector
% Luis Mendo's approach (cumsum)
f = #() luisMendo(w(k), x);
tf(k) = timeit(f);
% coin's approach (filter)
g = #() coin(w(k), u, x);
tg(k) = timeit(g);
% Jubobs's approach (conv)
h = #() jubobs(u, x);
th(k) = timeit(h);
end
figure
hold on
plot(w, tf, 'bo')
plot(w, tg, 'ro')
plot(w, th, 'mo')
hold off
xlabel('window size')
ylabel('time (s)')
legend('cumsum', 'filter', 'conv')
end
function y = luisMendo(w,x)
cs = cumsum(x);
y(1,numel(x)-w+1) = 0; %// hackish way to preallocate result
y(1) = cs(w);
y(2:end) = cs(w+1:end) - cs(1:end-w);
end
function y = coin(w,u,x)
y = filter(u, 1, x);
y = y(w:end);
end
function jubobs(u,x)
y = conv(x, u, 'valid');
end
Another possibility is to use cumsum. This approach probably requires fewer operations than conv does:
x = 1:8
n = 5;
cs = cumsum(x);
result = cs(n:end) - [0 cs(1:end-n)];
To save a little time, you can replace the last line by
%// clear result
result(1,numel(x)-n+1) = 0; %// hackish way to preallocate result
result(1) = cs(n);
result(2:end) = cs(n+1:end) - cs(1:end-n);
If you want to preserve the size of your input vector, I suggest using filter
>> x = 1:8;
>> y = filter(ones(1,5), 1, x)
y =
1 3 6 10 15 20 25 30
>> y = (5:end)
y =
15 20 25 30