I'm trying to change a correlation matrix into co-variance matrix...
Importing some data, I found the co-variance (sigma_a)
sigma_a = (sigma_d + (mu_d'+1)*(mu_d+1)).^N - (mu_d'+1).^N *(mu_d+1).^N;
Which returns...
0.1211 0.0231 0.0422 0.0278 0.0411 0.0354 0.0289 0.0366 0.0343 0.0165
0.0231 0.0788 0.0283 0.0242 0.0199 0.0248 0.0219 0.0199 0.0253 0.0140
0.0422 0.0283 0.1282 0.0339 0.0432 0.0366 0.0321 0.0399 0.0420 0.0216
0.0278 0.0242 0.0339 0.0554 0.0261 0.0294 0.0312 0.0269 0.0297 0.0164
0.0411 0.0199 0.0432 0.0261 0.0849 0.0289 0.0271 0.0371 0.0317 0.0173
0.0354 0.0248 0.0366 0.0294 0.0289 0.0728 0.0293 0.0400 0.0339 0.0149
0.0289 0.0219 0.0321 0.0312 0.0271 0.0293 0.0454 0.0276 0.0309 0.0135
0.0366 0.0199 0.0399 0.0269 0.0371 0.0400 0.0276 0.0726 0.0356 0.0162
0.0343 0.0253 0.0420 0.0297 0.0317 0.0339 0.0309 0.0356 0.0715 0.0198
0.0165 0.0140 0.0216 0.0164 0.0173 0.0149 0.0135 0.0162 0.0198 0.0927
Then I found the correlation matrix (rho)
rho = inv(sqrt(diag(diag(sigma_a))))*sigma_a*inv(sqrt(diag(diag(sigma_a))));
Which returns...
1.0000 0.2365 0.3388 0.3396 0.4050 0.3772 0.3897 0.3899 0.3686 0.1556
0.2365 1.0000 0.2812 0.3656 0.2437 0.3274 0.3658 0.2631 0.3377 0.1638
0.3388 0.2812 1.0000 0.4027 0.4141 0.3792 0.4199 0.4133 0.4382 0.1985
0.3396 0.3656 0.4027 1.0000 0.3809 0.4638 0.6221 0.4246 0.4728 0.2295
0.4050 0.2437 0.4141 0.3809 1.0000 0.3681 0.4366 0.4732 0.4068 0.1948
0.3772 0.3274 0.3792 0.4638 0.3681 1.0000 0.5093 0.5499 0.4707 0.1813
0.3897 0.3658 0.4199 0.6221 0.4366 0.5093 1.0000 0.4797 0.5428 0.2079
0.3899 0.2631 0.4133 0.4246 0.4732 0.5499 0.4797 1.0000 0.4936 0.1971
0.3686 0.3377 0.4382 0.4728 0.4068 0.4707 0.5428 0.4936 1.0000 0.2435
0.1556 0.1638 0.1985 0.2295 0.1948 0.1813 0.2079 0.1971 0.2435 1.0000
I know there is the function corrcov() in matlab that finds the correlation matrix... So I tried,
corrcov(sigma_a)
I compared the results and both corrcov(sigma_a) and rho produced the same correlation matrix.
However then I wanted to change all of the pairwise correlations by exactly +0.1. Which I did, with
rho_u = (rho + .1) - .1*eye(10);
And I got the following correlation matrix...
1.0000 0.3365 0.4388 0.4396 0.5050 0.4772 0.4897 0.4899 0.4686 0.2556
0.3365 1.0000 0.3812 0.4656 0.3437 0.4274 0.4658 0.3631 0.4377 0.2638
0.4388 0.3812 1.0000 0.5027 0.5141 0.4792 0.5199 0.5133 0.5382 0.2985
0.4396 0.4656 0.5027 1.0000 0.4809 0.5638 0.7221 0.5246 0.5728 0.3295
0.5050 0.3437 0.5141 0.4809 1.0000 0.4681 0.5366 0.5732 0.5068 0.2948
0.4772 0.4274 0.4792 0.5638 0.4681 1.0000 0.6093 0.6499 0.5707 0.2813
0.4897 0.4658 0.5199 0.7221 0.5366 0.6093 1.0000 0.5797 0.6428 0.3079
0.4899 0.3631 0.5133 0.5246 0.5732 0.6499 0.5797 1.0000 0.5936 0.2971
0.4686 0.4377 0.5382 0.5728 0.5068 0.5707 0.6428 0.5936 1.0000 0.3435
0.2556 0.2638 0.2985 0.3295 0.2948 0.2813 0.3079 0.2971 0.3435 1.0000
However, when I attempt to take the adjusted correlation matrix and make it a co-variance matrix the cov() is not producing the right matrix. I tried...
b = cov(rho_u);
Why is that? Is there another way to do that? Or is there a way to adjust what I did with
rho = inv(sqrt(diag(diag(sigma_a))))*sigma_a*inv(sqrt(diag(diag(sigma_a))));
so that it does the opposite (rho found the correlation matrix) to get the co-varience matrix instead?
Based on my understanding from the answer below, then the co-variance matrix for rho_u would be achieved by, doing...
sigma = sqrt(var(rho_u));
D = diag(sigma);
sigma_u = D*rho_u*D
Is this what was meant? I was little confused by which variables I should take the variance to. I thought that meant rho_u?
The MATLAB function cov is not defined to transform a correlation matrix to covariance matrix, as its documentation says
cov(X), if X is a vector, returns the variance. For matrices, where
each row is an observation, and each column a variable, cov(X) is the
covariance matrix.
So simply feeding the correlation matrix to cov() won't work. What you need to calculate the covariance matrix is the variance of your variables (which you can calculate from your data, but didn't post here)
So in your example using the 10x10 correlation matrix rho you posted and using some random numbers for the the standard deviations
sigma = rand(size(rho(:,1)));
D = diag(sigma); % Make the sigmas appear on the diagonal of an 10x10 matrix
(you have to insert the calculated values from your input data, of course). You can then calculate the covariance matrix by
S = D*rho*D
Related
This is the data, and a badly fitting exp2 fit:
http://oi64.tinypic.com/10e0di0.jpg
It seems easy to fit at first glance, but I have found it difficult to find a custom equation that fits this data. Exp2 and gauss2 are the usual candidates but I couldn't find a combination that work. It is important for me to preserve the monotony of the data, so polynomials make a bad fit, it is also important not to significantly overshoot or undershoot the data at the edges (like the shown exp2 fit). Preserving the sharply increasing middle part is less important.
Any help would be greatly appreciated.
Example data set:
x = 0 0.0200 0.0400 0.0600 0.0800 0.1000 0.1200 0.1400 0.1600 0.1800 0.2000 0.2200 0.2400 0.2600 0.2800 0.3000 0.3200 0.3400 0.3600 0.3800 0.4000 0.4200 0.4400 0.4600 0.4800 0.5000 0.5200 0.5400 0.5600 0.5800 0.6000 0.6200 0.6400 0.6600 0.6800 0.7000 0.7200 0.7400 0.7600 0.7800 0.8000 0.8200 0.8400 0.8600 0.8800 0.9000 0.9200 0.9400 0.9600 0.9800 1.0000
y = 0.0096 0.0093 0.0092 0.0092 0.0094 0.0097 0.0102 0.0107 0.0114 0.0123 0.0132 0.0144 0.0157 0.0171 0.0189 0.0209 0.0232 0.0259 0.0291 0.0328 0.0373 0.0426 0.0491 0.0570 0.0667 0.0789 0.0941 0.1135 0.1383 0.1699 0.2101 0.2605 0.3214 0.3918 0.4682 0.5455 0.6184 0.6834 0.7389 0.7848 0.8221 0.8521 0.8761 0.8954 0.9108 0.9232 0.9332 0.9413 0.9479 0.9533 0.9576
I am trying to classify vehicles in matlab. I need to reduce the dimensionality of the features to eliminate redundancy. Am using pca for this. Unfortunately, the the pca function is not returning the expected results. The output seems truncated and i don't understand why.
summary of this is as follows:
Components_matrix = [Areas_vector MajorAxisLengths_vector MinorAxisLengths_vector Perimeters_vector...
EquivDiameters_vector Extents_vector Orientations_vector Soliditys_vector]
The output is:
Components_matrix =
1.0e+03 *
1.4000 0.1042 0.0220 0.3352 0.0422 0.0003 0.0222 0.0006
2.7690 0.0998 0.0437 0.3973 0.0594 0.0005 0.0234 0.0007
1.7560 0.0853 0.0317 0.2610 0.0473 0.0005 0.0236 0.0008
1.0870 0.0920 0.0258 0.3939 0.0372 0.0003 0.0157 0.0005
0.7270 0.0583 0.0233 0.2451 0.0304 0.0004 0.0093 0.0006
1.2380 0.0624 0.0317 0.2436 0.0397 0.0004 0.0106 0.0007
Then i used the pca function as follows:
[COEFF, SCORE, LATENT] = pca(Components_matrix)
The displayed results are:
COEFF =
0.9984 -0.0533 -0.0057 -0.0177 0.0045
0.0162 0.1810 0.8788 0.0695 -0.3537
0.0099 -0.0218 -0.2809 0.8034 -0.2036
0.0514 0.9817 -0.1739 -0.0016 0.0468
0.0138 -0.0018 0.0616 0.4276 -0.3585
0.0001 -0.0008 -0.0025 0.0215 0.0210
0.0069 0.0158 0.3388 0.4070 0.8380
0.0001 -0.0011 0.0022 0.0198 0.0016
SCORE =
1.0e+03 *
-0.0946 0.0312 0.0184 -0.0014 -0.0009
1.2758 0.0179 -0.0086 -0.0008 0.0001
0.2569 -0.0642 0.0107 0.0016 0.0012
-0.4043 0.1031 -0.0043 0.0015 0.0003
-0.7721 -0.0299 -0.0079 -0.0017 0.0012
-0.2617 -0.0580 -0.0083 0.0008 -0.0020
LATENT =
1.0e+05 *
5.0614
0.0406
0.0014
0.0000
0.0000
I expected for instance COEFF and LATENT to be 8x8 and 8x1 matrices respectively. But that is not what i get. Why is this so and how can the situation be rectified. Kindly help.
Your usage of pca() and Matlab's output are correct. The issue is that you have more dimensions than you have samples, i.e., you only have 6 vehicles but 8 variables. If you have N samples and N or greater variables, the number of principal components there are is only N-1, because further components would not be unique. So COEFF are the eigenvectors of the covariance matrix of the input, and SCORE(:,1) is the first principal component, SCORE(:,2) is the second, etc., of which there are only N-1=5 in total, and LATENT are the eigenvalues of the covariance matrix, or the amount of variance explained by each successive principal component, of which there are, again, only N-1=5.
There is a more detailed discussion of this here.
let us consider following matrix for illustration
A=rand(6,3)
A =
0.3500 0.8308 0.7537
0.1966 0.5853 0.3804
0.2511 0.5497 0.5678
0.6160 0.9172 0.0759
0.4733 0.2858 0.0540
0.3517 0.7572 0.5308
to total we have 6*3=18 element,after apply reshape function
reshape(A,2,9)
ans =
0.3500 0.2511 0.4733 0.8308 0.5497 0.2858 0.7537 0.5678 0.0540
0.1966 0.6160 0.3517 0.5853 0.9172 0.7572 0.3804 0.0759 0.5308
clearly if we look on original array,then we can easily see that rows of these new matrix is same as
B=A(:)'
B =
Columns 1 through 9
0.3500 0.1966 0.2511 0.6160 0.4733 0.3517 0.8308 0.5853 0.5497
Columns 10 through 18
0.9172 0.2858 0.7572 0.7537 0.3804 0.5678 0.0759 0.0540 0.5308
>> B(1:2:18)
ans =
0.3500 0.2511 0.4733 0.8308 0.5497 0.2858 0.7537 0.5678 0.0540
so in reshape(A,m,n) where m*n must be total element,m represent starting form first element in first column,increment in columns until nth element?also when i have tried
reshape(A,3,4)
Error using reshape
To RESHAPE the number of elements must not change.
it gives me error,so whenever i choose n,m must be number of elements in array divided by n right?thanks in advance
Matlab stores its matrices column-wise. This means internally it basically is just one array where all the columns are concatenated. The shape of the matrix is stored seperately.
I don't quite understand your last question, because your matrix A has 18 entries, but you try to reshape it into a matrix with 3*4=12 entries
I hope this helped you
Reshape is for reordering elements as explained in #alex answer (and of course the number of elements must not change!). If you want to resize a matrix, use indexing:
Examples
A = rand(6,6) % Start matrix
A =
0.0113 0.5362 0.3510 0.7220 0.2084 0.8344
0.5013 0.9770 0.5221 0.5743 0.8442 0.8102
0.1214 0.0390 0.9594 0.1385 0.9038 0.6081
0.2480 0.9165 0.1986 0.3692 0.5135 0.6154
0.3631 0.9843 0.3697 0.5964 0.6437 0.6901
0.9978 0.8182 0.1990 0.8273 0.6811 0.2464
Use '[]' to remove lines or columns
A(2:3, :) = [] % This removes 2nd and 3rd lines
A(:, [2 5]) = [] % This further removes 2nd and 5th columns
A =
0.0113 0.3510 0.7220 0.8344
0.2480 0.1986 0.3692 0.6154
0.3631 0.3697 0.5964 0.6901
0.9978 0.1990 0.8273 0.2464
Use indexing for zero padding
AA = zeros(6, 6); % Build larger matrix the size you want ...
AA([1 2 4 6], [2 3 5 6]) = A % Place elements of `A` inside `AA` as you wish ...
AA =
0.0000 0.0113 0.3510 0.0000 0.7220 0.8344
0.0000 0.2480 0.1986 0.0000 0.3692 0.6154
0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.3631 0.3697 0.0000 0.5964 0.6901
0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.9978 0.1990 0.0000 0.8273 0.2464
With indexing you can also play around to create bigger/smaller matrices.
A([4 4 1 1 2 3], end:-1:1)
ans =
0.2464 0.8273 0.1990 0.9978
0.2464 0.8273 0.1990 0.9978
0.8344 0.7220 0.3510 0.0113
0.8344 0.7220 0.3510 0.0113
0.6154 0.3692 0.1986 0.2480
0.6901 0.5964 0.3697 0.3631
I have a 3X3 matrix
S_2 =
0.0001 -0.0004 0.0001
-0.0004 0.0029 -0.0002
0.0001 -0.0002 0.0003
when i apply [R,s] = corrcov(S_2)
it returns a vector with standard deviations sigma in s
R =
1.0000 -0.7834 0.3187
-0.7834 1.0000 -0.2631
0.3187 -0.2631 1.0000
s =
0.0099
0.0538
0.0163
what type calculation does corrcov perform to get the sigma "s" ??
Inspect the source code of corrcov to find out: edit corrcov.m
It turns out its: sigma = sqrt(diag(C)), where C is the input covariance matrix (the diagonal elements represent the variances, whose square roots are the standard deviations).
Remember that the correlation matrix is the covariance matrix normalized by the standard deviations: http://en.wikipedia.org/wiki/Covariance_and_correlation
There is an image X of N*M size row M,column N. There are other 2 images A,B of same size as X. The objective is to shuffle the rows of X with the rows extracted from A and shuffle the columns of X with the columns extracted from B resulting in a totally modified img.
I am stuck at the point where simultaneously this is occuring. I am aware about the colon operator with which the code runs but for a square image. Please help how to go about it.
X=imread('picture.jpg');
[r c]=size(X);
[dummy,rowscrambleIdx]=sort(A,1);
X_shuffled=X;
[dummy,colscrambleIdx]=sort(B,2);
EDIT: The following code works for square image and I want to do similar operation for a rectangular sized image. However, this code does not work for rectangular sized image. I have tried to make the first code follow a similar logic but it does not work for a non-square RGB image having say 256*240*3 size
X=imread('picture.jpg');
[dummy,scrambleIdx]=sort(A(:));
X_shuffled=X;
X_shuffled(:)=A(scrambleIdx);
%now unscrambling
[dummy,unscrambleIdx] = sort(scrambleIdx);
X_recovered=X;
X_recovered(:)=X_shuffled(unscrambleIdx);
Why not use randi to randomly create some number of indicies to pull from A, and some to pull from B?
Example:
m=10;
n=5;
A=rand(m,n)
B=ones(m,n)
%3x1 vector of random ints b/w 1 and 10
index=randi([1 10],3,1);
rand_row = A(index,:);
B(index,:)=rand_row
Then output is:
index =
10
9
4
A =
0.9797 0.1174 0.7303 0.6241 0.2619
0.4389 0.2967 0.4886 0.6791 0.3354
0.1111 0.3188 0.5785 0.3955 0.6797
0.2581 0.4242 0.2373 0.3674 0.1366
0.4087 0.5079 0.4588 0.9880 0.7212
0.5949 0.0855 0.9631 0.0377 0.1068
0.2622 0.2625 0.5468 0.8852 0.6538
0.6028 0.8010 0.5211 0.9133 0.4942
0.7112 0.0292 0.2316 0.7962 0.7791
0.2217 0.9289 0.4889 0.0987 0.7150
B =
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
B =
1.0000 1.0000 1.0000 1.0000 1.0000
1.0000 1.0000 1.0000 1.0000 1.0000
1.0000 1.0000 1.0000 1.0000 1.0000
0.2581 0.4242 0.2373 0.3674 0.1366
1.0000 1.0000 1.0000 1.0000 1.0000
1.0000 1.0000 1.0000 1.0000 1.0000
1.0000 1.0000 1.0000 1.0000 1.0000
1.0000 1.0000 1.0000 1.0000 1.0000
0.7112 0.0292 0.2316 0.7962 0.7791
0.2217 0.9289 0.4889 0.0987 0.7150