Let's say f(x) = (4x^2-9)/(2x-3). The function f(x) is undefined at x=3/2. Note that the function can be factored to yield f(x)=2x+3 but let's examine the first equation. In the following script when x=1.5, the function f(x=1.5)=4.0
clear all
clc
x = 0:0.3:2;
for i = 1:length(x)
if x(i) == 1.5 % this line for some reasons is ignored.
y(i) = 6;
else
y(i) = (4*x(i)^2-9)/(2*x(i)-3);
end
end
x
y
The output of the preceding script is
x = 0 0.3000 0.6000 0.9000 1.2000 1.5000 1.8000
y = 3.0000 3.6000 4.2000 4.8000 5.4000 4.0000 6.6000
Why y=4.0000 when x=1.5000? Now let's run the code without for-loop,
clear all
clc
x = 0:0.3:2
y = (4*x.^2-9)/(2*x-3)
The result of the above code is
x = 0 0.3000 0.6000 0.9000 1.2000 1.5000 1.8000
y = 3.6000
There is only one value for f(x). Can any one explain what is going on?
As for your first question, yes, you are running into a floating point precision error. You can check this by checking the difference between the x value that it's supposed to be a 1.5 and a 1.5.
x(6)-1.5
%ans=
% -2.2204e-16
Specifically in your case it comes from using 0.3 to construct the vector x since that value cannot be precisely saved into binary, see here for a deeper explanation
Any of the following should solve your problem
x=0:3:20; %Create the vector based on values that can be represented
x=x/10;
x=[0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8]; %Directly input the values
abs(x(i)-1.5) < tol %Instead of directly comparing values, compare the difference to a determined tolerance (very small compared to the values at hand)
As for your second question #Phill already gave you the answer, you are using / matrix division, and you want ./ element wise division.
When I run your first example with the for loop in Octave, I do not see a problem with the x=1.5 if statement being ignored. Perhaps this is a subtle difference between Matlab and Octave for this although I would be surprised.
For the array notation second example
clear all
clc
x = 0:0.3:2
y = (4*x.^2-9)/(2*x-3)
You have chosen the matrix division operator / instead of the element by element division operator ./
Related
This question already has answers here:
How to subtract a vector from each row of a matrix? [duplicate]
(2 answers)
Closed 6 years ago.
Hi I am new using MATLAB
What I am going to do is that
I have m-dimensional samples(data), which m is 2 here.
Data in MATLAB code is like this
X1 = [4,2;2,4;2,3;3,6;4,4];
X2 = [9,10;6,8;9,5;8,7;10,8];
I am going to subtract average of samples, which is
Mu1 = [3;3.8];
Then can I subtract each 2D data with average of samples in MATLAB code in one line
If I understand you correctly, you want to subtract the average Mu1 from your data (x1 and x2).
If so you could use the bsxfun function:
X1_subtracted = bsxfun(#minus, X1, Mu1')
which outputs:
X1_subtracted =
1.0000 -1.8000
-1.0000 0.2000
-1.0000 -0.8000
0 2.2000
1.0000 0.2000
Note you are going to have to use ' with the Mu1 as X1 has the shape 5x2 while Mu1 has the shape 1x2.
To get X1 - mean(X1) you could try
X = [X1(:,1) - mean(X1(:,1)), X1(:,2) - mean(X1(:,2))]
this will output
1. - 1.8
- 1. 0.2
- 1. - 0.8
0. 2.2
1. 0.2
I have a for loop in matlab, in which I want to make a matrix out of different matrices with different number of rows( I don't know what the difference of number of rows is gonna be). For example I have two matrices that are 10x1, and 4x1. How can I make a matrix from both of them.(In this case I know what is the difference, but in my loop I won't know their differences.)
A =
0.1000
0.5000
0.6000
0.8000
0.3000
0.2000
0.7000
0.6000
0.1000
1.0000
B =
0.1000
0.2000
0.3000
0.4000
C =
0.1000 0.1000
0.5000 0.2000
0.6000 0.3000
0.8000 0.4000
0.3000 NaN
0.2000 NaN
0.7000 NaN
0.6000 NaN
0.1000 NaN
1.0000 NaN
I want my last matrix to be like C.
Double Arrays
You can create matrices in MATLAB from concatenating other matrices together as long as the result is rectangular.
So, per your example, a new matrix/vector can be made by doing the following since the concatenation results in a rectangular output:
u = rand(10,1);
v = rand(4,1);
newVector = [u;v];
However, you cannot simply concatenate u and v into different columns since their row count differ.
So, a fill of some sort is necessary to balance the number of rows:
newMatrix = [ u , [v ; zeros(length(u)-length(v),1)]];
where the non-existent rows of v have been filled by a vector of 0s.
If you want a NaN fill, simply multiply the zero vector by NaN.
If you don't know whether u or v has greater length, you can do the following:
maxRows = max([length(u),length(v)]);
nFillRows = abs(length(u) - length(v));
% The fill vector will be empty if the vector has the maximum number of rows
uColumn = [u ; zeros( nFillRows * (length(u) ~= maxRows) ,1)];
vColumn = [v ; zeros( nFillRows * (length(v) ~= maxRows) ,1)];
newMatrix = [uColumn,vColumn];
In order for this to work, the number of rows to add needs to be known.
This can be set up recursively to make newMatrix larger and larger (though size() may need to be used if either u or v is a matrix instead of a vector); however, dynamically growing arrays can be a big performance hit.
Cell Arrays
If the for-loop's purpose is to generate a list of vectors that you simply want to store and use later, a cell array may be a good data structure to use:
vectorStorage = {u,v};
Since each element of a cell array can have it's own separate data type, it doesn't matter that u and v have different lengths.
From the command line, you will see this:
>> vectorStorage = {u,v}
vectorStorage =
[10x1 double] [4x1 double]
The first element is vector u, and the second element is vector v.
You can recall the value stored by specifying the index in curly braces: all(u == vectorStorage{1}) == 1.
If your first vector is A, create M by M=A, then for each new vector you wish to add, you can use this code:
if length(B)>size(M,1)
M=[M;nan(length(B)-size(M,1),size(M,2))];
M=[M B];
else
M=[M [B;nan(size(M,1)-length(B),1)]];
end
Although Troy's suggestion of using a cell array is a good idea for such a situation.
I have a matrix with the first row and the first column are data. Based on the row and the column, I wanna to find values in the matrix.
For example, I have the matrix look like this
A =
0.1000 1.0000 10.0000 100.0000
1.0000 0.9000 0.4000 0.5000
If the row data is 1 (the second row) and the column data is 10 (the third column), then I get 0.4 value.
Is there a way to find that value?
In case of the row data is 0.2 and the column data is 0.2, for example. How can I find values from that matrix?
Thank you for your respond.
Exact match case
%// Inputs (Added One more row to original post to include multiple match case)
A =[
0.1000 1.0000 10.0000 10.0000
1.0000 0.9000 0.4000 0.5000
1.0000 0.6000 0.5000 0.6000]
row_data = 1.0;
column_data = 10.0;
Now, if you are looking to find the values corresponding to all the matches, use this -
value = A(find(A(:,1)==row_data),find(A(1,:)==column_data))
giving us -
value =
0.4000 0.5000
0.5000 0.6000
Otherwise, if you are looking to find the value corresponding to just the first match, use this -
value = A(find(A(:,1)==row_data,1),find(A(1,:)==column_data,1))
giving us -
value =
0.4000
Also, please be mindful of the precision issues involved with floating point numbers. This shouldn't be a problem here because we have specifically mentioned the numbers and no other calculations had been done between matching and inputting the inputs.
Inexact match case
For cases when there aren't exact matches available, you can use interpolation as shown in codes next -
x = A(1,2:end)
y = A(2:end,1)
[X,Y] = meshgrid(x,y)
V = A(2:end,2:end)
row_data = 1.0;
column_data = 10.0;
value = interp2(X,Y,V,column_data,row_data)
If your Xq or Yq values are outside the X and Y ranges respectively, you need to do extrapolation, for which I think you can use scatteredInterpolant instead of interp2.
I have two sets of data. Each of them is a matrix and they have two columns, first column represents index x and second represents y. I want to see how similar are the curves of these datasets. In other words I need to have the correlation of these two curves represented by two matrices.
Thanks for help.
You might be looking for the corr2 function which calculates the correlation coefficient for each corresponding values in your matrices:
CorrMatrix = corr2(A,B)
plot(x,CorrMatrix);
Is that what you meant? If not please don't hesitate to ask for more details.
For matrices of unequal size I think you only have these options:
If you have the Signal Processing Toolbox you can use the cross-correlation function xcorr2, otherwise you can do the following:
1)either you calculate the correlation of you data where you use a part of the larger matrix so that the number of elements are similar: (the values I use are really dummy values sorry.)
clear
clc
% Create dummy matrices of unequal sizes
x =1:10;
x2 = 1:6;
A(:,1) = x;
A(:,2) = sin(x);
B(:,1) = x2;
B(:,2) = cos(x2);
A,B
C = corr2(A(1:6,:),B)
A =
1.0000 0.8415
2.0000 0.9093
3.0000 0.1411
4.0000 -0.7568
5.0000 -0.9589
6.0000 -0.2794
7.0000 0.6570
8.0000 0.9894
9.0000 0.4121
10.0000 -0.5440
B =
1.0000 0.5403
2.0000 -0.4161
3.0000 -0.9900
4.0000 -0.6536
5.0000 0.2837
6.0000 0.9602
C =
0.9463
or 2)
After some googling I saw that a similar question was posted here, in which it said that you can play around with Fourier transforms to get the correlation:
Cross-correlation in matlab without using the inbuilt function?
I am new to matlab and do not know how to make a table that compares the values of this polynomial function with w=1/(x^2+1)
my attempt
x= [-5,-3,-1, 1, 3,5]
x =
-5 -3 -1 1 3 5
y= [0.0385, 0.10, 0.50, 0.50, 0.10, 0.0385]
y =
0.0385 0.1000 0.5000 0.5000 0.1000 0.0385
yp=[0.0148,0.06,0.50,-0.50,-0.6,-0.0148]
yp =
0.0148 0.0600 0.5000 -0.5000 -0.6000 -0.0148
hp = hermite (x, y, yp )
hp =
-0.0000 -0.0000 0.0001 0.0004 -0.0011 -0.0100 0.0072 0.0969 -0.0113 -0.4156 0.0051 0.8282
Now it only remains to compare in a table the values of hp with w.
Could someone please help me?
Thanks for your help
I see no w in your question, but in general the expression
hp == w
will, if the vectors have the same length, return a vector of 0s and 1s, of that length, representing the cases where the two vectors match (1) or don't match (0). In passing, note that comparison for equality of floating-point numbers is fraught with 'issues' and you might be better evaluating:
abs(hp-w) < 10^-6
replacing 10^-6 by your preferred tolerance.
Given your definition for w you should be able to write
hp == 1/(x.^2+1)
Note the use of the elementwise squaring operator .^, which returns a vector of the same length as x with each element the square of the corresponding element in x. Of course, the expression
hp - 1./(x.^2+1)
will return a vector of the differences, which might be what you want.