]> Creatis software - CreaPhase.git/blob - octave_packages/m/linear-algebra/duplication_matrix.m
update packages
[CreaPhase.git] / octave_packages / m / linear-algebra / duplication_matrix.m
1 ## Copyright (C) 1995-2012 Kurt Hornik
2 ##
3 ## This file is part of Octave.
4 ##
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
9 ##
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 ## General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING.  If not, see
17 ## <http://www.gnu.org/licenses/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {} duplication_matrix (@var{n})
21 ## Return the duplication matrix
22 ## @tex
23 ##  $D_n$
24 ## @end tex
25 ## @ifnottex
26 ##  @math{Dn}
27 ## @end ifnottex
28 ##  which is the unique
29 ## @tex
30 ##  $n^2 \times n(n+1)/2$
31 ## @end tex
32 ## @ifnottex
33 ##  @math{n^2} by @math{n*(n+1)/2}
34 ## @end ifnottex
35 ##  matrix such that
36 ## @tex
37 ##  $D_n * {\rm vech} (A) = {\rm vec} (A)$
38 ## @end tex
39 ## @ifnottex
40 ##  @math{Dn vech (A) = vec (A)}
41 ## @end ifnottex
42 ##  for all symmetric
43 ## @tex
44 ##  $n \times n$
45 ## @end tex
46 ## @ifnottex
47 ##  @math{n} by @math{n}
48 ## @end ifnottex
49 ##  matrices
50 ## @tex
51 ##  $A$.
52 ## @end tex
53 ## @ifnottex
54 ##  @math{A}.
55 ## @end ifnottex
56 ##
57 ## See Magnus and Neudecker (1988), Matrix differential calculus with
58 ## applications in statistics and econometrics.
59 ## @end deftypefn
60
61 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
62 ## Created: 8 May 1995
63 ## Adapged-By: jwe
64
65 function d = duplication_matrix (n)
66
67   if (nargin != 1)
68     print_usage ();
69   endif
70
71   if (! (isscalar (n) && n > 0 && n == fix (n)))
72     error ("duplication_matrix: N must be a positive integer");
73   endif
74
75   d = zeros (n * n, n * (n + 1) / 2);
76
77   ## It is clearly possible to make this a LOT faster!
78   count = 0;
79   for j = 1 : n
80     d ((j - 1) * n + j, count + j) = 1;
81     for i = (j + 1) : n
82       d ((j - 1) * n + i, count + i) = 1;
83       d ((i - 1) * n + j, count + i) = 1;
84     endfor
85     count = count + n - j;
86   endfor
87
88 endfunction
89
90 %!test
91 %! N = 2;
92 %! A = rand(N);
93 %! B = A * A';
94 %! C = A + A';
95 %! D = duplication_matrix (N);
96 %! assert (D * vech (B), vec (B), 1e-6);
97 %! assert (D * vech (C), vec (C), 1e-6);
98
99 %!test
100 %! N = 3;
101 %! A = rand(N);
102 %! B = A * A';
103 %! C = A + A';
104 %! D = duplication_matrix (N);
105 %! assert (D * vech (B), vec (B), 1e-6);
106 %! assert (D * vech (C), vec (C), 1e-6);
107
108 %!test
109 %! N = 4;
110 %! A = rand(N);
111 %! B = A * A';
112 %! C = A + A';
113 %! D = duplication_matrix (N);
114 %! assert (D * vech (B), vec (B), 1e-6);
115 %! assert (D * vech (C), vec (C), 1e-6);
116
117 %!error duplication_matrix ();
118 %!error duplication_matrix (0.5);
119 %!error duplication_matrix (-1);
120 %!error duplication_matrix (ones(1,4));