]> Creatis software - CreaPhase.git/blob - blksparse.m
c418a52fcd882601087d6d524697e9cb22b1fac1
[CreaPhase.git] / blksparse.m
1 ## Copyright (C) 2010 VZLU Prague
2 ## 
3 ## This program is free software; you can redistribute it and/or modify
4 ## it under the terms of the GNU General Public License as published by
5 ## the Free Software Foundation; either version 3 of the License, or
6 ## (at your option) any later version.
7 ## 
8 ## This program is distributed in the hope that it will be useful,
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 ## GNU General Public License for more details.
12 ## 
13 ## You should have received a copy of the GNU General Public License
14 ## along with Octave; see the file COPYING.  If not, see
15 ## <http://www.gnu.org/licenses/>.
16
17 ## -*- texinfo -*-
18 ## @deftypefn{Function File} {@var{s} =} blksparse (@var{i}, @var{j}, @var{sv})
19 ## @deftypefnx{Function File} {@var{s} =} blksparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n})
20 ## @deftypefnx{Function File} {@var{s} =} blksparse (@dots{}, @var{mode})
21 ##
22 ## Construct a block sparse matrix. The meaning of arguments is analogous to the
23 ## built-in @code{sparse} function, except that @var{i}, @var{j} are indices of
24 ## blocks rather than elements, and @var{sv} is a 3-dimensional array, the first two
25 ## dimensions determining the block size. Optionally, @var{m} and @var{n} can be
26 ## specified as the true block dimensions; if not, the maximum values of @var{i}, @var{j}
27 ## are taken instead. The resulting sparse matrix has the size 
28 ##
29 ## @example
30 ##   [@var{m}*@var{p}, @var{n}*@var{q}]
31 ## @end example
32 ##
33 ## where 
34 ##
35 ## @example
36 ##   @var{p} = size (@var{sv}, 1)
37 ##   @var{q} = size (@var{sv}, 2)
38 ## @end example
39 ##
40 ## The blocks are located so that
41 ##
42 ## @example 
43 ## @var{s}(@var{i}(k):@var{i}(k)+@var{p}-1, @var{j}(k):@var{j}(K)+@var{q}-1) = @var{sv}(:,:,k)
44 ## @end example
45 ##
46 ## Multiple blocks corresponding to the same pair of indices are summed, unless
47 ## @var{mode} is "unique", in which case the last of them is used.
48 ## @end deftypefn
49
50 function s = blksparse (i, j, sv, m = 0, n = 0, mode)
51   persistent chkver = check_version ();
52   if (nargin == 0)
53     i = j = zeros (0, 1);
54     sv = zeros (1, 1, 0);
55     s = class (struct ("i", i, "j", j, "sv", sv, "siz", [0, 0], "bsiz", [1, 1]), "blksparse");
56     return
57   endif
58
59   if (nargin < 3 || nargin > 6)
60     print_usage ();
61   endif
62
63   if (! isvector (i) || ! isvector (j))
64     error ("blksparse: i, j must be vectors");
65   elseif (ndims (sv) != 3)
66     error ("blksparse: sv must be a 3D array");
67   endif
68
69   if (nargin == 4 && ischar (m))
70     mode = m;
71     m = 0;
72   elseif (nargin < 6)
73     mode = "sum";
74   endif
75
76   if (strcmp (mode, "unique"))
77     summation = false;
78   elseif (strcmp (mode, "sum") || strcmp (mode, "summation"))
79     summation = true;
80   else
81     error ("blksparse: invalid mode: %s", mode);
82   endif
83
84   if (m == 0)
85     m = max (i);
86   endif
87   if (n == 0)
88     n = max (j);
89   endif
90
91   siz = [m, n];
92   ji = [j(:), i(:)];
93
94   [ji, fidx, ridx] = unique (ji, "rows");
95   j = ji(:,1);
96   i = ji(:,2);
97
98   if (summation)
99     sv = accumdim (ridx, sv, 3, rows (ji));
100   else
101     sv = sv(:,:,fidx);
102   endif
103
104   s = struct ("i", i, "j", j, "sv", sv, "siz", siz, "bsiz", size (sv)(1:2));
105   s = class (s, "blksparse");
106
107 endfunction
108
109 function ok = check_version ()
110   ok = compare_versions (version, "3.3.51", ">=");
111   if (! ok)
112     error ("blksparse: can only be used with Octave 3.3.51+");
113   endif
114 endfunction