generalized convolution of inputs (U) with basis set (bf) FORMAT [X,Xname,Fc] = spm_Volterra(U,bf,V); U - input structure array bf - Basis functions V - [1 or 2] order of Volterra expansion [default = 1] X - Design Matrix Xname - names of regressors [columns] in X Fc(j).i - indices pertaining to input i (and interactions) Fc(j).name - names pertaining to input i (and interactions) ___________________________________________________________________________ For first order expansions spm_Volterra simply convolves the causes (e.g. stick functions) in U.u by the basis functions in bf to create a design matrix X. For second order expansions new entries appear in ind, bf and name that correspond to the interaction among the orginal causes. The basis functions for these efects are two dimensional and are used to assemble the second order kernel in spm_graph.m. Second order effects are computed for only the first column of U.u. ___________________________________________________________________________ @(#)spm_Volterra.m 2.3 Karl Friston 02/04/19
0001 function [X,Xname,Fc] = spm_Volterra(U,bf,V) 0002 % generalized convolution of inputs (U) with basis set (bf) 0003 % FORMAT [X,Xname,Fc] = spm_Volterra(U,bf,V); 0004 % U - input structure array 0005 % bf - Basis functions 0006 % V - [1 or 2] order of Volterra expansion [default = 1] 0007 % 0008 % X - Design Matrix 0009 % Xname - names of regressors [columns] in X 0010 % Fc(j).i - indices pertaining to input i (and interactions) 0011 % Fc(j).name - names pertaining to input i (and interactions) 0012 %___________________________________________________________________________ 0013 % 0014 % For first order expansions spm_Volterra simply convolves the causes 0015 % (e.g. stick functions) in U.u by the basis functions in bf to create 0016 % a design matrix X. For second order expansions new entries appear 0017 % in ind, bf and name that correspond to the interaction among the 0018 % orginal causes. The basis functions for these efects are two dimensional 0019 % and are used to assemble the second order kernel in spm_graph.m. 0020 % Second order effects are computed for only the first column of U.u. 0021 %___________________________________________________________________________ 0022 % @(#)spm_Volterra.m 2.3 Karl Friston 02/04/19 0023 0024 0025 % 1st order terms 0026 %--------------------------------------------------------------------------- 0027 if nargin == 2, V == 1; end 0028 0029 % Construct X 0030 %=========================================================================== 0031 0032 % 1st order terms 0033 %--------------------------------------------------------------------------- 0034 X = []; 0035 Xname = {}; 0036 ind = {}; 0037 Uname = {}; 0038 Fc = {}; 0039 for i = 1:length(U) 0040 ind = []; 0041 for k = 1:size(U(i).u,2) 0042 for p = 1:size(bf,2) 0043 x = U(i).u(:,k); 0044 d = 1:length(x); 0045 x = conv(full(x),bf(:,p)); 0046 x = x(d); 0047 X = [X x]; 0048 0049 % indices and regressor names 0050 %----------------------------------------------------------- 0051 str = sprintf('%s*bf(%i)',U(i).name{k},p); 0052 Xname{end + 1} = str; 0053 ind(end + 1) = size(X,2); 0054 end 0055 end 0056 Fc(end + 1).i = ind; 0057 Fc(end).name = U(i).name{1}; 0058 end 0059 0060 % return if first order 0061 %--------------------------------------------------------------------------- 0062 if V == 1, return, end 0063 0064 % 2nd order terms 0065 %--------------------------------------------------------------------------- 0066 for i = 1:length(U) 0067 for j = i:length(U) 0068 ind = []; 0069 for p = 1:size(bf,2) 0070 for q = 1:size(bf,2) 0071 x = U(i).u(:,1); 0072 y = U(j).u(:,1); 0073 x = conv(full(x),bf(:,p)); 0074 y = conv(full(y),bf(:,q)); 0075 x = x(d); 0076 y = y(d); 0077 X = [X x.*y]; 0078 0079 % indices and regressor names 0080 %----------------------------------------------------------- 0081 str = sprintf('%s*bf(%i)x%s*bf(%i)',... 0082 U(i).name{1},p,... 0083 U(j).name{1},q); 0084 Xname{end + 1} = str; 0085 ind(end + 1) = size(X,2); 0086 end 0087 end 0088 Fc(end + 1).i = ind; 0089 Fc(end).name = [U(i).name{1} 'x' U(j).name{1}]; 0090 end 0091 end