annotate src/DLD-FUNCTIONS/spkron.cc @ 7016:93c65f2a5668

[project @ 2007-10-12 06:40:56 by jwe]
author jwe
date Fri, 12 Oct 2007 06:41:26 +0000
parents 49724abe1236
children a1dbe9d80eee
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5323
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
1 /*
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
2
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
3 Copyright (C) 2002 John W. Eaton
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
4 Copyright (C) 2005 David Bateman
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
5
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
6 This file is part of Octave.
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
7
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
8 Octave is free software; you can redistribute it and/or modify it
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
9 under the terms of the GNU General Public License as published by the
7016
93c65f2a5668 [project @ 2007-10-12 06:40:56 by jwe]
jwe
parents: 6678
diff changeset
10 Free Software Foundation; either version 3 of the License, or (at your
93c65f2a5668 [project @ 2007-10-12 06:40:56 by jwe]
jwe
parents: 6678
diff changeset
11 option) any later version.
5323
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
12
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
13 Octave is distributed in the hope that it will be useful, but WITHOUT
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
16 for more details.
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
17
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
7016
93c65f2a5668 [project @ 2007-10-12 06:40:56 by jwe]
jwe
parents: 6678
diff changeset
19 along with Octave; see the file COPYING. If not, see
93c65f2a5668 [project @ 2007-10-12 06:40:56 by jwe]
jwe
parents: 6678
diff changeset
20 <http://www.gnu.org/licenses/>.
5323
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
21
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
22 */
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
23
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
24 // Author: Paul Kienzle <pkienzle@users.sf.net>
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
25
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
26 #ifdef HAVE_CONFIG_H
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
27 #include <config.h>
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
28 #endif
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
29
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
30 #include "dSparse.h"
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
31 #include "CSparse.h"
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
32 #include "quit.h"
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
33
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
34 #include "defun-dld.h"
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
35 #include "error.h"
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
36 #include "oct-obj.h"
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
37
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
38 #if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
39 extern void
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
40 kron (const Sparse<double>&, const Sparse<double>&, Sparse<double>&);
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
41
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
42 extern void
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
43 kron (const Sparse<Complex>&, const Sparse<Complex>&, Sparse<Complex>&);
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
44 #endif
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
45
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
46 template <class T>
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
47 void
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
48 kron (const Sparse<T>& A, const Sparse<T>& B, Sparse<T>& C)
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
49 {
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
50 octave_idx_type idx = 0;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
51 C = Sparse<T> (A.rows () * B.rows (), A.columns () * B.columns (),
5604
2857357f9d3c [project @ 2006-01-31 18:22:59 by jwe]
jwe
parents: 5534
diff changeset
52 A.nzmax () * B.nzmax ());
5323
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
53
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
54 C.cidx (0) = 0;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
55
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
56 for (octave_idx_type Aj = 0; Aj < A.columns (); Aj++)
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
57 for (octave_idx_type Bj = 0; Bj < B.columns (); Bj++)
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
58 {
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
59 for (octave_idx_type Ai = A.cidx (Aj); Ai < A.cidx (Aj+1); Ai++)
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
60 {
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
61 octave_idx_type Ci = A.ridx(Ai) * B.rows ();
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
62 const T v = A.data (Ai);
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
63
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
64 for (octave_idx_type Bi = B.cidx (Bj); Bi < B.cidx (Bj+1); Bi++)
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
65 {
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
66 OCTAVE_QUIT;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
67 C.data (idx) = v * B.data (Bi);
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
68 C.ridx (idx++) = Ci + B.ridx (Bi);
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
69 }
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
70 }
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
71 C.cidx (Aj * B.columns () + Bj + 1) = idx;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
72 }
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
73 }
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
74
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
75 template void
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
76 kron (const Sparse<double>&, const Sparse<double>&, Sparse<double>&);
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
77
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
78 template void
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
79 kron (const Sparse<Complex>&, const Sparse<Complex>&, Sparse<Complex>&);
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
80
5534
e107161b8ca3 [project @ 2005-11-11 17:44:05 by jwe]
jwe
parents: 5323
diff changeset
81 // PKG_ADD: dispatch ("kron", "spkron", "sparse matrix");
e107161b8ca3 [project @ 2005-11-11 17:44:05 by jwe]
jwe
parents: 5323
diff changeset
82 // PKG_ADD: dispatch ("kron", "spkron", "sparse complex matrix");
e107161b8ca3 [project @ 2005-11-11 17:44:05 by jwe]
jwe
parents: 5323
diff changeset
83 // PKG_ADD: dispatch ("kron", "spkron", "sparse bool matrix");
5323
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
84 DEFUN_DLD (spkron, args, nargout, "-*- texinfo -*-\n\
6678
49724abe1236 [project @ 2007-05-31 19:44:45 by jwe]
jwe
parents: 5989
diff changeset
85 @deftypefn {Loadable Function} {} spkron (@var{a}, @var{b})\n\
5323
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
86 Form the kronecker product of two sparse matrices. This is defined\n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
87 block by block as\n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
88 \n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
89 @example\n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
90 x = [a(i, j) b]\n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
91 @end example\n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
92 \n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
93 For example,\n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
94 \n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
95 @example\n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
96 @group\n\
5989
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
97 kron(speye(3),spdiag([1,2,3]))\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
98 @result{}\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
99 Compressed Column Sparse (rows = 9, cols = 9, nnz = 9)\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
100 \n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
101 (1, 1) -> 1\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
102 (2, 2) -> 2\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
103 (3, 3) -> 3\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
104 (4, 4) -> 1\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
105 (5, 5) -> 2\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
106 (6, 6) -> 3\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
107 (7, 7) -> 1\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
108 (8, 8) -> 2\n\
e049385342f6 [project @ 2006-09-14 02:10:46 by jwe]
jwe
parents: 5823
diff changeset
109 (9, 9) -> 3\n\
5323
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
110 @end group\n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
111 @end example\n\
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
112 @end deftypefn")
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
113 {
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
114 octave_value_list retval;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
115
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
116 int nargin = args.length ();
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
117
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
118 if (nargin != 2 || nargout > 1)
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
119 {
5823
080c08b192d8 [project @ 2006-05-19 05:32:17 by jwe]
jwe
parents: 5610
diff changeset
120 print_usage ();
5323
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
121 }
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
122 else if (args(0).is_complex_type () || args(1).is_complex_type ())
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
123 {
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
124 SparseComplexMatrix a (args(0).sparse_complex_matrix_value());
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
125 SparseComplexMatrix b (args(1).sparse_complex_matrix_value());
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
126
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
127 if (! error_state)
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
128 {
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
129 SparseComplexMatrix c;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
130 kron (a, b, c);
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
131 retval(0) = c;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
132 }
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
133 }
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
134 else
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
135 {
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
136 SparseMatrix a (args(0).sparse_matrix_value ());
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
137 SparseMatrix b (args(1).sparse_matrix_value ());
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
138
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
139 if (! error_state)
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
140 {
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
141 SparseMatrix c;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
142 kron (a, b, c);
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
143 retval (0) = c;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
144 }
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
145 }
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
146
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
147 return retval;
e5a68648db9c [project @ 2005-04-29 13:10:36 by dbateman]
dbateman
parents:
diff changeset
148 }
5610
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
149
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
150 /*
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
151
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
152 %!assert(spkron(spdiag([1,2,3]),spdiag([1,2,3])),sparse(kron(diag([1,2,3]),diag([1,2,3]))))
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
153 %!assert(spkron(spdiag([1i,2,3]),spdiag([1i,2,3])),sparse(kron(diag([1i,2,3]),diag([1i,2,3]))))
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
154
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
155 */
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
156
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
157 /*
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
158 ;;; Local Variables: ***
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
159 ;;; mode: C++ ***
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
160 ;;; End: ***
9761b7d24e9e [project @ 2006-02-09 09:12:02 by dbateman]
dbateman
parents: 5604
diff changeset
161 */