I have a problem on time-series data clustering using MATLAB
I am trying to use the DTW library below to be my distance measure method
http://www.mathworks.com/matlabcentral/fileexchange/16350-continuous-dynamic-time-warping
TimeData = csvread('testData10.csv',1,0)
Y = pdist(TimeData,#dtw_dist)
Z = linkage(Y,'complete')
dendrogram(Z)
I make a function to fit the format of 'pdist' distance function
function d2 = dtw_dist(XI,XJ)
[dist,D,k,w,rw,tw] = dtw2(XI,XJ,0)
d2 = dist
end
but I get the error message
Error using pdist (line 373)
Error evaluating distance function 'dtw_dist'.
Caused by:
Error using -
Matrix dimensions must agree.
I will be apericiate if anyone helps me
Thanks!
---2015.1.5 update ---
I change my funciton to call dtw to fit the format
and it works
function d2 = dtw_dist(XI,XJ)
result =[];
[m1,n1] = size(XI);
[m2,n2] = size(XJ);
for j=1:m2
result = horzcat(result,dtw(XI,XJ(j,:)));
end
d2=result;
end
It's hard to tell without knowing what dtw2 is. But here's one possible cause: When you call pdist2 with a custom distance function, it should meet the following condition:
A distance function must be of the form
function D2 = DISTFUN(ZI,ZJ)
taking as arguments a 1-by-N vector ZI containing a single observation from X or Y, an M2-by-N matrix ZJ containing multiple observations from X or Y, and returning an M2-by-1 vector of distances D2, whose Jth element is the distance between the observations ZI and ZJ(J,:).
Check if dtw2 fulfills that, and if not, modify it accordingly (or use a loop instead of pdist2).
Related
I am working on an assignment that requires me to use the trapz function in MATLAB in order to evaluate an integral. I believe I have written the code correctly, but the program returns answers that are wildly incorrect. I am attempting to find the integral of e^(-x^2) from 0 to 1.
x = linspace(0,1,2000);
y = zeros(1,2000);
for iCnt = 1:2000
y(iCnt) = e.^(-(x(iCnt)^2));
end
a = trapz(y);
disp(a);
This code currently returns
1.4929e+03
What am I doing incorrectly?
You need to just specify also the x values:
x = linspace(0,1,2000);
y = exp(-x.^2);
a = trapz(x,y)
a =
0.7468
More details:
First of all, in MATLAB you can use vectors to avoid for-loops for performing operation on arrays (vectors). So the whole four lines of code
y = zeros(1,2000);
for iCnt = 1:2000
y(iCnt) = exp(-(x(iCnt)^2));
end
will be translated to one line:
y = exp(-x.^2)
You defined x = linspace(0,1,2000) it means that you need to calculate the integral of the given function in range [0 1]. So there is a mistake in the way you calculate y which returns it to be in range [1 2000] and that is why you got the big number as the result.
In addition, in MATLAB you should use exp there is not function as e in MATLAB.
Also, if you plot the function in the range, you will see that the result makes sense because the whole page has an area of 1x1.
Does anyone have experience with defining an input function as threshold criterion for the qtdecomp function in MATLAB? I tried the following but it did not work:
MyFunc = #(A,threshold) std2(A)>threshold;
S = qtdecomp(Image,MyFunc,threshold);
Somehow, for some threshold values, only the leftmost quarter of the quadtree is divided into new pieces. Could this maybe be an error in the qtdecomp code itself or is there something wrong with my function input?
See the attached image for details. I get this regardless of the threshold I choose:
The problem is that the image is passed to your anonymous function as an m x m x k array representing the image decomposed into k blocks. The function must return a vector of length k, but std2 only looks at the first block and returns a scalar. I'm still trying to come up with a vectorized approach to this, but for now here's a simple loop in a standalone function:
function v = Std2Func(A, threshold)
s = size(A,3);
v = zeros(1,s);
for k = 1:s
v(k) = std2(A(:,:,k))>threshold;
end
end
This iterates through the k planes of the input array, applying std2 to each 2d plane and putting the results into the output vector. Then you just call qtdecomp using a handle to the new function:
S = qtdecomp(Image,#Std2Func,threshold);
So I'm just trying to plot 4 different subplots with variations of the increments. So first would be dx=5, then dx=1, dx=0.1 and dx=0.01 from 0<=x<=20.
I tried to this:
%for dx = 5
x = 0:5:20;
fx = 2*pi*x *sin(x^2)
plot(x,fx)
however I get the error inner matrix elements must agree. Then I tried to do this,
x = 0:5:20
fx = (2*pi).*x.*sin(x.^2)
plot(x,fx)
I get a figure, but I'm not entirely sure if this would be the same as what I am trying to do initially. Is this correct?
The initial error arose since two vectors with the same shape cannot be squared (x^2) nor multiplied (x * sin(x^2)). The addition of the . before the * and ^ operators is correct here since that will perform the operation on the individual elements of the vectors. So yes, this is correct.
Also, bit of a more advanced feature, you can use an anonymous function to aid in the expressions:
fx = #(x) 2*pi.*x.*sin(x.^2); % function of x
x = 0:5:20;
plot(x,fx(x));
hold('on');
x = 0:1:20;
plot(x,fx(x));
hold('off');
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’m currently a Physics student and for several weeks have been compiling data related to ‘Quantum Entanglement’. I’ve now got to a point where I have to plot my data (which should resemble a cos² graph - and does) to a sort of “best fit” cos² graph. The lab script says the following:
A more precise determination of the visibility V (this is basically how 'clean' the data is) follows from the best fit to the measured data using the function:
f(b) = A/2[1-Vsin(b-b(center)/P)]
Granted this probably doesn’t mean much out of context, but essentially A is the amplitude, b is an angle and P is the periodicity. Hence this is also a “wave” like the experimental data I have found.
From this I understand, as previously mentioned, I am making a “best fit” curve. However, I have been told that this isn’t possible with Excel and that the best approach is Matlab.
I know intermediate JavaScript but do not know Matlab and was hoping for some direction.
Is there a tutorial I can read for this? Is it possible for someone to go through it with me? I really have no idea what it entails, so any feed back would be greatly appreciated.
Thanks a lot!
Initial steps
I guess we should begin by getting a representation in Matlab of the function that you're trying to model. A direct translation of your formula looks like this:
function y = targetfunction(A,V,P,bc,b)
y = (A/2) * (1 - V * sin((b-bc) / P));
end
Getting hold of the data
My next step is going to be to generate some data to work with (you'll use your own data, naturally). So here's a function that generates some noisy data. Notice that I've supplied some values for the parameters.
function [y b] = generateData(npoints,noise)
A = 2;
V = 1;
P = 0.7;
bc = 0;
b = 2 * pi * rand(npoints,1);
y = targetfunction(A,V,P,bc,b) + noise * randn(npoints,1);
end
The function rand generates random points on the interval [0,1], and I multiplied those by 2*pi to get points randomly on the interval [0, 2*pi]. I then applied the target function at those points, and added a bit of noise (the function randn generates normally distributed random variables).
Fitting parameters
The most complicated function is the one that fits a model to your data. For this I use the function fminunc, which does unconstrained minimization. The routine looks like this:
function [A V P bc] = bestfit(y,b)
x0(1) = 1; %# A
x0(2) = 1; %# V
x0(3) = 0.5; %# P
x0(4) = 0; %# bc
f = #(x) norm(y - targetfunction(x(1),x(2),x(3),x(4),b));
x = fminunc(f,x0);
A = x(1);
V = x(2);
P = x(3);
bc = x(4);
end
Let's go through line by line. First, I define the function f that I want to minimize. This isn't too hard. To minimize a function in Matlab, it needs to take a single vector as a parameter. Therefore we have to pack our four parameters into a vector, which I do in the first four lines. I used values that are close, but not the same, as the ones that I used to generate the data.
Then I define the function I want to minimize. It takes a single argument x, which it unpacks and feeds to the targetfunction, along with the points b in our dataset. Hopefully these are close to y. We measure how far they are from y by subtracting from y and applying the function norm, which squares every component, adds them up and takes the square root (i.e. it computes the root mean square error).
Then I call fminunc with our function to be minimized, and the initial guess for the parameters. This uses an internal routine to find the closest match for each of the parameters, and returns them in the vector x.
Finally, I unpack the parameters from the vector x.
Putting it all together
We now have all the components we need, so we just want one final function to tie them together. Here it is:
function master
%# Generate some data (you should read in your own data here)
[f b] = generateData(1000,1);
%# Find the best fitting parameters
[A V P bc] = bestfit(f,b);
%# Print them to the screen
fprintf('A = %f\n',A)
fprintf('V = %f\n',V)
fprintf('P = %f\n',P)
fprintf('bc = %f\n',bc)
%# Make plots of the data and the function we have fitted
plot(b,f,'.');
hold on
plot(sort(b),targetfunction(A,V,P,bc,sort(b)),'r','LineWidth',2)
end
If I run this function, I see this being printed to the screen:
>> master
Local minimum found.
Optimization completed because the size of the gradient is less than
the default value of the function tolerance.
A = 1.991727
V = 0.979819
P = 0.695265
bc = 0.067431
And the following plot appears:
That fit looks good enough to me. Let me know if you have any questions about anything I've done here.
I am a bit surprised as you mention f(a) and your function does not contain an a, but in general, suppose you want to plot f(x) = cos(x)^2
First determine for which values of x you want to make a plot, for example
xmin = 0;
stepsize = 1/100;
xmax = 6.5;
x = xmin:stepsize:xmax;
y = cos(x).^2;
plot(x,y)
However, note that this approach works just as well in excel, you just have to do some work to get your x values and function in the right cells.