Home > marsbar > @mardo_5 > private > pr_spm_diff.m

pr_spm_diff

PURPOSE ^

matrix high-order differentials

SYNOPSIS ^

function [J] = pr_spm_diff(varargin)

DESCRIPTION ^

 matrix high-order differentials
 FORMAT [dfdx] = pr_spm_diff(f,x,...,n)

 f      - [inline] function f(x{1},...)
 x      - input argument[s]
 n      - arguments to differentiate w.r.t.

 dfdx          - df/dx{i}                     ; n =  i
 dfdx{p}...{q} - df/dx{i}dx{j}(q)...dx{k}(p)  ; n = [i j ... k]

 - a cunning recursive routine
__________________________________________________________________________
 Copyright (C) 2005 Wellcome Department of Imaging Neuroscience

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [J] = pr_spm_diff(varargin)
0002 % matrix high-order differentials
0003 % FORMAT [dfdx] = pr_spm_diff(f,x,...,n)
0004 %
0005 % f      - [inline] function f(x{1},...)
0006 % x      - input argument[s]
0007 % n      - arguments to differentiate w.r.t.
0008 %
0009 % dfdx          - df/dx{i}                     ; n =  i
0010 % dfdx{p}...{q} - df/dx{i}dx{j}(q)...dx{k}(p)  ; n = [i j ... k]
0011 %
0012 % - a cunning recursive routine
0013 %__________________________________________________________________________
0014 % Copyright (C) 2005 Wellcome Department of Imaging Neuroscience
0015 
0016 % Karl Friston
0017 % $Id: spm_diff.m 417 2006-02-01 13:50:14Z karl $
0018 
0019 % create inline object
0020 %--------------------------------------------------------------------------
0021 f     = fcnchk(varargin{1});
0022 x     = varargin(2:(end - 1));
0023 n     = varargin{end};
0024 m     = n(end);
0025 xm    = pr_spm_vec(x{m});
0026 dx    = exp(-8);
0027 J     = cell(1,length(xm));
0028 
0029 % proceed to derivatives
0030 %==========================================================================
0031 if length(n) == 1
0032 
0033     % dfdx
0034     %----------------------------------------------------------------------
0035     f0    = feval(f,x{:});
0036     for i = 1:length(J)
0037         xi       = x;
0038         xmi      = xm;
0039         xmi(i)   = xmi(i) + dx;
0040         xi{n}    = pr_spm_unvec(xmi,xi{n});
0041         fi       = feval(f,xi{:});
0042         J{i}     = pr_spm_dfdx(fi,f0,dx);
0043     end
0044 
0045 else
0046 
0047     % dfdxdxdx....
0048     %----------------------------------------------------------------------
0049     f0    = pr_spm_diff(f,x{:},n(1:end - 1));
0050     for i = 1:length(J)
0051         xi       = x;
0052         xmi      = xm;
0053         xmi(i)   = xmi(i) + dx;
0054         xi{m}    = pr_spm_unvec(xmi,xi{m});
0055         fi       = pr_spm_diff(f,xi{:},n(1:end - 1));
0056         J{i}     = pr_spm_dfdx(fi,f0,dx);
0057     end
0058     return
0059 
0060 end
0061 
0062 % return numeric array for first order derivatives
0063 %==========================================================================
0064 
0065 % vectorise f
0066 %--------------------------------------------------------------------------
0067 f  = pr_spm_vec(f0);
0068 
0069 % if there are no arguments to differentiate w.r.t. ...
0070 %--------------------------------------------------------------------------
0071 if ~length(xm)
0072     J = sparse(length(f),0);
0073     return
0074 end
0075 
0076 % if there are no arguments to differentiate
0077 %--------------------------------------------------------------------------
0078 if ~length(f)
0079     J = sparse(0,length(xm));
0080     return
0081 end
0082 
0083 % if f is a scalar
0084 %--------------------------------------------------------------------------
0085 if length(f) == 1
0086     J = pr_spm_cat(J);
0087     return
0088 end
0089 
0090 % if x{n} is a scalar
0091 %--------------------------------------------------------------------------
0092 if length(xm) == 1
0093     J = pr_spm_cat(J);
0094     return
0095 end
0096 
0097 % else f and xm are vectors return numeric array
0098 %--------------------------------------------------------------------------
0099 for i = 1:length(J)
0100     J{i} = pr_spm_vec(J{i});
0101 end
0102 J    = pr_spm_cat(J);
0103 return
0104 
0105 function dfdx = pr_spm_dfdx(f,f0,dx)
0106 % cell subtraction
0107 %--------------------------------------------------------------------------
0108 if iscell(f)
0109     dfdx  = f;
0110     for i = 1:length(f(:))
0111         dfdx{i} = pr_spm_dfdx(f{i},f0{i},dx);
0112     end
0113 else
0114     dfdx  = (f - f0)/dx;
0115 end

Generated on Wed 11-May-2022 16:26:09 by m2html © 2003-2019