Matlab curve fitting toolbox - what custom fitting function? - matlab

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

Related

Matrix being divided by a value unexpectedly

Just working on multiply 2 rows of a matrix and making the answer another row within the same matrix. However when putting the new row in the matrix all of the values are for some reason divided by 1.0e+03.
X = (M(1,1:5) .* M(2,1:5));
M(3,1:5) = X(1,1:5)
disp(X)
Actual Result
X =
1.0e+03 *
0.4000 0.5500 0.7000 0.5000 0.6000
0.0030 0.0005 0.0008 0.0015 0.0050
1.2000 0.2750 0.5250 0.7500 3.0000
Expected Result
400.0000 550.0000 700.0000 500.0000 600.0000
3.0000 0.5000 0.7500 1.5000 5.0000
1200 275 525 750 3000

Changing correlation matrix into covariane matrix Matlab

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

Obsolete syntax warning in dlmread

I'm completely new to Matlab, so I've been tying out the various IO functions to see how they operate. Here I try to construct a matrix from a tab-delimited spreadsheet:
%Matrix test
M = dlmread('MyFile.txt', '\t', 1);
disp(M);
The output:
>> MatrixTest
Warning: Obsolete syntax. C must be specified with R.
> In dlmread (line 91)
In MatrixTest (line 2)
0.3800 0.2900 0.0400 0.2900 -22.2000
0.4600 0.4500 0.0200 0.0700 -22.2500
0.4900 0.1500 0.0200 0.3400 -66.7700
0.1000 0.8100 0.0200 0.0700 -81.7500
0.1200 0.5700 0.0500 0.2600 -49.5000
0.3000 0.6000 0.0300 0.0700 -57.4700
0.4200 0.0900 0.0100 0.4800 -56.3500
0.2600 0.2800 0.2900 0.1700 -79.7900
0.4800 0.0300 0.4000 0.0900 -76.8500
0.2600 0.0100 0.1400 0.5900 -28.6600
0.2900 0.5000 0.1900 0.0200 -21.5700
0.1400 0.8300 0.0200 0.0100 -31.2700
0.0200 0.4700 0.1300 0.3800 -93.1500
0.0400 0.5000 0.3500 0.1100 -16.9500
0.1100 0.0100 0.1300 0.7500 -11.0500
0.2000 0.6700 0.1200 0.0100 -44.7900
0.3900 0.3600 0.1700 0.0800 -18.7300
0.1500 0.3300 0.0600 0.4600 -48.4500
0.3900 0.0800 0.2300 0.3000 -60.6100
0.3400 0.3600 0.2200 0.0800 -33.0800
0.1400 0.7800 0.0200 0.0600 -60.5000
0.3600 0.6300 0.0100 0 -46.6700
0.1600 0.4800 0.0700 0.2900 -38.2800
The code works as expected, but apparently I've used obsolete syntax (or maybe the issue is with the dlmread function?). Anyway, what is the more appropriate way to perform this same operation?
Thanks in advance.
Try using this
%Matrix test
M = dlmread('MyFile.txt', '\t', 1, 0);
disp(M);
Here, for ignoring first column - use:
%Matrix test
M = dlmread('MyFile.txt', '\t', 1, 1);
disp(M);
Thanks

Indexing inside a nested loop in matlab

I would like to create a matrix to hold the result of functions in a nested loop as follow:
list = [0.01; 0.03; 0.1; 0.3; 1; 3; 10; 30];
res = zeros((size(list,1)),(size(list,1)));
for i = list
for j = list
res(i,j)=function(depending on i and j values from the list) goes
here); % This is the part where I need help
end
end
Because list contains real numbers the indexing res(i,j) doesn't work. Cn anyone give me an idea on how to proceed?
Thanks in advance.
All the suggested comments (working with indexes in a nested for) are valid for this answer, I will also recommend use something like this, the operation that you need is something simimlar to apply to a function to de cartesian product of the list so you can work as follow:
>> [X,Y] = meshgrid(list,list);
>> abs(X - Y)
ans =
0 0.0200 0.0900 0.2900 0.9900 2.9900 9.9900 29.9900
0.0200 0 0.0700 0.2700 0.9700 2.9700 9.9700 29.9700
0.0900 0.0700 0 0.2000 0.9000 2.9000 9.9000 29.9000
0.2900 0.2700 0.2000 0 0.7000 2.7000 9.7000 29.7000
0.9900 0.9700 0.9000 0.7000 0 2.0000 9.0000 29.0000
2.9900 2.9700 2.9000 2.7000 2.0000 0 7.0000 27.0000
9.9900 9.9700 9.9000 9.7000 9.0000 7.0000 0 20.0000
29.9900 29.9700 29.9000 29.7000 29.0000 27.0000 20.0000 0

Dimension reduction using PCA in Matlab

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.