⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 handwrit.m

📁 手写签名数据
💻 M
📖 第 1 页 / 共 2 页
字号:
%  -----------------------------------------------------------------------
%                 Registered Handwriting Data
%  -----------------------------------------------------------------------

% These data are the X-Y coordinates of 20 replications of writing
% the script "fda".  The subject was Jim Ramsay.  Each replication
% is represented by 1401 coordinate values.  The scripts have been 
% extensively pre-processed.  They have been adjusted to a common
% length that corresponds to 2.3 seconds or 2300 milliseconds, and
% they have already been registered so that important features in
% each script are aligned.
% 
% This analysis is designed to illustrate techniques for working
% with functional data having rather high frequency variation and
% represented by thousands of data points per record.  Comments
% along the way explain the choices of analysis that were made.
% 
% The final result of the analysis is a third order linear 
% differential equation for each coordinate forced by a 
% constant and by time.  The equations are able to reconstruct
% the scripts to a fairly high level of accuracy, and are also
% able to accommodate a substantial amount of the variation in
% the observed scripts across replications.  by contrast, a 
% second order equation was found to be completely inadequate.
% 
% An interesting suprise in the results is the role placed by
% a 120 millisecond cycle such that sharp features such as cusps
% correspond closely to this period.  This 110-120 msec cycle
% seems is usually seen in human movement data involving rapid
% movements, such as speech, juggling and so on.

%  Last modified 17 June 2008

% Add paths to functional data functions and to the data

addpath ('c:\Program Files\matlab\fdaM')
addpath ('c:\Program Files\matlab\fdaM\examples\handwrit')

%  Input the data.  These 20 records have already been
%  normalized to a common time interval of 2300 milliseconds
%  and have beeen also registered so that prominent features
%  occur at the same times across replications.
%  Time will be measured in milliseconds and space in meters.
%  The data will require a small amount of smoothing, since
%  an error of 0.5 mm is characteristic of the OPTOTRAK 3D
%  measurement system used to collect the data.

fid      = fopen('fdareg.dat','rt');
fdaarray = reshape(fscanf(fid,'%f'), [20,2,1401]);
fdaarray = permute(fdaarray,[3,1,2]);
fdaarray = fdaarray/1000;   %  convert spatial unit to meters

%  Set up time values and range.
%  It is best to choose milliseconds as a time scale
%  in order to make the ratio of the time
%  unit to the inter-knot interval not too
%  far from one.  Otherwise, smoothing parameter values
%  may be extremely small or extremely large.

fdatime  = linspace(0, 2300, 1401)';
fdarange = [0, 2300];

%  The basis functions will be B-splines, with a spline 
%  placed at each knot.  One may question whether so many
%  basis functions are required, but this decision is found to 
%  be  essential for stable derivative estimation up to the 
%  third order at and near the boundaries.

%  Order 7 was used to get a smooth third derivative, which
%  requires penalizing the size of the 5th derivative, which
%  in turn requires an order of at least 7.
%  This implies norder + no. of interior knots = 1399 + 7 = 1406 
%  basis functions.  

nbasis   = 1406;
norder   =    7;
fdabasis = create_bspline_basis(fdarange, nbasis, norder);

%  The smoothing parameter value 1e8 was chosen to obtain a
%  fitting error of about 0.5 mm, the known error level in
%  the OPTOTRACK equipment.

fdafd  = fd(zeros(nbasis,20,2), fdabasis);
lambda = 1e9;
fdaPar = fdPar(fdafd, 5, lambda);

%  set up the functional data structure 

[fdafd, df, gcv] = smooth_basis(fdatime, fdaarray, fdaPar);

%  Add suitable names for the dimensions of the data.

fdafd_fdnames{1} = 'Milliseconds';
fdafd_fdnames{2} = 'Replications';
fdafd_fdnames{3} = 'Metres';
fdafd = putnames(fdafd, fdafd_fdnames);

%  display degrees of freedom and total GCV criterion

disp(['degrees of freedom = ',num2str(df)])  %  about 92
totalgcv = sum(sum(gcv));
disp(['total GCV = ',num2str(totalgcv)])  
RMSgcv = sqrt(totalgcv)*1000; % about 0.3 mm
disp(['RMS GCV = ',num2str(RMSgcv)])  

%  plot the fit to the data.  It's good to within plotting
%  accuracy, but the title displays RMSE values

plotfit_fd(fdaarray, fdatime, fdafd);

%  plot all curves

plot(fdafd)

%  compute values of curves and the values of the curve

fdameanfd  = mean(fdafd);
fdamat     = eval_fd(fdatime, fdafd);
fdameanmat = squeeze(eval_fd(fdatime, fdameanfd));

%  Evaluate the three derivatives and their means

D1fdamat = eval_fd(fdatime, fdafd, 1);
D2fdamat = eval_fd(fdatime, fdafd, 2);
D3fdamat = eval_fd(fdatime, fdafd, 3);

D1fdameanmat = eval_fd(fdatime, fdameanfd, 1);
D2fdameanmat = eval_fd(fdatime, fdameanfd, 2);
D3fdameanmat = eval_fd(fdatime, fdameanfd, 3);

%  -----------------------------------------------------
%            Principal Components Analysis
%  -----------------------------------------------------

%  Set up a more compact basis using the df identified in
%  the spline smoothing above.  Use order 6 splines

nbasis92   = 92;
norder92   =  6;
fdabasis92 = create_bspline_basis(fdarange, nbasis92, norder92);

%  set up the functional data structure 

fdafd92 = smooth_basis(fdatime, fdaarray, fdabasis92);
%  Add suitable names for the dimensions of the data.
fdafd92_fdnames{1} = 'Milliseconds';
fdafd92_fdnames{2} = 'Replications';
fdafd92_fdnames{3} = 'Metres';
fdafd92 = putnames(fdafd92, fdafd92_fdnames);

%  principal components analysis

lambda    = 0;
fdPar92   = fdPar(fdabasis92, 4, lambda);
nharm     = 3;
fdapcastr = pca_fd(fdafd92, nharm, fdPar92);

%  plot unrotated harmonics

subplot(1,1,1)
plot_pca(fdapcastr)

%  Varimax rotation

fdarotpcastr = varmx_pca(fdapcastr);

%  plot rotated harmonics

subplot(1,1,1)
plot_pca(fdarotpcastr)

fdameanfd  = mean(fdafd92);
fdameanmat = squeeze(eval_fd(fdatime, fdameanfd));

harmfd  = fdarotpcastr.harmfd;
harmmat = eval_fd(fdatime, harmfd);

nfine = 201;

fdapointtime = linspace(0,2300,nfine)';
fdameanpoint = squeeze(eval_fd(fdapointtime, fdameanfd));
harmpointmat = squeeze(eval_fd(fdapointtime, harmfd));

fac = 0.1;
harmplusmat = zeros(nfine,3,2);
harmminsmat = zeros(nfine,3,2);
for j=1:3
    harmplusmat(:,j,:) = fdameanpoint + fac.*squeeze(harmpointmat(:,j,:));
    harmminsmat(:,j,:) = fdameanpoint - fac.*squeeze(harmpointmat(:,j,:));
end

for j=1:2
%     figure(j)
    subplot(1,2,j)
    phdl = plot(fdameanmat(:,1), fdameanmat(:,2), 'b-');
    set(phdl, 'LineWidth', 2)
%     text(harmplusmat(:,j,1), harmplusmat(:,j,2), '+');
%     text(harmminsmat(:,j,1), harmminsmat(:,j,2), '-');
    hold on
    plot(harmplusmat(:,j,1), harmplusmat(:,j,2), 'b--');
    plot(harmminsmat(:,j,1), harmminsmat(:,j,2), 'b--');
    hold off
    axis('square')
end

%  plot log eigenvalues

fdaharmeigval = fdapcastr.values;
x = ones(16,2);
x(:,2) = reshape((4:19),[16,1]);
y = log10(fdaharmeigval(4:19));
c = x\y;
subplot(1,1,1)
plot(1:19,log10(fdaharmeigval(1:19)),'-o', ...
     1:19, c(1)+ c(2).*(1:19), ':')
xlabel('Eigenvalue Number')
ylabel('Log10 Eigenvalue')

%  plot factor scores

harmscr = fdarotpcastr.harmscr;

plot(harmscr(:,1), harmscr(:,2), 'o')
xlabel('Harmonic I')
ylabel('Harmonic II')

%  -----------------------------------------------------
%  Display the neural clock cycle of 119 milliseconds
%  -----------------------------------------------------

%  Set up motor control clock cycle times at every 
%  119 milliseconds. 

cyclelength = 117;
cycle  = 0:cyclelength:2300;
ncycle = length(cycle);

%  evaluate curves at cycle times

fdamatcycle     = eval_fd(cycle, fdafd);
fdameanmatcycle = squeeze(eval_fd(cycle, fdameanfd));

%  Indices of cycle times corresponding to important features:
%  -- the cusp in "f", 
%  -- the the cusp in "d", 
%  -- the first cusp in "a", 
%  -- the rest after the first cusp in "a", and 
%  -- the second cusp in "a".
%  It is remarkable that these features correspond so closely
%  with clock cycle times!

featureindex   = [3, 5, 7, 10, 13, 16, 19];
fdafeature     = fdamatcycle(featureindex,:,:);
fdameanfeature = fdameanmatcycle(featureindex,:);

%  Plot mean, including both sampling points and fit
%  Points at cycle times are plotted as blue circles, and
%  points at feature times are plotted as red circles.

subplot(1,1,1);
lhdl = plot(fdameanmat(:,1),      fdameanmat(:,2),      'b-', ...
            fdameanmatcycle(:,1), fdameanmatcycle(:,2), 'bo', ...
            fdameanfeature(:,1),  fdameanfeature(:,2),  'ro');
set(lhdl, 'LineWidth', 2);
xlabel('\fontsize{16} Metres')
ylabel('\fontsize{16} Metres')
axis([-.040, .040,-.040, .040]);
title('\fontsize{16} Mean script');

%  Plot individual curves, including both sampling points and fit
%  also plot the mean curve in the background.
%  Note how closely individual curve features are tied to the
%  feature cycle times.

subplot(1,1,1);
for i = 1:20
  lhdl = plot(fdamat(:,i,1),        fdamat(:,i,2),        'b-', ...
              fdamatcycle(:,i,1),   fdamatcycle(:,i,2),   'bo', ...
              fdafeature(:,i,1),    fdafeature(:,i,2),    'go', ...
              fdameanmat(:,1),      fdameanmat(:,2),      'r--', ...
              fdameanmatcycle(:,1), fdameanmatcycle(:,2), 'ro', ...
              fdameanfeature(:,1),  fdameanfeature(:,2),  'mo');
  set(lhdl, 'LineWidth', 2);
  xlabel('\fontsize{16} Metres')
  ylabel('\fontsize{16} Metres')
  axis([-.040, .040,-.040, .040]);
  title(['Record ', num2str(i)]);
  pause;
end

%  Plot the individual acceleration records.
%  In these plots, acceleration is displayed as
%  metres per second per second.

%  Cycle and feature times are plotted as vertical
%  dashed lines, un-featured cycle times as red 
%  dotted lines, and cycle times of features as 
%  heavier magenta solid lines.

subplot(1,1,1);
for i=1:20
    lhdl = plot(fdatime, 1e6*D2fdamat(:,i,1), '-', ...
        fdatime, 1e6*D2fdamat(:,i,2), '-', ...
        [0,2300],[0,0], 'r:');
    set(lhdl, 'Linewidth', 2)
    hold on
    plotrange = [-12,12];
    for k=1:length(cycle)
        lhdl = plot([cycle(k),cycle(k)],plotrange,'r:');
        set(lhdl, 'LineWidth', 1')
    end
    for j=1:length(featureindex)
        k = featureindex(j);
        lhdl = plot([cycle(k),cycle(k)],plotrange,'m-');
        set(lhdl, 'LineWidth', 2')
    end
    hold off
    xlabel('\fontsize{16} Milliseconds')
    ylabel('\fontsize{16} Meters/msec/msec')
    title(['\fontsize{16} Curve ',num2str(i)])
    legend('X', 'Y')
    axis([0, 2300, -12, 12]);
    pause
end

%  Compute and plot the acceleration magnitudes,  
%  also called the tangential accelerations.  

D2mag  = sqrt(D2fdamat(:,:,1).^2 + D2fdamat(:,:,2).^2);
D2magmean = mean(D2mag,2);

subplot(1,1,1);
plot(fdatime, 1e6*D2mag)
hold on
plotrange = [0,12];
for k=1:length(cycle)
    lhdl = plot([cycle(k),cycle(k)],plotrange,'r:');
    set(lhdl, 'LineWidth', 1')
end
for j=1:length(featureindex)
    k = featureindex(j);
    lhdl = plot([cycle(k),cycle(k)],plotrange,'m-');
    set(lhdl, 'LineWidth', 2')
end
hold off
xlabel('\fontsize{16} Milliseconds')
ylabel('\fontsize{16} Metres/sec/sec')
title('\fontsize{16} Acceleration Magnitude');
axis([0,2300,0,12]);

%  Plot the mean acceleration magnitude as well as
%  those for each curve.
%  Note the two rest cycles, one in "d" and one in "a"

subplot(1,1,1);
lhdl = plot(fdatime, 1e6*D2magmean);
set(lhdl, 'LineWidth', 2')
hold on
plotrange = [0,8];
for k=1:length(cycle)
    lhdl = plot([cycle(k),cycle(k)],plotrange,'r:');
    set(lhdl, 'LineWidth', 1')
end
for j=1:length(featureindex)
    k = featureindex(j);
    lhdl = plot([cycle(k),cycle(k)],plotrange,'m-');
    set(lhdl, 'LineWidth', 2')
end
hold off
xlabel('\fontsize{16} Milliseconds')
ylabel('\fontsize{16} Metres/sec/sec')
title('\fontsize{16} Mean acceleration Magnitude');
axis([0,2300,0,8]);

%  Plot each individual acceleration magnitude, along
%  with the mean magnitude as a green dashed line

subplot(1,1,1)
for i=1:20
    lhdl = plot(fdatime, 1e6*D2mag(:,i), '-', ...
        fdatime, 1e6*D2magmean, '--');
    set(lhdl, 'LineWidth', 2)
    hold on
    plotrange = [0,12];
    for k=1:length(cycle)
        lhdl = plot([cycle(k),cycle(k)],plotrange,'r:');
        set(lhdl, 'LineWidth', 1')
    end
    for j=1:length(featureindex)
        k = featureindex(j);
        lhdl = plot([cycle(k),cycle(k)],plotrange,'m-');
        set(lhdl, 'LineWidth', 2')
    end
    hold off
    xlabel('\fontsize{16} Milliseconds')
    ylabel('\fontsize{16} Metres/sec/sec')
    title(['\fontsize{16} Script ',num2str(i)])
    axis([0,2300,0,12])
    pause
end

%  ------------------------------------------------------------
%                 Principal Differential Analysis 
%  A third order equation forced by a constant and time is
%          estimated for X and Y coordinates separately.
%  Forcing with constant and time is required to allow for 
%  an arbitrary origin and the left-right motion in X.
%  ------------------------------------------------------------

difeorder  = 3;  %  order of equation

%  set up the two forcing functions

%  constant forcing
constbasis = create_constant_basis(fdarange);
constfd    = fd(ones(1,20), constbasis);
ufdcell{1} = constfd;               
% time forcing
linbasis   = create_monomial_basis(fdarange, 2);
lincoef    = zeros(2,20);
lincoef(2,:) = 1;
ufdcell{2} = fd(lincoef, linbasis); 

%  set up the corresponding weight functions

constfd    = fd(1, constbasis);
constfdPar = fdPar(constfd);
awtcell{1} = constfdPar;
awtcell{2} = constfdPar;

%  Define two basis systems for the derivative weight
%  functions.  One for a background analysis used as a
%  baseline and using constant weight functions, and
%  another using 125 basis functions that will be used
%  to generate the equaations.

%  Set the number of basis functions to match the 
%  119 msec clock time estimated above, so that the
%  gap between knots is 11.9 msec.

delta   = 11.9;
breaks  = [0:delta:2300, 2300];
nbreaks = length(breaks);
nwbasis = nbreaks + 2;
wbasis  = create_bspline_basis(fdarange, nwbasis);

%  ------------------------------------------------------------
%                   Analysis for coordinate X
%  ------------------------------------------------------------

%  Define the variable with a reduced basis to save
%  computation time

xbasis = create_bspline_basis(fdarange, 245);
xfdcell{1} = data2fd(squeeze(fdamat(:,:,1)), fdatime, xbasis);

%  Set up the derivative weight functions

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -