i've defined each function alone and plot it then made the addition of the functions then plot them all together using subplot .
%with using heaviside
clc;clear
t=-5:1/1000:+5
u1=heaviside(t-2)
u2=heaviside(t+1)
u3=heaviside(t+4)
X=u1+u2+u3
subplot(411)
plot(t,u1,'r');grid on
subplot(412)
plot(t,u2,'r');grid on
subplot(413)
plot(t,u3,'r');grid on
subplot(414)
plot(t,X,'r');grid on
In your case, X is the sum of 3 heaviside functions with different time-shifts, meaning it has a total value of 3*1 (for t to infinity).
If you want the 3 step function X to have an amplitude of 1, you have to divide by 3.
clc;clear
t=-5:1/1000:+5;
u1=heaviside(t-2);
u2=heaviside(t+1);
u3=heaviside(t+4);
X=(u1+u2+u3)/3;
Related
I'm writing a function that calculates the Taylor series of any Function.
syms x
y=cos(x);
y0=0;
a=0;
for i=0:25
diff(y,i); %%Gives the derivative formula
y0=y0+diff(y,i)*((x-a)^i)/factorial(i); %%sums every new element of the series
end
x=0:0.1:2*pi;
res = subs(y0,x);
plot(x,res,x,cos(x))
This is the Matlab code.
My problem is that it graphs cos(2x) instead of cos(x), similarly it graphs ln(2x) instead of ln(x) and so on.
I have checked the factorials and they appear to be correct.
What could be the problem, have I messed up the series or have I made a Matlab mistake?
You are constructing the Taylor polynomial around the point x with incrementx-a, that is, you are computing an approximation for
f(x+(x-a))=f(2*x-a)
Now as a=0, this means that as observed, you get f(2*x).
You would need to evaluate the derivatives at a to get the correct coefficients.
y0=y0+subs(diff(y,i),a)*((x-a)^i)/factorial(i); %%sums every new element of the series
x=linspace(0, 2*pi, 100);
y=sin(x);
z=exp(-x);
Given that x, y, and z are already initialized, how do I write a function that plots exp(-x)sin(x) across the interval [0, 4pi] without additional calls to sin or exp? Just need some help getting started.
Thanks to #Rayryeng for getting me started. I believe the following command more closely satisfies the question's specifications.
plot(x+x, z.*z.*y)
Well, you've already created arrays for sin and exp stored in y and z respectively. These arrays were created on the same domain as x. You just need to multiply both arrays together element-wise and plot the graph. It's as simple as doing:
plot(x, z.*y);
Here, .* stands for element-wise multiplication. If you were to do z*y, MATLAB interprets this as matrix multiplication where z and y are interpreted to be matrices. This is obviously not what you want.
However, your array of x only contains points from 0 to 2*pi. If you want to plot this from 0 to 4*pi, you have to modify your call to linspace:
x=linspace(0, 4*pi, 100); %// Change
y=sin(x);
z=exp(-x);
plot(x, z.*y);
Now, x will contain 100 points between 0 to 4*pi. For more information on basic MATLAB operations, check out this link: http://www.mathworks.com/help/matlab/matlab_prog/array-vs-matrix-operations.html. What you have asked falls into the basic realms of array and matrix operations.
Edit
In the spirit of your question, we can't modify linspace. You did something clever where we can simply scale our values of x by 2 or adding with x so that we have points going from 0 to 2*pi to 0 to 4*pi. Also, if we scale our points by 2, this means that our input argument into the function must also be scaled by 2. So, the final function we need to plot is:
y = exp(-2x)*sin(2x)
Noting your hint, exp(-2x) = exp(-x-x) = exp(-x)exp(-x). Further, note that sin(2x) performs a compression by a factor of 2 (tip of the hat goes to knedlsepp for noticing my blunder). Due to the periodic nature of sin(x), we know that elements will repeat after 2*pi, and so if you want to go to 4*pi, simply subsample y by a factor of 2 and then append these same elements to a new vector. Therefore, our expression for the function simplifies to:
y = exp(-x)exp(-x)sin(2x)
This leads to the answer alluded to knedlsepp:
plot(x+x, z.*z.*[y(1:2:end) y(1:2:end)]);
As such, you should consider changing your edits to match this answer instead. It isn't quite right with respect to the sin(x) part in your code.
I'm a beginner to matlab coding so any help would be appreciated.
I'm trying to minimize difference of summation squared problem SUM((a-b)^2) for 2 variables. I've already coded it up in Excel's Solver like this:
Goal= Sum[{i, 9}, ( Y[i]- (X[i]*m+b) )^2 ]
using nonlinear methods.
where Y and X and arrays, and m and b are the variables we are trying to find by minimizing the sum. How would go do this same thing in Matlab?
thanks.
Here is an example. I've set the bounds by using fmincon.
x=0:10;
y=x*randi(10)-randi(10)+rand(size(x)); % Create data y
f=#(A) sum((y-(A(1)*x+A(2))).^2) % Test function that we wish to minimise
R=fmincon(f,[1 1],[],[],[],[],[0 0],[Inf Inf]) % Run the minimisation R(1)=m, R(2)=b
plot(x,y,x,R(1)*x+R(2)) % Plot the results
I am doing a project where i find an approximation of the Sine function, using the Least Squares method. Also i can use 12 values of my own choice.Since i couldn't figure out how to solve it i thought of using Taylor's series for Sine and then solving it as a polynomial of order 5. Here is my code :
%% Find the sine of the 12 known values
x=[0,pi/8,pi/4,7*pi/2,3*pi/4,pi,4*pi/11,3*pi/2,2*pi,5*pi/4,3*pi/8,12*pi/20];
y=zeros(12,1);
for i=1:12
y=sin(x);
end
n=12;
j=5;
%% Find the sums to populate the matrix A and matrix B
s1=sum(x);s2=sum(x.^2);
s3=sum(x.^3);s4=sum(x.^4);
s5=sum(x.^5);s6=sum(x.^6);
s7=sum(x.^7);s8=sum(x.^8);
s9=sum(x.^9);s10=sum(x.^10);
sy=sum(y);
sxy=sum(x.*y);
sxy2=sum( (x.^2).*y);
sxy3=sum( (x.^3).*y);
sxy4=sum( (x.^4).*y);
sxy5=sum( (x.^5).*y);
A=[n,s1,s2,s3,s4,s5;s1,s2,s3,s4,s5,s6;s2,s3,s4,s5,s6,s7;
s3,s4,s5,s6,s7,s8;s4,s5,s6,s7,s8,s9;s5,s6,s7,s8,s9,s10];
B=[sy;sxy;sxy2;sxy3;sxy4;sxy5];
Then at matlab i get this result
>> a=A^-1*B
a =
-0.0248
1.2203
-0.2351
-0.1408
0.0364
-0.0021
However when i try to replace the values of a in the taylor series and solve f.e t=pi/2 i get wrong results
>> t=pi/2;
fun=t-t^3*a(4)+a(6)*t^5
fun =
2.0967
I am doing something wrong when i replace the values of a matrix in the Taylor series or is my initial thought flawed ?
Note: i can't use any built-in function
If you need a least-squares approximation, simply decide on a fixed interval that you want to approximate on and generate some x abscissae on that interval (possibly equally spaced abscissae using linspace - or non-uniformly spaced as you have in your example). Then evaluate your sine function at each point such that you have
y = sin(x)
Then simply use the polyfit function (documented here) to obtain least squares parameters
b = polyfit(x,y,n)
where n is the degree of the polynomial you want to approximate. You can then use polyval (documented here) to obtain the values of your approximation at other values of x.
EDIT: As you can't use polyfit you can generate the Vandermonde matrix for the least-squares approximation directly (the below assumes x is a row vector).
A = ones(length(x),1);
x = x';
for i=1:n
A = [A x.^i];
end
then simply obtain the least squares parameters using
b = A\y;
You can clearly optimise the clumsy Vandermonde generation loop above I have just written to illustrate the concept. For better numerical stability you would also be better to use a nice orthogonal polynomial system like Chebyshev polynomials of the first kind. If you are not even allowed to use the matrix divide \ function then you will need to code up your own implementation of a QR factorisation and solve the system that way (or some other numerically stable method).
I have various plots (with hold on) as show in the following figure:
I would like to know how to find equations of these six curves in Matlab. Thanks.
I found interactive fitting tool in Matlab simple and helpful, though somewhat limited in scope:
The graph above seems to be linear interpolation. Given vectors X and Y of data, where X contains the arguments and Y the function points, you could do
f = interp1(X, Y, x)
to get the linearly interpolated value f(x). For example if the data is
X = [0 1 2 3 4 5];
Y = [0 1 4 9 16 25];
then
y = interp1(X, Y, 1.5)
should give you a very rough approximation to 1.5^2. interp1 will match the graph exactly, but you might be interested in fancier curve-fitting operations, like spline approximations etc.
Does rxns stand for reactions? In that case, your curves are most likely exponential. An exponential function has the form: y = a*exp(b * x) . In your case, y is the width of mixing zone, and x is the time in years. Now, all you need to do is run exponential regression in Matlab to find the optimal values of parameters a and b, and you'll have your equations.
The advice, though there might be better answer, from me is: try to see the rate of increase in the curve. For example, cubic is more representative than quadratic if the rate of increase seems fast and find the polynomial and compute the deviation error. For irregular curves, you might try spline fitting. I guess there is also a toolbox in matlab for spline fitting.
There is a way to extract information with the current figure handle (gcf) from you graph.
For example, you can get the series that were plotted in a graph:
% Some figure is created and data are plotted on it
figure;
hold on;
A = [ 1 2 3 4 5 7] % Dummy data
B = A.*A % Some other dummy data
plot(A,B);
plot(A.*3,B-1);
% Those three lines of code will get you series that were plotted on your graph
lh=findall(gcf,'type','line'); % Extract the plotted line from the figure handle
xp=get(lh,'xdata'); % Extract the Xs
yp=get(lh,'ydata'); % Extract the Ys
There must be other informations that you can get from the "findall(gcf,...)" methods.