Home > SurfStat > random.m

random

PURPOSE ^

Makes a fixed and random effects term into a mixed effects model.

SYNOPSIS ^

function model = random( ran, fix, strran, strfix, ranisvar );

DESCRIPTION ^

Makes a fixed and random effects term into a mixed effects model.

 Usage: model = random( ran [,fix [,strran [,strfix [,ranisvar]]] );

 Internally a random consists of two terms that describe linear models for
 the mean and the variance. The variables for the variance term are 
 symmetric matrices stored as column vectors. If n is the number of rows
 in the mean term, then n^2 is the number of rows in the variance term. 

 ran    = term, or anything that can be converted into a term, for the
          variance. The single variable for the variance term is
          vec(double(ran)*double(ran)'). If ran is a scalar s, then it is 
          vec(identity matrix)*s^2 whose size matches that of the other
          term in a binary operator, and its name is 'Is^2' or 'I' if s=1.
 fix    = term, or anything that can be converted into a term, for the 
          mean, empty if empty or absent. ran and fix must have the same 
          number of rows, except when one is a scalar.
 strran = string for name of ran. If empty or absent, 'ran' is used. If  
          ran is a scalar, then 'I' is used. 
 strfix = cell array of strings for names for the variables in fix. If 
          empty or absent, chosen by term(fix).
 ranisvar = 1 if ran is already a term for the variance. 
 If ran is a random, model=ran. With no arguments, model is empty.

 Let model.mean be the mean term, and model.variance be the variance term.
 The following operators are overloaded for random models m1 and m2:

 m = m1 + m2: m.mean = m1.mean + m2.mean,  and 
              m.variance = m1.variance + m2.variance.

 m = m1 - m2: m.mean = m1.mean - m2.mean,  and 
              m.variance = m1.variance - m2.variance.

 m = m1 * m2: m.mean = m1.mean * m2.mean,  and 
              m.variance = m1.variance * m2.variance +
              m1.variance * sum_{i<=j} random( (m2.mean_i+m2.mean_j)/2 ) +
              m1.variance * sum_{i<j}  random( (m2.mean_i-m2.mean_j)/2 ) +
              sum_{i<=j} random( (m1.mean_i+m1.mean_j)/2 ) * m2.variance +
              sum_{i<j}  random( (m1.mean_i-m1.mean_j)/2 ) * m2.variance,

              where _i indicates variable i. m_.mean_i is divided by its 
              maximum absolute value so the variables have comparable 
              size, and the factor of 1/2 produces nicer printout. 
              These last four extra sums are equivalent to 

              sum_{i<=j} vec( m1.mean_i * m1.mean_j' ) * m2.variance +
              sum_{i<=j} vec( m2.mean_i * m2.mean_j' ) * m1.variance,

              which allow for an interaction between fixed effects and 
              random effects with arbitrary variance matrices that is
              invariant to any linear transformation of the fixed effects.
              The advantage of the former parameterisation is that if its
              coefficients are positive then the variance matrix of the
              observations is positive definite. The reason is that
              element-wise products of positive definite matrices are
              positive definite. However enforcing positivity has two bad
              side effects: we lose invariance to any linear
              transformation of the fixed effects, and it restricts the
              range of positive definite matrices in the model.
              Specifically, if r is the correlation between two fixed
              effects (crossed with a random effect) with standard
              deviations sd1<=sd2, then |r|<=sd1/sd2. In other words, if
              the sd's are very different, then the correlaton can't be
              too big. 

 m = m1 ^ k:  product of m1 with itself, k times. 

 Algebra: commutative, associative and distributive rules for random a,b,c
    a + b = b + a
    a * b = b * a
    (a + b) + c = a + (b + c)
    (a * b) * c = a * (b * c)
    (a + b) * c = a * c + b * c   only if a,b,c are purely fixed or random
    a + 0 = a
    a * 1 = a
    a * 0 = 0
 However note that 
    a + b - c =/= a + (b - c) =/= a - c + b
 If t1,t2 are terms:
    random(t1 * t2)  =  random(t1) * random(t2), but
    random(t1 + t2) =/= random(t1) + random(t2), since the LHS is one term

 The following functions are overloaded for random model:
 char(model)    = [char(model.mean), char(model.variance)].
 double(model)  = [double(model.mean), double(model.variance)].
 size(model)    = [size(model.mean), size(model.variance)].
 isempty(model) = 1 if model is empty and 0 if not.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function model = random( ran, fix, strran, strfix, ranisvar );
0002 
0003 %Makes a fixed and random effects term into a mixed effects model.
0004 %
0005 % Usage: model = random( ran [,fix [,strran [,strfix [,ranisvar]]] );
0006 %
0007 % Internally a random consists of two terms that describe linear models for
0008 % the mean and the variance. The variables for the variance term are
0009 % symmetric matrices stored as column vectors. If n is the number of rows
0010 % in the mean term, then n^2 is the number of rows in the variance term.
0011 %
0012 % ran    = term, or anything that can be converted into a term, for the
0013 %          variance. The single variable for the variance term is
0014 %          vec(double(ran)*double(ran)'). If ran is a scalar s, then it is
0015 %          vec(identity matrix)*s^2 whose size matches that of the other
0016 %          term in a binary operator, and its name is 'Is^2' or 'I' if s=1.
0017 % fix    = term, or anything that can be converted into a term, for the
0018 %          mean, empty if empty or absent. ran and fix must have the same
0019 %          number of rows, except when one is a scalar.
0020 % strran = string for name of ran. If empty or absent, 'ran' is used. If
0021 %          ran is a scalar, then 'I' is used.
0022 % strfix = cell array of strings for names for the variables in fix. If
0023 %          empty or absent, chosen by term(fix).
0024 % ranisvar = 1 if ran is already a term for the variance.
0025 % If ran is a random, model=ran. With no arguments, model is empty.
0026 %
0027 % Let model.mean be the mean term, and model.variance be the variance term.
0028 % The following operators are overloaded for random models m1 and m2:
0029 %
0030 % m = m1 + m2: m.mean = m1.mean + m2.mean,  and
0031 %              m.variance = m1.variance + m2.variance.
0032 %
0033 % m = m1 - m2: m.mean = m1.mean - m2.mean,  and
0034 %              m.variance = m1.variance - m2.variance.
0035 %
0036 % m = m1 * m2: m.mean = m1.mean * m2.mean,  and
0037 %              m.variance = m1.variance * m2.variance +
0038 %              m1.variance * sum_{i<=j} random( (m2.mean_i+m2.mean_j)/2 ) +
0039 %              m1.variance * sum_{i<j}  random( (m2.mean_i-m2.mean_j)/2 ) +
0040 %              sum_{i<=j} random( (m1.mean_i+m1.mean_j)/2 ) * m2.variance +
0041 %              sum_{i<j}  random( (m1.mean_i-m1.mean_j)/2 ) * m2.variance,
0042 %
0043 %              where _i indicates variable i. m_.mean_i is divided by its
0044 %              maximum absolute value so the variables have comparable
0045 %              size, and the factor of 1/2 produces nicer printout.
0046 %              These last four extra sums are equivalent to
0047 %
0048 %              sum_{i<=j} vec( m1.mean_i * m1.mean_j' ) * m2.variance +
0049 %              sum_{i<=j} vec( m2.mean_i * m2.mean_j' ) * m1.variance,
0050 %
0051 %              which allow for an interaction between fixed effects and
0052 %              random effects with arbitrary variance matrices that is
0053 %              invariant to any linear transformation of the fixed effects.
0054 %              The advantage of the former parameterisation is that if its
0055 %              coefficients are positive then the variance matrix of the
0056 %              observations is positive definite. The reason is that
0057 %              element-wise products of positive definite matrices are
0058 %              positive definite. However enforcing positivity has two bad
0059 %              side effects: we lose invariance to any linear
0060 %              transformation of the fixed effects, and it restricts the
0061 %              range of positive definite matrices in the model.
0062 %              Specifically, if r is the correlation between two fixed
0063 %              effects (crossed with a random effect) with standard
0064 %              deviations sd1<=sd2, then |r|<=sd1/sd2. In other words, if
0065 %              the sd's are very different, then the correlaton can't be
0066 %              too big.
0067 %
0068 % m = m1 ^ k:  product of m1 with itself, k times.
0069 %
0070 % Algebra: commutative, associative and distributive rules for random a,b,c
0071 %    a + b = b + a
0072 %    a * b = b * a
0073 %    (a + b) + c = a + (b + c)
0074 %    (a * b) * c = a * (b * c)
0075 %    (a + b) * c = a * c + b * c   only if a,b,c are purely fixed or random
0076 %    a + 0 = a
0077 %    a * 1 = a
0078 %    a * 0 = 0
0079 % However note that
0080 %    a + b - c =/= a + (b - c) =/= a - c + b
0081 % If t1,t2 are terms:
0082 %    random(t1 * t2)  =  random(t1) * random(t2), but
0083 %    random(t1 + t2) =/= random(t1) + random(t2), since the LHS is one term
0084 %
0085 % The following functions are overloaded for random model:
0086 % char(model)    = [char(model.mean), char(model.variance)].
0087 % double(model)  = [double(model.mean), double(model.variance)].
0088 % size(model)    = [size(model.mean), size(model.variance)].
0089 % isempty(model) = 1 if model is empty and 0 if not.
0090 
0091 if nargin==0
0092     model.mean=[];
0093     model.variance=[];
0094     model=class(model,'random');
0095 elseif isa(ran,'random')
0096     model=ran;
0097 else
0098     model.mean=term;
0099     model.variance=term;
0100     if ~isempty(ran)
0101         if nargin<3 || isempty(strran)
0102             strran=inputname(1);
0103         end
0104         if ~isa(ran,'term')
0105             ran=term(ran,strran);
0106         end
0107         if nargin==5 & ranisvar
0108             model.variance=ran;
0109         else
0110             x=double(ran);
0111             if prod(size(ran))==1
0112                 if x==1
0113                     strran='I';
0114                 else
0115                     strran=['I' num2str(x) '^2'];
0116                 end
0117             end
0118             v=x*x';
0119             model.variance=term(v(:),strran);
0120         end
0121     end
0122     if nargin>=2 && ~isempty(fix)
0123         if nargin<4 || isempty(strfix)
0124             strfix=inputname(2);
0125         end
0126         if ~isa(fix,'term')
0127             fix=term(fix,strfix);
0128         end
0129         model.mean=fix;
0130     end
0131     model=class(model,'random');
0132 end
0133 superiorto('term');
0134 
0135 return
0136 end

Generated on Fri 26-Sep-2008 14:05:29 by m2html © 2003