Mercurial > octave
annotate scripts/sparse/private/__sprand__.m @ 30564:796f54d4ddbf stable
update Octave Project Developers copyright for the new year
In files that have the "Octave Project Developers" copyright notice,
update for 2021.
In all .txi and .texi files except gpl.txi and gpl.texi in the
doc/liboctave and doc/interpreter directories, change the copyright
to "Octave Project Developers", the same as used for other source
files. Update copyright notices for 2022 (not done since 2019). For
gpl.txi and gpl.texi, change the copyright notice to be "Free Software
Foundation, Inc." and leave the date at 2007 only because this file
only contains the text of the GPL, not anything created by the Octave
Project Developers.
Add Paul Thomas to contributors.in.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 28 Dec 2021 18:22:40 -0500 |
parents | 7854d5752dd2 |
children | 5d3faba0342e |
rev | line source |
---|---|
27923
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
1 ######################################################################## |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
2 ## |
30564
796f54d4ddbf
update Octave Project Developers copyright for the new year
John W. Eaton <jwe@octave.org>
parents:
29359
diff
changeset
|
3 ## Copyright (C) 2004-2022 The Octave Project Developers |
27918
b442ec6dda5c
use centralized file for copyright info for individual contributors
John W. Eaton <jwe@octave.org>
parents:
27880
diff
changeset
|
4 ## |
27923
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
5 ## See the file COPYRIGHT.md in the top-level directory of this |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
6 ## distribution or <https://octave.org/copyright/>. |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
7 ## |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
8 ## This file is part of Octave. |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
9 ## |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
23220
diff
changeset
|
10 ## Octave is free software: you can redistribute it and/or modify it |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
11 ## under the terms of the GNU General Public License as published by |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
23220
diff
changeset
|
12 ## the Free Software Foundation, either version 3 of the License, or |
22755
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22323
diff
changeset
|
13 ## (at your option) any later version. |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
14 ## |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
15 ## Octave is distributed in the hope that it will be useful, but |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
16 ## WITHOUT ANY WARRANTY; without even the implied warranty of |
22755
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22323
diff
changeset
|
17 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22323
diff
changeset
|
18 ## GNU General Public License for more details. |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
19 ## |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
20 ## You should have received a copy of the GNU General Public License |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
21 ## along with Octave; see the file COPYING. If not, see |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
23220
diff
changeset
|
22 ## <https://www.gnu.org/licenses/>. |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
23 ## |
27923
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
24 ######################################################################## |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
25 ## |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
26 ## Original version by Paul Kienzle distributed as free software in the |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
27 ## public domain. |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
28 |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
29 ## -*- texinfo -*- |
20852
516bb87ea72e
2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents:
20735
diff
changeset
|
30 ## @deftypefn {} {} __sprand__ (@var{s}, @var{randfun}) |
516bb87ea72e
2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents:
20735
diff
changeset
|
31 ## @deftypefnx {} {} __sprand__ (@var{m}, @var{n}, @var{d}, @var{fcnname}, @var{randfun}) |
516bb87ea72e
2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents:
20735
diff
changeset
|
32 ## @deftypefnx {} {} __sprand__ (@var{m}, @var{n}, @var{d}, @var{rc}, @var{fcnname}, @var{randfun}) |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
33 ## Undocumented internal function. |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
34 ## @end deftypefn |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
35 |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
36 ## Actual implementation of sprand and sprandn happens here. |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
37 |
20399
26bd6008fc9c
maint: Rename __sprand_impl__.m to __sprand__.m
Rik <rik@octave.org>
parents:
20231
diff
changeset
|
38 function S = __sprand__ (varargin) |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
39 |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
40 if (nargin == 2) |
18590 | 41 [m, randfun] = deal (varargin{1:2}); |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
42 [i, j] = find (m); |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
43 [nr, nc] = size (m); |
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
44 S = sparse (i, j, randfun (size (i)), nr, nc); |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
45 else |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
46 if (nargin == 5) |
18590 | 47 [m, n, d, fcnname, randfun] = deal (varargin{:}); |
48 else | |
49 [m, n, d, rc, fcnname, randfun] = deal (varargin{:}); | |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
50 endif |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
51 |
28059
e9d57f6d6353
allow sprand and sprandsym to create empty sparse matrices
John W. Eaton <jwe@octave.org>
parents:
27923
diff
changeset
|
52 if (! (isscalar (m) && m == fix (m) && m >= 0)) |
e9d57f6d6353
allow sprand and sprandsym to create empty sparse matrices
John W. Eaton <jwe@octave.org>
parents:
27923
diff
changeset
|
53 error ("%s: M must be a non-negative integer", fcnname); |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
54 endif |
28059
e9d57f6d6353
allow sprand and sprandsym to create empty sparse matrices
John W. Eaton <jwe@octave.org>
parents:
27923
diff
changeset
|
55 if (! (isscalar (n) && n == fix (n) && n >= 0)) |
e9d57f6d6353
allow sprand and sprandsym to create empty sparse matrices
John W. Eaton <jwe@octave.org>
parents:
27923
diff
changeset
|
56 error ("%s: N must be a non-negative integer", fcnname); |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
57 endif |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
58 if (d < 0 || d > 1) |
18590 | 59 error ("%s: density D must be between 0 and 1", fcnname); |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
60 endif |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
61 |
28059
e9d57f6d6353
allow sprand and sprandsym to create empty sparse matrices
John W. Eaton <jwe@octave.org>
parents:
27923
diff
changeset
|
62 if (m == 0 || n == 0) |
e9d57f6d6353
allow sprand and sprandsym to create empty sparse matrices
John W. Eaton <jwe@octave.org>
parents:
27923
diff
changeset
|
63 S = sparse (m, n); |
e9d57f6d6353
allow sprand and sprandsym to create empty sparse matrices
John W. Eaton <jwe@octave.org>
parents:
27923
diff
changeset
|
64 return; |
e9d57f6d6353
allow sprand and sprandsym to create empty sparse matrices
John W. Eaton <jwe@octave.org>
parents:
27923
diff
changeset
|
65 endif |
e9d57f6d6353
allow sprand and sprandsym to create empty sparse matrices
John W. Eaton <jwe@octave.org>
parents:
27923
diff
changeset
|
66 |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
67 if (nargin == 5) |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
68 mn = m*n; |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
69 k = round (d*mn); |
27880
31b95261c7d2
Backed out changeset 2890a931e647 (bug #47469)
Rik <rik@octave.org>
parents:
27627
diff
changeset
|
70 if (mn > sizemax ()) |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
71 ## randperm will overflow, so use alternative methods |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
72 |
18590 | 73 idx = unique (fix (rand (1.01*k, 1) * mn)) + 1; |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
74 |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
75 ## idx contains random numbers in [1,mn] |
18590 | 76 ## Generate 1% more random values than necessary in order to reduce the |
77 ## probability that there are less than k distinct values; maybe a | |
78 ## better strategy could be used but I don't think it's worth the price. | |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
79 |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
80 ## actual number of entries in S |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
81 k = min (length (idx), k); |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
82 j = floor ((idx(1:k) - 1) / m); |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
83 i = idx(1:k) - j * m; |
20735
418ae0cb752f
Replace ++,-- with in-place operators for performance.
Rik <rik@octave.org>
parents:
20399
diff
changeset
|
84 j += 1; |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
85 else |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
86 idx = randperm (mn, k); |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
87 [i, j] = ind2sub ([m, n], idx); |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
88 endif |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
89 |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
90 S = sparse (i, j, randfun (k, 1), m, n); |
18590 | 91 |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
92 elseif (nargin == 6) |
18590 | 93 ## Create a matrix with specified reciprocal condition number. |
94 | |
95 if (! isscalar (rc) && ! isvector (rc)) | |
96 error ("%s: RC must be a scalar or vector", fcnname); | |
97 endif | |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
98 |
18590 | 99 ## We want to reverse singular valued decomposition A=U*S*V'. |
100 ## First, first S is constructed and then U = U1*U2*..Un and | |
101 ## V' = V1*V2*..Vn are seen as Jacobi rotation matrices with angles and | |
102 ## planes of rotation randomized. Repeatedly apply rotations until the | |
103 ## required density for A is achieved. | |
16779
8fce0ed4894a
Specialize is_empty and numel methods for sparse matrices (debian bug #706376)
David Bateman <dbateman@free.fr>
parents:
14868
diff
changeset
|
104 |
18590 | 105 if (isscalar (rc)) |
106 if (rc < 0 || rc > 1) | |
107 error ("%s: reciprocal condition number RC must be between 0 and 1", fcnname); | |
108 endif | |
109 ## Reciprocal condition number is ratio of smallest SV to largest SV | |
110 ## Generate singular values randomly and sort them to build S | |
111 ## Random singular values in range [rc, 1]. | |
112 v = rand (1, min (m,n)) * (1 - rc) + rc; | |
113 v(1) = 1; | |
114 v(end) = rc; | |
115 v = sort (v, "descend"); | |
116 S = sparse (diag (v, m, n)); | |
117 else | |
118 ## Only the min (m, n) greater singular values from rc vector are used. | |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
119 if (length (rc) > min (m,n)) |
28912
0de38a6ef693
maint: Use Octave convention of space after function name in scripts dir.
Rik <rik@octave.org>
parents:
28059
diff
changeset
|
120 rc = rc(1:min (m, n)); |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
121 endif |
18590 | 122 S = sparse (diag (sort (rc, "descend"), m, n)); |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
123 endif |
13197
6db186dfdeaa
Refactor sprandn/sprand code, move common code to common function (bug #34352)
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
diff
changeset
|
124 |
18590 | 125 Uinit = speye (m); |
126 Vinit = speye (n); | |
127 k = round (d*m*n); | |
128 while (nnz (S) < k) | |
129 if (m > 1) | |
130 ## Construct U randomized rotation matrix | |
131 rot_angleu = 2 * pi * rand (); | |
132 cu = cos (rot_angleu); su = sin (rot_angleu); | |
133 rndtmp = randperm (m, 2); | |
134 i = rndtmp(1); j = rndtmp(2); | |
135 U = Uinit; | |
136 U(i, i) = cu; U(i, j) = -su; | |
137 U(j, i) = su; U(j, j) = cu; | |
138 S = U * S; | |
139 endif | |
140 if (n > 1) | |
141 ## Construct V' randomized rotation matrix | |
142 rot_anglev = 2 * pi * rand (); | |
143 cv = cos (rot_anglev); sv = sin (rot_anglev); | |
144 rndtmp = randperm (n, 2); | |
145 i = rndtmp(1); j = rndtmp(2); | |
146 V = Vinit; | |
147 V(i, i) = cv; V(i, j) = sv; | |
148 V(j, i) = -sv; V(j, j) = cv; | |
20231
83792dd9bcc1
Use in-place operators in m-files where possible.
Rik <rik@octave.org>
parents:
19697
diff
changeset
|
149 S *= V; |
18590 | 150 endif |
18589
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
151 endwhile |
35a5e7740a6d
Added implementation for 4th argument of sprand/sprandn (bug #41839).
Eduardo Ramos (edu159) <eduradical951@gmail.com>
parents:
17744
diff
changeset
|
152 endif |
16779
8fce0ed4894a
Specialize is_empty and numel methods for sparse matrices (debian bug #706376)
David Bateman <dbateman@free.fr>
parents:
14868
diff
changeset
|
153 endif |
8fce0ed4894a
Specialize is_empty and numel methods for sparse matrices (debian bug #706376)
David Bateman <dbateman@free.fr>
parents:
14868
diff
changeset
|
154 |
14868
5d3a684236b0
maint: Use Octave coding conventions for cuddling parentheses in scripts directory
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
155 endfunction |