I'm stumped. What is going on with MATLAB's syntax?
clear all;
dx = .1;
x=-2:dx:2;
f=zeros(length(x),1);
int_f=zeros(length(x),1);
for n=1:length(x)
f(n)=x(n).^2;
int_f(n) = f(n)*dx+int_f(n);
end
plot(x,int_f(n));
I think you should be plotting that using plot(x,int_f); that way you plot the two arrays rather than one array against one single number.
Also your integral step is wrong, it should be int_f(n) = f(n)*dx+int_f(n-1) except for the first run, where it should be int_f(n) = f(n)*dx
Because in plot(x,int_f(n));, x is a row vector, but int_f(n) is a scalar value. You should be plotting a vector against a vector.
Related
I want to compute using MATLAB all the integers x such that x^2-2x<2000, but I am having problems in the displaying part because when I run my code MATLAB seems not to finish. My code is as follows:
x=100;
while x^2+2x-2000>=10^-6
x=x-20;
if x^2+2x-2000<10^-6
disp(x)
end
end
I think the wrong part is when I type disp(x) in the while loop, but I don't know how to fix it.
NOTE: I am using the 10^-6 to avoid rounding errors
Can someone help me to fix this code please?
Computationally, finding all integers that satisfy this condition will need some help from a quick insight into this problem. Otherwise, you'll have to test all the integers, which is impossible since there is infinite number of integers. Analytically, finding all the integers that satisfy the condition x^2-2x < 2000 means finding the integers that lies within the intersection of the curve x^2 - 2x and y = 2000.
Let's first take a look at the problem by plotting it:
x = -500:.1:500;
y = x.^2 - 2*x;
plot(x, y, 'color', 'g')
hold on
line([-200 200], [2000 2000], 'color', 'r')
You can easily see that you can limit your search to at least between -100 and 100. You can store the value in an array
results = [] % Declare empty array first and append value later.
for x = -100:100
if x^2 - 2*x < 2000
disp(x)
results = [results,x]; % Using a bracket to append value to the array.
end
end
And a faster way to get results using logical indexing.
x = -100:100
results = x(x.^2 - 2*x<2000)
In the above code, x.^2 - 2*x < 2000 generates a logical array that has the same size as x. Each element stores the logical value that comes from the evaluating each element in x with the expression. You then use this as a mask to pick out only elements in x that satisfy this condition.
If you add in some parentheses and use the correct syntax for 2*x, it works.
x=100;
while (x^2+2*x-2000)>= (10^-6)
x=(x-20);
if (x^2+2*x-2000) <10^-6
disp(x)
end
end
Building upon #User3667217's solution, you can also vectorise this:
x = -100:100;
y = x.^2-2*x;
tmp = y<2000;
results = y(tmp);
this will give you a speed up over the for-loop solution.
In my application, I need to find the "closest" (minimum Euclidean distance vector) to an input vector, among a set of vectors (i.e. a matrix)
Therefore every single time I have to do this :
function [match_col] = find_closest_column(input_vector, vectors)
cmin = 99999999999; % current minimum distance
match_col = -1;
for col=1:width
candidate_vector = vectors(:,c); % structure of the input is not important
dist = norm(input_vector - candidate_vector);
if dist < cmin
cmin = dist;
match_col = col;
end
end
is there a built-in MATLAB function that does this kind of thing easily (with a short amount of code) for me ?
Thanks for any help !
Use pdist2. Assuming (from your code) that your vectors are columns, transposition is needed because pdist2 works with rows:
[cmin, match_col] = min(pdist2(vectors.', input_vector.' ,'euclidean'));
It can also be done with bsxfun (in this case it's easier to work directly with columns):
[cmin, match_col] = min(sum(bsxfun(#minus, vectors, input_vector).^2));
cmin = sqrt(cmin); %// to save operations, apply sqrt only to the minimizer
norm can't be directly applied to every column or row of a matrix, so you can use arrayfun:
dist = arrayfun(#(col) norm(input_vector - candidate_vector(:,col)), 1:width);
[cmin, match_col] = min(dist);
This solution was also given here.
HOWEVER, this solution is much much slower than doing a direct computation using bsxfun (as in Luis Mendo's answer), so it should be avoided. arrayfun should be used for more complex functions, where a vectorized approach is harder to get at.
having a problem with my "new love", matlab: I wrote a function to calculate an integral using the trapz-method: `
function [L]=bogenlaenge_innen(schwingungen)
R = 1500; %Ablegeradius
OA = 1; %Amplitude
S = schwingungen; %Schwingungszahl
B = 3.175; %Tapebreite
phi = 0:2.*pi./10000:2.*pi;
BL = sqrt((R-B).^2+2.*(R-B).*OA.*sin(S.*phi)+OA.^2.*(sin(S.*phi)).^2+OA.^2.*S.^2.*(cos(S.*phi)).^2);
L = trapz(phi,BL)`
this works fine when i start it with one specific number out of the command-window. Now I want to plot the values of "L" for several S.
I did the following in a new *.m-file:
W = (0:1:1500);
T = bogenlaenge_innen(W);
plot(W,T)
And there it is:
Error using .*
Matrix dimensions must agree.
What is wrong? Is it just a dot somewhere? I am using matlab for the second day now, so please be patient.... ;) Thank you so much in advance!
PS: just ignore the german part of the code, it does not really matter :)
In your code, the arrays S and phi in the expression sin(S.*phi) should have same size or one of them should be a constant in order the code works
The error is most likely because you have made it so that the number of elements in schwingungen, i.e. W in your code, must be equal to the number of elements in phi. Since size(W) gives you a different result from size(0:2.*pi./10000:2.*pi), you get the error.
The way .* works is that is multiplies each corresponding elements of two matrices provided that they either have the same dimensions or that one of them is a scalar. So your code will work when schwingungen is a scalar, but not when it's a vector as chances are it has a different number of elements from the way you hard coded phi.
The simplest course of action (not necessarily the most Matlabesque though) for you is to loop through the different values of S:
W = (0:1:1500);
T = zeros(size(W); %Preallocate for speed)
for ii = 1:length(W)
T(ii) = bogenlaenge_innen(W(ii));
end
plot(W,T)
In your function you define phi as a vector of 10001 elements.
In this same function you do S.*phi, so if S is not the same length as phi, you will get the "dimensions must agree" error.
In your call to the function you are doing it with a vector of length 1501, so there is your error.
Regards
I have a function in two variables in MATLAB. I want to fix one variable, get the maxima of the resultant function, then change the value of the variable and again get the maxima, and so on. How can I get all the resulting maxima in one step or one vector? The variation in the second variable is a continuous one, not a discrete one.
Some variation of this work for you?
function main
clear all, close all
sizer = floor(rand(1) .* 10 + 1)
X = ceil(rand(sizer,1) .* 10)
Y = floor(rand(sizer,1) .* 10)
Z = Zmax(X, Y, sizer)
function Z = Zmax(X, Y, sizer)
Z = zeros(size(sizer));
for i = 1:1:sizer
Z(i) = max([X(i), Y(i)]);
end
Z = Z';
end
end
You'll probably have to add this to Zmax since your second variable has continuous variation: http://www.mathworks.com/help/curvefit/fnval.html
Thanks guys, but worked it out. I just varied the variable in a loop and stored the respective maxima in an array. Did the job for me.. :)
I am a bit stuck on a simple exercise and would appreciate some help.
I am trying to do some simple 2D interpolation using the "interp2" function in Matlab for a variable 'tmin' of dimension [15x12]:
lat = 15:1.5:32;
lon = 70:1.5:92;
lat_interp = 15:1:32;
lon_interp = 70:1:92;
[X,Y] = meshgrid(lat,lon);
[Xi,Yi] = meshgrid(lat_interp,lon_interp);
tmin_interp = zeros(length(lon_interp),length(lat_interp),Num_Days);
tmin_interp(:,:) = interp2(X,Y,tmin(:,:),Xi,Yi,'linear');
This code results in the last row and last column of tmin_interp to be NaNs, i.e.:
tmin_interp(23,1:18) ==> NaN
tmin_interp(1:23,18) ==> NaN
Does anyone know what I might be doing wrong? Am I making a simple mistake with regards to the interpolation setup? Thank you for your time.
The reason they are nans is that there is no data before and after your grid to interpolate to. Linear interpolation uses the gradient of the field at the Xi,Yi, in order to estimate the value at that point. If there is nothing either side, it can't.
You can use extrapval parameter to extrapolate outside the X,Y you specify. Just add the parameter 0 after 'linear':
interp2(X,Y,tmin(:,:),Xi,Yi,'linear', 0);
This will put zero for the points 'on the edge'. However, it is likely that for points outside, they may fall off to some default value, like zero. To do this, you can add zeros before and after tmin:
tmin_padded = [ zeros(1,size(tmin,2)+2)
zeros(size(tmin,1),1) tmin zeros(size(tmin,1),1)
zeros(1,size(tmin,2)+2) ];
(haven't checked this but you get the idea.) you will also need to add some pre- and post-values to X and Y.
Use some other value, if that's the 'outside' or 'default' value of tmin.
PS why are you creating tmin_interp as 3-dimensional?
Or just try:
interp2(X,Y,tmin(:,:),Xi,Yi,'spline');
to avoid imposing the 0 value.
HTH!