How I can build a table in matlab with the following values? - matlab

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.

Related

Am I facing floating point issue?

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 ./

Scale output of FFT (MATLAB)

I am doing some Fourier transforms of audio (.wav) data using the FFT command in MATLAB. The input values are numbers between -1.0 and 1.0
My understanding is that after taking the absolute value (modulus) of the output of the FFT, I should get values that have units of amplitude, but the actual values are on the order of thousands. This doesn't make sense as theoretically I should be able to sum the Fourier components to get the original signal back. I feel like the output should then also be between 0 and 1, so what's up here? My guess is that the FFT algorithm blows it out of proportion but I'm not sure what value to use to scale it back.
The FFT is an algorithm for computing the Discrete Fourier Transform (DFT). The inverse DFT (IDFT) has a 1/N scaling factor in its definition. Perhaps that's what's confusing you. From the Wikipedia:
DFT (from finite sequence x to Fourier coefficients X):
IDFT (from X back to x):
So, just apply ifft to the result of fft and you'll get the original result. For example:
>> x = linspace(-1,1,5)
x =
-1.0000 -0.5000 0 0.5000 1.0000
>> y = fft(x)
y =
0 -1.2500 + 1.7205i -1.2500 + 0.4061i -1.2500 - 0.4061i -1.2500 - 1.7205i
>> abs(y)
ans =
0 2.1266 1.3143 1.3143 2.1266 %// note values greater than 1
>> ifft(y)
ans =
-1.0000 -0.5000 0.0000 0.5000 1.0000
In fact, the IDFT can be expressed in terms of the DFT applying complex conjugation and the referred scaling factor. Denoting the DFT by F, the IDFT by F-1 and complex conjugate by *,
In the above example,
>> 1/numel(y) * conj(fft(conj(y)))
ans =
-1.0000 -0.5000 0.0000 0.5000 1.0000
In Matlab use the following code to scale from 1 to (roughly) 0.
dataDFT=abs(fft(data)); % Take the complex magnitude of the fft of your data
dataDFTScaled=dataDFT/max(dataDFT); % Divide by the maximum value
You don't want it to scale to zero because that would make it impossible to view on a log plot.

How to create a matrix out of different matrices with different number of rows in matlab?

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.

Correlation of curves using Matlab

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?

ICA - Statistical Independence & Eigenvalues of Covariance Matrix

I am currently creating different signals using Matlab, mixing them by multiplying them by a mixing matrix A, and then trying to get back the original signals using FastICA.
So far, the recovered signals are really bad when compared to the original ones, which was not what I expected.
I'm trying to see whether I'm doing anything wrong. The signals I'm generating are the following: (Amplitudes are in the range [0,1].)
s1 = (-x.^2 + 100*x + 500) / 3000; % quadratic
s2 = exp(-x / 10); % -ve exponential
s3 = (sin(x)+ 1) * 0.5; % sine
s4 = 0.5 + 0.1 * randn(size(x, 2), 1); % gaussian
s5 = (sawtooth(x, 0.75)+ 1) * 0.5; % sawtooth
One condition for ICA to be successful is that at most one signal is Gaussian, and I've observed this in my signal generation.
However, another condition is that all signals are statistically independent.
All I know is that this means that, given two signals A & B, knowing one signal does not give any information with regards to the other, i.e.: P(A|B) = P(A) where P is the probability.
Now my question is this: Are my signals statistically independent? Is there any way I can determine this? Perhaps some property that must be observed?
Another thing I've noticed is that when I calculate the eigenvalues of the covariance matrix (calculated for the matrix containing the mixed signals), the eigenspectrum seems to show that there is only one (main) principal component. What does this really mean? Shouldn't there be 5, since I have 5 (supposedly) independent signals?
For example, when using the following mixing matrix:
A =
0.2000 0.4267 0.2133 0.1067 0.0533
0.2909 0.2000 0.2909 0.1455 0.0727
0.1333 0.2667 0.2000 0.2667 0.1333
0.0727 0.1455 0.2909 0.2000 0.2909
0.0533 0.1067 0.2133 0.4267 0.2000
The eigenvalues are: 0.0000 0.0005 0.0022 0.0042 0.0345 (only 4!)
When using the identity matrix as the mixing matrix (i.e. the mixed signals are the same as the original ones), the eigenspectrum is: 0.0103 0.0199 0.0330 0.0811 0.1762. There still is one value much larger than the rest..
Thank you for your help.
I apologise if the answers to my questions are painfully obvious, but I'm really new to statistics, ICA and Matlab. Thanks again.
EDIT - I have 500 samples of each signal, in the range [0.2, 100], in steps of 0.2, i.e. x = 0:0.1:100.
EDIT - Given the ICA Model: X = As + n (I'm not adding any noise at the moment), but I am referring to the eigenspectrum of the transpose of X, i.e. eig(cov(X')).
Your signals are correlated (not independent). Right off the bat, the sawtooth and the sine are the same period. Tell me the value of one I'll tell you the value of the other, perfect correlation.
If you change up the period of one of them that'll make them more independent.
Also S1 and S2 are kinda correlated.
As for the eigenvalues, first of all your signals are not independent (see above).
Second of all, your filter matrix A is also not well conditioned, spreading out your eigenvalues further.
Even if you were to pipe in five fully independent (iid, yada yada) signals the covariance would be:
E[ A y y' A' ] = E[ A I A' ] = A A'
The eigenvalues of that are:
eig(A*A')
ans =
0.000167972216475
0.025688510850262
0.035666735304024
0.148813869149738
1.042451912479502
So you're really filtering/squishing all the signals down onto one basis function / degree of freedom and of course they'll be hard to recover, whatever method you use.
To find if the signals are mutually independent you could look at the techniques described here In general two random variables are independent if they are orthogonal. This means that: E{s1*s2} = 0 Meaning that the expectation of the random variable s1 multiplied by the random variable s2 is zero. This orthogonality condition is extremely important in statistics and probability and shows up everywhere. Unfortunately it applies to 2 variables at a time. There are multivariable techniques, but none that I would feel comfortable recommending. Another link I dug up was this one, not sure what your application is, but that paper is very well done.
When I calculate the covariance matrix I get:
cov(A) =
0.0619 -0.0284 -0.0002 -0.0028 -0.0010
-0.0284 0.0393 0.0049 0.0007 -0.0026
-0.0002 0.0049 0.1259 0.0001 -0.0682
-0.0028 0.0007 0.0001 0.0099 -0.0012
-0.0010 -0.0026 -0.0682 -0.0012 0.0831
With eigenvectors,V and values D:
[V,D] = eig(cov(A))
V =
-0.0871 0.5534 0.0268 -0.8279 0.0063
-0.0592 0.8264 -0.0007 0.5584 -0.0415
-0.0166 -0.0352 0.5914 -0.0087 -0.8054
-0.9937 -0.0973 -0.0400 0.0382 -0.0050
-0.0343 0.0033 0.8050 0.0364 0.5912
D =
0.0097 0 0 0 0
0 0.0200 0 0 0
0 0 0.0330 0 0
0 0 0 0.0812 0
0 0 0 0 0.1762
Here's my code:
x = transpose(0.2:0.2:100);
s1 = (-x.^2 + 100*x + 500) / 3000; % quadratic
s2 = exp(-x / 10); % -ve exponential
s3 = (sin(x)+ 1) * 0.5; % sine
s4 = 0.5 + 0.1 * randn(length(x), 1); % gaussian
s5 = (sawtooth(x, 0.75)+ 1) * 0.5; % sawtooth
A = [s1 s2 s3 s4 s5];
cov(A)
[V,D] = eig(cov(A))
Let me know if I can help any more, or if I misunderstood.
EDIT Properly referred to eigenvalues and vectors, used 0.2 sampling interval added code.