Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I want to make a graph with this function in matlab in space [-2,2]. Because I am new (really new actually) in matlab, I am struggling, especially with the first part of the function, the one with the "e":
So any help about the whole thing will be very useful.
Let's cover all the points in no particular order:
The e is known as Euler's constant, where e ~ 2.71828...
Something like ex, i.e. raising e to the power of x is known as the exponential function. While you could in theory compute e and then use the power operator (^ in matlab) to raise e to that power accordingly, this is in fact a less precise way of calculating the exponential function, and therefore matlab provides the exp function for that purpose. If you pass an array [x1, x2,...] to exp, it will perform this function "elementwise", and return [ex1, ex2,...] appropriately.
The sin function, similarly, if given an array of numbers, will calculate the sin for each of those numbers, and return an array of the same shape as its input.
You could use fplot with an anonymous function as Neo suggested, but I find that beginners find that confusing. So instead I would suggest you create an array of values between [-2,2], and obtain the value of y for each of them, which in matlab can be done as a single operation because it's good at working with arrays and performing such 'vectorized' operations:
x = [-2:0.1:2]; % Create an array of values from -2 to 2, with a step of 0.1
% Note: the ';' at the end suppresses output; if you want to
% see the contents of your array, remove it at the end.
Now that you have your array x you can perform operations on it. By convention, matlab uses "dot-operators" to denote "elementwise" operations, as opposed to 'undotted' ones denoting primarily "matrix" operations. Therefore to raise all elements of the array x to the power of 6, you would do x .^ 6
With that in mind, you can now calculate your f(x) for each point in the array x, by using elementwise operations:
y = exp( sin(x).^3 ) + x.^6 - 2*(x.^4) - x.^3 - 1;
The result is an array y of the same size as x.
You can now plot this using the plot command, which takes two arrays of the same size and plots all points in the first array against their equivalent points in the second array, as (x,y) pairs:
plot( x, y );
Output:
As you can see, matlab 'connects' the points by default. If you wanted to see just the individual points of your array instead, you can specify this as the third argument:
plot(x, y, 'o');
Type help plot at the matlab terminal to see more options for the plot command.
PS: The above plots were made in octave rather than in matlab, because I don't have matlab at home. Your own plots may look slightly different.
For a simple one-liner you could use:
fplot(#(x) exp(sin(x).^3) + x.^6 - 2*x.^4 - x.^3 - 1, [-2 2]);
See fplot.
Related
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 am trying to evaluate a triple integral using the 'trapz' command in MATLAB. My integrand is function of gamma1,gamma2,s... I want to evaluate the integral numerically and not symbolically.
syms gamma1; syms gamma2; syms s
f=gamma1*gamma2*exp(-s*10);
x= -20:0.3:20;
y=linspace(0.1,100000,length(x));
z=linspace(0.1,100000,length(x));
[s,gamma1,gamma2] = ndgrid(x,y,z);
mat=eval(f).* (gamma2>gamma1); %MY QUESTION IS HERE
out = trapz(x,trapz(y,trapz(z,mat,3),2),1);
My question is I have a condition on my integrand, it should be evaluated ONLY when gamma2 >gamma1. Is my code correct above i.e is the way I add the logical statement correct?
Yes, the logic is correct: mat will have zeros where the condition gamma2>gamma1 fails.
You can test correctness yourself by using an example where you know the answer already. For instance, integration of f=gamma1*gamma2*s within [0,2] in each variable gives 8 (with paper and pencil), and if the condition gamma2>gamma1 is added, the result is halved (by symmetry), so it becomes 4. And indeed, your code returns approximately 4 for this function.
As an aside: you may want to reconsider the desirability of using the same number of sample points in every dimension, given the disparity of sizes (40 by 100000 by 100000).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm going to write a program where the input is a data set of 2D points and the output is the regression coefficients of the line of best fit by minimizing the minimum MSE error.
I have some sample points that I would like to process:
X Y
1.00 1.00
2.00 2.00
3.00 1.30
4.00 3.75
5.00 2.25
How would I do this in MATLAB?
Specifically, I need to get the following formula:
y = A + Bx + e
A is the intercept and B is the slope while e is the residual error per point.
Judging from the link you provided, and my understanding of your problem, you want to calculate the line of best fit for a set of data points. You also want to do this from first principles. This will require some basic Calculus as well as some linear algebra for solving a 2 x 2 system of equations. If you recall from linear regression theory, we wish to find the best slope m and intercept b such that for a set of points ([x_1,y_1], [x_2,y_2], ..., [x_n,y_n]) (that is, we have n data points), we want to minimize the sum of squared residuals between this line and the data points.
In other words, we wish to minimize the cost function F(m,b,x,y):
m and b are our slope and intercept for this best fit line, while x and y are a vector of x and y co-ordinates that form our data set.
This function is convex, so there is an optimal minimum that we can determine. The minimum can be determined by finding the derivative with respect to each parameter, and setting these equal to 0. We then solve for m and b. The intuition behind this is that we are simultaneously finding m and b such that the cost function is jointly minimized by these two parameters. In other words:
OK, so let's find the first quantity :
We can drop the factor 2 from the derivative as the other side of the equation is equal to 0, and we can also do some distribution of terms by multiplying the -x_i term throughout:
Next, let's tackle the next parameter :
We can again drop the factor of 2 and distribute the -1 throughout the expression:
Knowing that is simply n, we can simplify the above to:
Now, we need to simultaneously solve for m and b with the above two equations. This will jointly minimize the cost function which finds the best line of fit for our data points.
Doing some re-arranging, we can isolate m and b on one side of the equations and the rest on the other sides:
As you can see, we can formulate this into a 2 x 2 system of equations to solve for m and b. Specifically, let's re-arrange the two equations above so that it's in matrix form:
With regards to above, we can decompose the problem by solving a linear system: Ax = b. All you have to do is solve for x, which is x = A^{-1}*b. To find the inverse of a 2 x 2 system, given the matrix:
The inverse is simply:
Therefore, by substituting our quantities into the above equation, we solve for m and b in matrix form, and it simplifies to this:
Carrying out this multiplication and solving for m and b individually, this gives:
As such, to find the best slope and intercept to best fit your data, you need to calculate m and b using the above equations.
Given your data specified in the link in your comments, we can do this quite easily:
%// Define points
X = 1:5;
Y = [1 2 1.3 3.75 2.25];
%// Get total number of points
n = numel(X);
% // Define relevant quantities for finding quantities
sumxi = sum(X);
sumyi = sum(Y);
sumxiyi = sum(X.*Y);
sumxi2 = sum(X.^2);
sumyi2 = sum(Y.^2);
%// Determine slope and intercept
m = (sumxi * sumyi - n*sumxiyi) / (sumxi^2 - n*sumxi2);
b = (sumxiyi * sumxi - sumyi * sumxi2) / (sumxi^2 - n*sumxi2);
%// Display them
disp([m b])
... and we get:
0.4250 0.7850
Therefore, the line of best fit that minimizes the error is:
y = 0.4250*x + 0.7850
However, if you want to use built-in MATLAB tools, you can use polyfit (credit goes to Luis Mendo for providing the hint). polyfit determines the line (or nth order polynomial curve rather...) of best fit by linear regression by minimizing the sum of squared errors between the best fit line and your data points. How you call the function is so:
coeff = polyfit(x,y,order);
x and y are the x and y points of your data while order determines the order of the line of best fit you want. As an example, order=1 means that the line is linear, order=2 means that the line is quadratic and so on. Essentially, polyfit fits a polynomial of order order given your data points. Given your problem, order=1. As such, given the data in the link, you would simply do:
X = 1:5;
Y = [1 2 1.3 3.75 2.25];
coeff = polyfit(X,Y,1)
coeff =
0.4250 0.7850
The way coeff works is that these are the coefficients of the regression line, starting from the highest order in decreasing value. As such, the above coeff variable means that the regression line was fitted as:
y = 0.4250*x + 0.7850
The first coefficient is the slope while the second coefficient is the intercept. You'll also see that this matches up with the link you provided.
If you want a visual representation, here's a plot of the data points as well as the regression line that best fits these points:
plot(X, Y, 'r.', X, polyval(coeff, X));
Here's the plot:
polyval takes an array of coefficients (usually produced by polyfit), and you provide a set of x co-ordinates and it calculates what the y values are given the values of x. Essentially, you are evaluating what the points are along the best fit line.
Edit - Extending to higher orders
If you want to extend so that you're finding the best fit for any nth order polynomial, I won't go into the details, but it boils down to constructing the following linear system. Given the relationship for the ith point between (x_i, y_i):
You would construct the following linear system:
Basically, you would create a vector of points y, and you would construct a matrix X such that each column denotes taking your vector of points x and applying a power operation to each column. Specifically, the first column is the zero-th power, the first column is the first power, the second column is the second power and so on. You would do this up until m, which is the order polynomial you want. The vector of e would be the residual error for each point in your set.
Specifically, the formulation of the problem can be written in matrix form as:
Once you construct this matrix, you would find the parameters by least-squares by calculating the pseudo-inverse. How the pseudo-inverse is derived, you can read it up on the Wikipedia article I linked to, but this is the basis for minimizing a system by least-squares. The pseudo-inverse is the backbone behind least-squares minimization. Specifically:
(X^{T}*X)^{-1}*X^{T} is the pseudo-inverse. X itself is a very popular matrix, which is known as the Vandermonde matrix and MATLAB has a command called vander to help you compute that matrix. A small note is that vander in MATLAB is returned in reverse order. The powers decrease from m-1 down to 0. If you want to have this reversed, you'd need to call fliplr on that output matrix. Also, you will need to append one more column at the end of it, which is the vector with all of its elements raised to the mth power.
I won't go into how you'd repeat your example for anything higher order than linear. I'm going to leave that to you as a learning exercise, but simply construct the vector y, the matrix X with vander, then find the parameters by applying the pseudo-inverse of X with the above to solve for your parameters.
Good luck!
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to create a function that takes a component matrix as a parameter and returns a matrix?
Apparently this function should normalise my data?
There are other instructions along with this step in my project such as:
Take the matrix and calculate the mean value along a certain column.
Calculate the difference between the measurement and this mean.
Subtract this difference from each measurement.
Return corrected matrix to the script.
Place corrected matrix in a variable within the script.
(I don't know if this is what the function is supposed to do or anything I'm completely lost and any help would be appreciated thanks!)
This is probably homework but I'll help you get started.
To create a function which takes a matrix and return a matrix:
function m_out = my_function(m_in)
%insert calculations here
end
To find the 2-norm of a matrix (which is the largest singular value):
the_norm = norm(my_matrix); % returns a scalar, 2-norm of matrix
To find the mean of a vector:
the_mean = mean(my_vector); % returns a scalar, mean of the vector
To access a specific column of a matrix:
my_col = my_matrix(:, col_number); % my_col is a vector
To access a specific row of a matrix:
my_row = my_matrix(row_num, :); % my_row is a vector
To subtract a scalar (single number) from a matrix:
new_matrix = old_matrix - single_number; % returns a matrix
To store a matrix into a variable (example):
my_matrix = [1,2,3;4,5,6;7,8,9];
Give it a try creating a function which puts this all together.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 3 years ago.
Improve this question
I am performing weighted least squares regression as described on wiki: WLS
I need to solve this equation: $B= (t(X)WX)^{-1}*t(X)Wy$
I use SVD to find: $(t(X)WX)^{-1}$ and store it in a matrix. In addition I store the matrix $H= (t(X)WX)^{-1}*t(X)W$ and simply do the following for any new value of y: B= Hy. This way I am able to save the cost of repeating SVD and matrix multiplications as y's change.
W is a diagonal matrix and generally does not change. However sometimes I change one or two elements on the diagonal in the W matrix. In that case I need to do SVD again and recalc the H matrix. This is clearly slow and time consuming.
My question is: If I know what changed in W and nothing changes in X is there a more efficient method to recalculate (t(X)WX)^-1?
Or put differently is there an efficient analytic method to find B given that only diagonal elements in W can change by a known amount?
There is such a method, in the case that the inverse you compute is a true inverse and not a generalised inverse (ie none of the singular values are 0). However some caution in using this is recommended. If you were doing your sums in infinite precision, all would be well. With finite precision, and particularly with nearly singular problems -- if some of the singular values are very large -- these formulae could result in loss of precision.
I'll call inverse you store C. If you add d (which can be positive or negative) to the m'th weight, then the modified C matrix, C~ say, and the modified H, H~, can be computed like this:
(' denotes transpose, and e_m is row the vector that's all 0, except the m'th slot is 1)
Let
c = the m'th column of H, divided by the original m'th weight
a = m'th row of the data matrix X
f = e_m - a*H
gamma = 1/d + a*c
(so c is a column vector, while a and f are row vectors)
Then
C~ = C - c*c'/gamma
H~ = H + c*f/gamma
If you want to find the new B, B~ say, for a given y, it can be calculated via:
r = y[m] - a*B
B~ = B + (r/gamma) * c
The derivation of these formulae is straightforward, but tedious, matrix algebra. The matrix inversion lemma comes in handy.