I want to Calculating the value of a function for different inputs in matlab and insert output in a matrix for example: x(1,1)=1 y(1,1)=1 x(1,2)=2 y(1,2)=4 and etc.
this is my m file in matlab:
clc,clear all,close all
x0=0;
xn=10;
n=10;
h=(xn-x0)/n;
k=1;
for k=1:n
x=[1:10];
x=x0+h;
y=x^2
x0=x;
end
My problem is that every time the for loop runs The output value is stored in the y and I can't use the output value for example: x=2 in somewhere else.
A few thoughts:
x=[1:10] does not do anything as you overwrite it in the next line
If you remove x = [1:10] you can achieve what you want to achieve by using indexing, i.e. x(k) = x0 + h and y(k) = x(k)^2 and x0 = x(k)
There is a simpler way though using vectorization though!
x = 1:10
y = x.^2
Related
I am trying to write a MATLAB function which interpolates data points in X to create a natural cubic spline, similar to interp1 but without using interp1. The function takes inputs vector x and c (from the system Ac=Y) and vector X of data points that I want to interpolate.
My function is almost complete, I have put the system in matrix form, found the y values, coefficients a,b,c and d but I do not know how to evaluate the X values to get my estimated value Y.
For example, this is what I have at the moment:
%cubic spline interpolation
n = length(x);
N = length(X);
Y = zeros(size(X));
for i = 1:n-1
for j = 1:N
while x(i) <= X(j) && x(i+1) >= X(j)
Y(j) = a(i)*(X(j)^3) + b(i)*(X(j)^2) + c(i)*X(j) + d(i);
break
end
end
end
My question is why does this not work? I know interp1 does not find the natural spline but I am very new to MATLAB so I was just using this built-in function as a reference as to how the graph should look and my function is just completely wrong. I hope that makes some sense. Any help would be great.
% create variable x with array of all necessary values
x=linspace(0.1,13,50);
for i=x
% create equation to determine y
y=(sqrt(2.*i)*4*i.^3)/(4.*i+7.^(i/10));
%create equation to determine z
z=log10(2.*i+5)+(4.*i+exp(i))/(2./3+4.*i.^2);
end
Using Matlab and im trying to use values from my x array to create two arrays, y and z, im pretty new to matlab and im struggling, thanks.
The problem in you code is that you did not use for loop properly. You can run through the index of x, then assign x(i) to a new variable k in each iteration, i.e.,
x=linspace(0.1,13,50);
for k = 1:length(x)
i = x(k);
% create equation to determine y
y(k) =(sqrt(2.*i)*4*i.^3)/(4.*i+7.^(i/10));
%create equation to determine z
z(k) =log10(2.*i+5)+(4.*i+exp(i))/(2./3+4.*i.^2);
end
Since MATLAB is able to vectorize the operations, so you are recommended to do it like below to speed up (for loop in MATLAB is expensive)
x = linspace(0.1,13,50);
y = (sqrt(2*x).*4.*x.^3)./(4*x+7^(x/10));
z = log10(2*x+5)+(4*x+exp(x))./(2/3 + 4*x.^2);
Remarks: you should be careful about the difference between .* and *, or ./ and /, where * and / are not element-wise operations.
Method 1:
you can initialize y and z into empty arrays and just append the corresponding result at the end:
% create variable x with array of all necessary values
x=linspace(0.1,13,50);
y=[];
z=[];
for i=x
% create equation to determine y
y(end+1)=(sqrt(2.*i)*4*i.^3)/(4.*i+7.^(i/10));
%create equation to determine z
z(end+1)=log10(2.*i+5)+(4.*i+exp(i))/(2./3+4.*i.^2);
end
This approach can prove to be poor in terms of efficiency, since the size of y and z changes dynamically.
Method 2:
If you still want to use a for loop, it is better to preallocate memory for y and z and iterate the indices of x, something like:
% create variable x with array of all necessary values
x=linspace(0.1,13,50);
% Memory allocation
y = zeros(1, length(x));
z = zeros(1, length(x));
for i = 1 : length(x)
% create equation to determine y
y(i)=(sqrt(2.*x(i)*4*x(i).^3)/(4.*x(i)+7.^(x(i)/10));
%create equation to determine z
z(i)=log10(2.*x(i)+5)+(4.*x(i)+exp(x(i)))/(2./3+4.*x(i).^2);
end
Method 3 (preferred one):
It is generally more efficient to vectorize your implementations. In your case you could use something like:
x = linspace(0.1,13,50);
y = (sqrt(2.*x)*4*.*x.^3) ./ (4*x + 7.^(x./10));
z = log10(2*x+5) + (4*x + exp(x)) ./ (2/3 + 4*x.^2);
I am trying to write a function that implements Newton's method in two dimensions and whilst I have done this, I have to now adjust my script so that the input parameters of my function must be f(x) in a column vector, the Jacobian matrix of f(x), the initial guess x0 and the tolerance where the function f(x) and its Jacobian matrix are in separate .m files.
As an example of a script I wrote that implements Newton's method, I have:
n=0; %initialize iteration counter
eps=1; %initialize error
x=[1;1]; %set starting value
%Computation loop
while eps>1e-10&n<100
g=[x(1)^2+x(2)^3-1;x(1)^4-x(2)^4+x(1)*x(2)]; %g(x)
eps=abs(g(1))+abs(g(2)); %error
Jg=[2*x(1),3*x(2)^2;4*x(1)^3+x(2),-4*x(2)^3+x(1)]; %Jacobian
y=x-Jg\g; %iterate
x=y; %update x
n=n+1; %counter+1
end
n,x,eps %display end values
So with this script, I had implemented the function and the Jacobian matrix into the actual script and I am struggling to work out how I can actually create a script with the input parameters required.
Thanks!
If you don't mind, I'd like to restructure your code so that it is more dynamic and more user friendly to read.
Let's start with some preliminaries. If you want to make your script truly dynamic, then I would recommend that you use the Symbolic Math Toolbox. This way, you can use MATLAB to tackle derivatives of functions for you. You first need to use the syms command, followed by any variable you want. This tells MATLAB that you are now going to treat this variable as "symbolic" (i.e. not a constant). Let's start with some basics:
syms x;
y = 2*x^2 + 6*x + 3;
dy = diff(y); % Derivative with respect to x. Should give 4*x + 6;
out = subs(y, 3); % The subs command will substitute all x's in y with the value 3
% This should give 2*(3^2) + 6*3 + 3 = 39
Because this is 2D, we're going to need 2D functions... so let's define x and y as variables. The way you call the subs command will be slightly different:
syms x, y; % Two variables now
z = 2*x*y^2 + 6*y + x;
dzx = diff(z, 'x'); % Differentiate with respect to x - Should give 2*y^2 + 1
dzy = diff(z, 'y'); % Differentiate with respect to y - Should give 4*x*y + 6
out = subs(z, {x, y}, [2, 3]); % For z, with variables x,y, substitute x = 2, y = 3
% Should give 56
One more thing... we can place equations into vectors or matrices and use subs to simultaneously substitute all values of x and y into each equation.
syms x, y;
z1 = 3*x + 6*y + 3;
z2 = 3*y + 4*y + 4;
f = [z1; z2];
out = subs(f, {x,y}, [2, 3]); % Produces a 2 x 1 vector with [27; 25]
We can do the same thing for matrices, but for brevity I won't show you how to do that. I will defer to the code and you can see it then.
Now that we have that established, let's tackle your code one piece at a time to truly make this dynamic. Your function requires the initial guess x0, the function f(x) as a column vector, the Jacobian matrix as a 2 x 2 matrix and the tolerance tol.
Before you run your script, you will need to generate your parameters:
syms x y; % Make x,y symbolic
f1 = x^2 + y^3 - 1; % Make your two equations (from your example)
f2 = x^4 - y^4 + x*y;
f = [f1; f2]; % f(x) vector
% Jacobian matrix
J = [diff(f1, 'x') diff(f1, 'y'); diff(f2, 'x') diff(f2, 'y')];
% Initial vector
x0 = [1; 1];
% Tolerance:
tol = 1e-10;
Now, make your script into a function:
% To run in MATLAB, do:
% [n, xout, tol] = Jacobian2D(f, J, x0, tol);
% disp('n = '); disp(n); disp('x = '); disp(xout); disp('tol = '); disp(tol);
function [n, xout, tol] = Jacobian2D(f, J, x0, tol)
% Just to be sure...
syms x, y;
% Initialize error
ep = 1; % Note: eps is a reserved keyword in MATLAB
% Initialize counter
n = 0;
% For the beginning of the loop
% Must transpose into a row vector as this is required by subs
xout = x0';
% Computation loop
while ep > tol && n < 100
g = subs(f, {x,y}, xout); %g(x)
ep = abs(g(1)) + abs(g(2)); %error
Jg = subs(J, {x,y}, xout); %Jacobian
yout = xout - Jg\g; %iterate
xout = yout; %update x
n = n + 1; %counter+1
end
% Transpose and convert back to number representation
xout = double(xout');
I should probably tell you that when you're doing computation using the Symbolic Math Toolbox, the data type of the numbers as you're calculating them are a sym object. You probably want to convert these back into real numbers and so you can use double to cast them back. However, if you leave them in the sym format, it displays your numbers as neat fractions if that's what you're looking for. Cast to double if you want the decimal point representation.
Now when you run this function, it should give you what you're looking for. I have not tested this code, but I'm pretty sure this will work.
Happy to answer any more questions you may have. Hope this helps.
Cheers!
I have two for loops in a nested format. My second loop calculates the final equation. The display of the result is outside the second loop in order to display when the second loop is complete.
Below is the logic I used in MATLAB. I need to plot graph of eqn2 vs x.
L=100
for x=1:10
eqn1
for y=1:L
eqn2
end
value = num2strn eqn2
disp value
end
Currently the problem I am facing is that value or output of eqn2 is always replaced after each cycle until x reaches 10. Hence, the workspace table of eqn2 and value only shows the last value. My intention is to document all the output values of value in every cycle of x from 1:10.
How can I do this?
You pseudo-coded a little too strongly for my taste - I have tried to reconstruct what you were trying to do. If I understood correctly, this should do address your question (store intermediate results from the calculation in array Z):
L=100
z = zeros(L,10);
for x=1:10
% perform some calculations
eqn1
for y=1:L
% perform some more calculations; it is not clear whether the result of
% this loop over y=1:L yields one value, or L. I am going to assume L values
z(y, x) = eqn2(x, y)
end
value =num2strn eqn2
disp value
end
% now you have the value of each evaluation of the innermost loop available. You can plot it as follows:
figure;
plot( x, z); % multiple plots with a common x parameter; may need to use Z' (transpose)...
title 'this is my plot';
xlabel 'this is the x axis';
ylabel 'this is the y axis';
As for the other questions you asked in your comments, you could probably findd inspiration in the following:
L = 100;
nx = 20; ny = 99; % I am choosing how many x and y values to test
Z = zeros(ny, nx); % allocate space for the results
x = linspace(0, 10, nx); % x and y don't need to be integers
y = linspace(1, L, ny);
myFlag = 0; % flag can be used for breaking out of both loops
for xi = 1:nx % xi and yi are integers
for yi = 1:ny
% evaluate "some function" of x(xi) and y(yi)
% note that these are not constrained to be integers
Z(yi, xi) = (x(xi)-4).^2 + 3*(y(yi)-5).^2+2;
% the break condition you were asking for
if Z(yi, xi) < 5
fprintf(1, 'Z less than 5 with x=%.1f and y=%.1f\n', x(xi), y(yi));
myFlag = 1; % set flag so we break out of both loops
break
end
end
if myFlag==1, break; end % break out of the outer loop as well
end
This may not be what you had in mind - I cannot understand "run the loop untill all the values of z(y,x) <5 and then it should output x". If you run the outer loop to completion (that's the only way you know "all the values of z(y,x)" then your value of x will be the last value it was... This is why I was suggesting running through all values of x and y, collecting the whole matrix Z, and then examining Z for the things you want.
For example, if you wonder if there is a value for X for which all Z < 5, you could do this (if you didn't break out of the for loops):
highestZ = max(Z, [], 1); % "take the highest value of Z in the 1 dimension
fprintf(1, 'Z is always < 5 for x = %d\n', x(highestZ<5));
etc.
If you can't figure it out from here, I give up...
Suppose I have a function y(t,x) = exp(-t)*sin(x)
In Matlab, I define
t = [0: 0.5: 5];
x = [0: 0.1: 10*2*pi];
y = zeros(length(t), length(x)); % empty matrix init
Now, how do I define matrix y without using any loop, such that each element y(i,j) contains the value of desired function y at (t(i), x(j))? Below is how I did it using a for loop.
for i = 1:length(t)
y(i,:) = exp(-t(i)) .* sin(x);
end
Your input vectors x is 1xN and t is 1xM, output matrix y is MxN. To vectorize the code both x and t must have the same dimension as y.
[x_,t_] = meshgrid(x,t);
y_ = exp(-t_) .* sin(x_);
Your example is a simple 2D case. Function meshgrid() works also 3D. Sometimes you can not avoid the loop, in such cases, when your loop can go either 1:N or 1:M, choose the shortest one. Another function I use to prepare vector for vectorized equation (vector x matrix multiplication) is diag().
there is no need for meshgrid; simply use:
y = exp(-t(:)) * sin(x(:)'); %multiplies a column vector times a row vector.
Those might be helpful:
http://www.mathworks.com/access/helpdesk/help/techdoc/ref/meshgrid.html
http://www.mathworks.com/company/newsletters/digest/sept00/meshgrid.html
Good Luck.