Mercurial > hg > octave-lyh
annotate scripts/special-matrix/hadamard.m @ 11100:cdf940db26a0
provide mxIsFunctionHandle MEX interface function
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 16 Oct 2010 13:27:18 -0400 |
parents | 693e22af08ae |
children | 1740012184f9 |
rev | line source |
---|---|
8920 | 1 ## Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2004, 2006, 2007, 2009 |
7017 | 2 ## Paul Kienzle |
5827 | 3 ## |
4 ## This file is part of Octave. | |
5 ## | |
6 ## Octave is free software; you can redistribute it and/or modify it | |
7 ## under the terms of the GNU General Public License as published by | |
7016 | 8 ## the Free Software Foundation; either version 3 of the License, or (at |
9 ## your option) any later version. | |
5827 | 10 ## |
11 ## Octave is distributed in the hope that it will be useful, but | |
12 ## WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 ## General Public License for more details. | |
15 ## | |
16 ## You should have received a copy of the GNU General Public License | |
7016 | 17 ## along with Octave; see the file COPYING. If not, see |
18 ## <http://www.gnu.org/licenses/>. | |
5827 | 19 ## |
20 ## Original version by Paul Kienzle distributed as free software in the | |
21 ## public domain. | |
22 | |
23 ## -*- texinfo -*- | |
24 ## @deftypefn {Function File} {} hadamard (@var{n}) | |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
25 ## Construct a Hadamard matrix @var{Hn} of size @var{n}-by-@var{n}. The |
6516 | 26 ## size @var{n} must be of the form @code{2 ^ @var{k} * @var{p}} in which |
9051
1bf0ce0930be
Grammar check TexInfo in all .m files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
27 ## @var{p} is one of 1, 12, 20 or 28. The returned matrix is normalized, |
10791
3140cb7a05a1
Add spellchecker scripts for Octave and run spellcheck of documentation
Rik <octave@nomad.inbox5.com>
parents:
10635
diff
changeset
|
28 ## meaning @code{Hn(:,1) == 1} and @code{Hn(1,:) == 1}. |
5827 | 29 ## |
30 ## Some of the properties of Hadamard matrices are: | |
31 ## | |
32 ## @itemize @bullet | |
33 ## @item | |
34 ## @code{kron (@var{Hm}, @var{Hn})} is a Hadamard matrix of size | |
35 ## @var{m}-by-@var{n}. | |
10821
693e22af08ae
Grammarcheck documentation of m-files
Rik <octave@nomad.inbox5.com>
parents:
10791
diff
changeset
|
36 ## |
5827 | 37 ## @item |
6248 | 38 ## @code{Hn * Hn' == @var{n} * eye (@var{n})}. |
10821
693e22af08ae
Grammarcheck documentation of m-files
Rik <octave@nomad.inbox5.com>
parents:
10791
diff
changeset
|
39 ## |
5827 | 40 ## @item |
41 ## The rows of @var{Hn} are orthogonal. | |
10821
693e22af08ae
Grammarcheck documentation of m-files
Rik <octave@nomad.inbox5.com>
parents:
10791
diff
changeset
|
42 ## |
5827 | 43 ## @item |
9117
efac34f78ea4
minor fix to documentation of hadamard function
Aravindh Krishnamoorthy <aravindh.k.dev@gmail.com>
parents:
9051
diff
changeset
|
44 ## @code{det (@var{A}) <= abs(det (@var{Hn}))} for all @var{A} with |
5827 | 45 ## @code{abs (@var{A} (@var{i}, @var{j})) <= 1}. |
10821
693e22af08ae
Grammarcheck documentation of m-files
Rik <octave@nomad.inbox5.com>
parents:
10791
diff
changeset
|
46 ## |
5827 | 47 ## @item |
48 ## Multiply any row or column by -1 and still have a Hadamard matrix. | |
49 ## @end itemize | |
50 ## | |
51 ## @end deftypefn | |
52 | |
53 | |
54 ## Reference [1] contains a list of Hadamard matrices up to n=256. | |
55 ## See code for h28 in hadamard.m for an example of how to extend | |
56 ## this function for additional p. | |
57 ## | |
58 ## References: | |
59 ## [1] A Library of Hadamard Matrices, N. J. A. Sloane | |
60 ## http://www.research.att.com/~njas/hadamard/ | |
61 | |
62 function h = hadamard (n) | |
63 | |
64 if (nargin != 1) | |
65 print_usage (); | |
66 endif | |
67 | |
8507 | 68 ## Find k if n = 2^k*p. |
5827 | 69 k = 0; |
70 while (n > 1 && floor (n/2) == n/2) | |
71 k++; | |
72 n = n/2; | |
73 endwhile | |
74 | |
8507 | 75 ## Find base hadamard. |
76 ## Except for n=2^k, need a multiple of 4. | |
5827 | 77 if (n != 1) |
78 k -= 2; | |
79 endif | |
80 | |
8507 | 81 ## Trigger error if not a multiple of 4. |
5827 | 82 if (k < 0) |
83 n =- 1; | |
84 endif | |
85 | |
86 switch (n) | |
87 case 1 | |
88 h = 1; | |
89 case 3 | |
90 h = h12 (); | |
91 case 5 | |
92 h = h20 (); | |
93 case 7 | |
94 h = hnormalize (h28 ()); | |
95 otherwise | |
10635
d1978e7364ad
Print name of function in error() string messages.
Rik <octave@nomad.inbox5.com>
parents:
9117
diff
changeset
|
96 error ("hadamard: n must be 2^k*p, for p = 1, 12, 20 or 28"); |
5827 | 97 endswitch |
98 | |
8507 | 99 ## Build H(2^k*n) from kron(H(2^k),H(n)). |
5827 | 100 h2 = [1,1;1,-1]; |
101 while (true) | |
102 if (floor (k/2) != k/2) | |
103 h = kron (h2, h); | |
104 endif | |
105 k = floor (k/2); | |
106 if (k == 0) | |
107 break; | |
108 endif | |
109 h2 = kron (h2, h2); | |
110 endwhile | |
111 endfunction | |
112 | |
113 function h = h12 () | |
8507 | 114 tu = [-1,+1,-1,+1,+1,+1,-1,-1,-1,+1,-1]; |
115 tl = [-1,-1,+1,-1,-1,-1,+1,+1,+1,-1,+1]; | |
116 ## Note: assert (tu(2:end), tl(end:-1:2)). | |
5827 | 117 h = ones (12); |
118 h(2:end,2:end) = toeplitz (tu, tl); | |
119 endfunction | |
120 | |
121 | |
122 function h = h20 () | |
8507 | 123 tu = [+1,-1,-1,+1,+1,+1,+1,-1,+1,-1,+1,-1,-1,-1,-1,+1,+1,-1,-1]; |
124 tl = [+1,-1,-1,+1,+1,-1,-1,-1,-1,+1,-1,+1,-1,+1,+1,+1,+1,-1,-1]; | |
125 ## Note: assert (tu(2:end), tl(end:-1:2)). | |
5827 | 126 h = ones (20); |
127 h(2:end,2:end) = fliplr (toeplitz (tu, tl)); | |
128 endfunction | |
129 | |
130 function h = hnormalize (h) | |
8507 | 131 ## Make sure each row and column starts with +1. |
5827 | 132 h(h(:,1)==-1,:) *= -1; |
133 h(:,h(1,:)==-1) *= -1; | |
134 endfunction | |
135 | |
136 function h = h28 () | |
137 ## Williamson matrix construction from | |
138 ## http://www.research.att.com/~njas/hadamard/had.28.will.txt | |
8507 | 139 s = ["+------++----++-+--+-+--++--"; |
140 "-+-----+++-----+-+--+-+--++-"; | |
141 "--+-----+++---+-+-+----+--++"; | |
142 "---+-----+++---+-+-+-+--+--+"; | |
143 "----+-----+++---+-+-+++--+--"; | |
144 "-----+-----++++--+-+--++--+-"; | |
145 "------++----++-+--+-+--++--+"; | |
146 "--++++-+-------++--+++-+--+-"; | |
147 "---++++-+-----+-++--+-+-+--+"; | |
148 "+---+++--+----++-++--+-+-+--"; | |
149 "++---++---+----++-++--+-+-+-"; | |
150 "+++---+----+----++-++--+-+-+"; | |
151 "++++--------+-+--++-++--+-+-"; | |
152 "-++++--------+++--++--+--+-+"; | |
153 "-+-++-++--++--+--------++++-"; | |
154 "+-+-++--+--++--+--------++++"; | |
155 "-+-+-++--+--++--+----+---+++"; | |
156 "+-+-+-++--+--+---+---++---++"; | |
157 "++-+-+-++--+------+--+++---+"; | |
158 "-++-+-+-++--+------+-++++---"; | |
159 "+-++-+---++--+------+-++++--"; | |
160 "-++--++-+-++-+++----++------"; | |
161 "+-++--++-+-++-+++-----+-----"; | |
162 "++-++---+-+-++-+++-----+----"; | |
163 "-++-++-+-+-+-+--+++-----+---"; | |
164 "--++-++++-+-+----+++-----+--"; | |
165 "+--++-+-++-+-+----+++-----+-"; | |
166 "++--++-+-++-+-+----++------+"]; | |
5901 | 167 ## Without this, the assignment of -1 will not work properly |
168 ## (compatibility forces LHS(idx) = ANY_VAL to keep the LHS logical | |
169 ## instead of widening to a type that can represent ANY_VAL). | |
8507 | 170 h = double (s == "+"); |
5827 | 171 h(!h) = -1; |
172 endfunction | |
173 | |
174 %!assert(hadamard(1),1) | |
175 %!assert(hadamard(2),[1,1;1,-1]) | |
176 %!test | |
177 %! for n=[1,2,4,8,12,24,48,20,28,2^9] | |
178 %! h=hadamard(n); assert(norm(h*h'-n*eye(n)),0); | |
179 %! end |