1 |
aw0a |
1 |
#ifdef __MTX_C_SEEN__ |
2 |
jds |
54 |
/* |
3 |
aw0a |
1 |
* mtx2: Ascend Sparse Matrix Package |
4 |
|
|
* by Benjamin Andrew Allan |
5 |
|
|
* Derived from mtx by Karl Michael Westerberg |
6 |
|
|
* Created: 5/3/90 |
7 |
|
|
* Version: $Revision: 1.9 $ |
8 |
|
|
* Version control file: $RCSfile: mtx_use_only.h,v $ |
9 |
|
|
* Date last modified: $Date: 2000/01/25 02:27:13 $ |
10 |
|
|
* Last modified by: $Author: ballan $ |
11 |
|
|
* |
12 |
|
|
* This file is part of the SLV solver. |
13 |
|
|
* |
14 |
|
|
* Copyright (C) 1996 Benjamin Andrew Allan |
15 |
|
|
* based (loosely) on mtx |
16 |
|
|
* Copyright (C) 1990 Karl Michael Westerberg |
17 |
|
|
* Copyright (C) 1993 Joseph Zaher |
18 |
|
|
* Copyright (C) 1994 Joseph Zaher, Benjamin Andrew Allan |
19 |
|
|
* Copyright (C) 1995 Kirk Andre Abbott, Benjamin Andrew Allan |
20 |
|
|
* |
21 |
|
|
* The SLV solver is free software; you can redistribute |
22 |
|
|
* it and/or modify it under the terms of the GNU General Public License as |
23 |
|
|
* published by the Free Software Foundation; either version 2 of the |
24 |
|
|
* License, or (at your option) any later version. |
25 |
|
|
* |
26 |
|
|
* The SLV solver is distributed in hope that it will be |
27 |
|
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
29 |
|
|
* General Public License for more details. |
30 |
|
|
* |
31 |
|
|
* You should have received a copy of the GNU General Public License along with |
32 |
|
|
* the program; if not, write to the Free Software Foundation, Inc., 675 |
33 |
|
|
* Mass Ave, Cambridge, MA 02139 USA. Check the file named COPYING. |
34 |
|
|
* COPYING is found in ../compiler. |
35 |
|
|
*/ |
36 |
|
|
|
37 |
jds |
54 |
/** @file |
38 |
|
|
* mtx2: Ascend Sparse Matrix Package (Private). |
39 |
|
|
* |
40 |
|
|
* This file defines the private parts of an mtx and is only for mtx*.c |
41 |
|
|
* consumption. Any temptation to include this header in a linear or |
42 |
|
|
* nonlinear solver package is a symptom of extremely bad programming |
43 |
|
|
* and lack of proper task analysis. This header should be regarded as |
44 |
|
|
* highly unstable. We make ABSOLUTELY NO commitment to maintain |
45 |
|
|
* consistency between any two versions of this file.<br><br> |
46 |
|
|
* |
47 |
|
|
* Note to third parties: |
48 |
|
|
* mtx is PRODUCTION code in very long use at Carnegie Mellon University. |
49 |
|
|
* * As such, we maintain a very tight hold of the internals of our data |
50 |
|
|
* structure so that we can easily prove the code when apparent bugs arise. |
51 |
|
|
* 99.44% of "bugs" experienced in using mtx are the result of not |
52 |
|
|
* reading the public headers carefully.<br><br> |
53 |
|
|
* |
54 |
|
|
* The material in this file was never a part of any header until the |
55 |
|
|
* old mtx.c file got so big that we had to split it up to make it |
56 |
|
|
* manageable.<br><br> |
57 |
|
|
* |
58 |
|
|
* Note to future developers of the mtx module. If you change ANYTHING |
59 |
|
|
* in this file it is YOUR job to: |
60 |
|
|
* a) clear that change with all the other developers using this header |
61 |
|
|
* b) fix ALL the other mtx*.c files that depend on it. |
62 |
|
|
* If you are not willing to do that much work, why the hell are you |
63 |
|
|
* dabbling in sparse matrix math? go work on GUIs. |
64 |
|
|
* <pre> |
65 |
|
|
* requires: #include <stdio.h> |
66 |
|
|
* requires: #include "utilities/ascConfig.h" |
67 |
|
|
* requires: #include "mem.h" |
68 |
|
|
* requires: #include "mtx.h" |
69 |
|
|
* <pre> |
70 |
|
|
*/ |
71 |
aw0a |
1 |
|
72 |
|
|
#ifndef __MTX_INTERNAL_USE_ONLY_H__ |
73 |
|
|
#define __MTX_INTERNAL_USE_ONLY_H__ |
74 |
|
|
|
75 |
johnpye |
1013 |
/** @addtogroup linear @{ */ |
76 |
|
|
|
77 |
aw0a |
1 |
#ifndef FALSE |
78 |
jds |
54 |
/** These should have come in from ascConfig.h. |
79 |
|
|
* @todo Remove redefines of FALSE & TRUE to enforce pre-inclusion of ascCenfig.h? */ |
80 |
aw0a |
1 |
#define FALSE 0 |
81 |
|
|
#define TRUE 1 |
82 |
|
|
#endif |
83 |
|
|
|
84 |
|
|
#define MTX_DEBUG FALSE |
85 |
ben.allan |
33 |
/**< MTX_DEBUG is a no holds barred sanity checking flag for use when |
86 |
aw0a |
1 |
* nothing else is giving a clue why something is going wrong. It |
87 |
|
|
* slows down the code to a crawl. Do not under any conditions change |
88 |
|
|
* its value or undefine it except at this location. If you need some |
89 |
|
|
* other sort of debugging flag for debugging a particular function, |
90 |
|
|
* use some personal debugging flag. |
91 |
|
|
*/ |
92 |
|
|
|
93 |
|
|
#define EVEN FALSE |
94 |
|
|
#define ODD TRUE |
95 |
|
|
#define SWAPS_PRESERVE_ORDER TRUE |
96 |
ben.allan |
33 |
/**< |
97 |
aw0a |
1 |
*** Do row and column swaps preserve the ordering of non-zeros in rows |
98 |
|
|
*** and columns? Setting this to TRUE means swapping only entails the |
99 |
|
|
*** movement of integer row or column numbers and NOT the exchange of |
100 |
|
|
*** entire row or columns. |
101 |
|
|
**/ |
102 |
|
|
#define WIDTHMAGIC 2048 |
103 |
ben.allan |
33 |
/**< |
104 |
aw0a |
1 |
*** WIDTHMAGIC is the byte size to aim for in allocating groups of elements. |
105 |
jds |
54 |
**/ |
106 |
|
|
#define LENMAGIC 10 |
107 |
|
|
/**< |
108 |
aw0a |
1 |
*** LENMAGIC initial # of groups of elements, hence the smallest |
109 |
|
|
*** possible number of elements a matrix will ever have is LENM*WIDTHM/eltsize. |
110 |
|
|
**/ |
111 |
|
|
|
112 |
|
|
extern FILE *g_mtxerr; |
113 |
jds |
54 |
/**< |
114 |
aw0a |
1 |
*** Global file pointer to which errors are reported. Should never be |
115 |
|
|
*** NULL. Also useful when running ascend in gdb and you can't find |
116 |
|
|
*** any other file pointer to use. |
117 |
|
|
**/ |
118 |
|
|
|
119 |
jds |
54 |
/** just a struct to make resulting code more readable. */ |
120 |
aw0a |
1 |
struct next_element_t { |
121 |
|
|
struct element_t *row; |
122 |
|
|
struct element_t *col; |
123 |
|
|
}; |
124 |
|
|
|
125 |
jds |
54 |
/** |
126 |
aw0a |
1 |
*** This is the basic jacobian element of an mtx. |
127 |
|
|
*** It's size is 24 bytes on 4 byte pointer machines and |
128 |
|
|
*** 32 bytes on 8 byte pointer machines. |
129 |
|
|
*** The elements form a bidirectional singly linked list. |
130 |
|
|
*** The row and col indices in an element refer back to |
131 |
|
|
*** the header positions of the two lists that element is in. |
132 |
|
|
*** That is, each element knows its orgrow and orgcol. |
133 |
|
|
**/ |
134 |
jds |
54 |
struct element_t { |
135 |
|
|
real64 value; |
136 |
|
|
int32 row; |
137 |
|
|
int32 col; |
138 |
|
|
struct next_element_t next; |
139 |
|
|
}; |
140 |
aw0a |
1 |
|
141 |
jds |
54 |
/** |
142 |
aw0a |
1 |
*** Each matrix is really just a pair of arrays of pointers to |
143 |
|
|
*** elements. The index of a row or column in THESE arrays is |
144 |
|
|
*** what is referred to as an org index. A value of NULL in |
145 |
jds |
54 |
*** either array means that that row (or col) is empty.<br><br> |
146 |
|
|
*** |
147 |
aw0a |
1 |
*** When we insert elements in the matrix, we simply shove the |
148 |
|
|
*** element in at the head of the its row/column lists. |
149 |
|
|
*** When we delete an element in the matrix, we search in one |
150 |
|
|
*** direction and unlink the element, marking it "dead". Then a |
151 |
|
|
*** general pass in the other direction unlinks all the "dead" |
152 |
jds |
54 |
*** elements.<br><br> |
153 |
|
|
*** |
154 |
aw0a |
1 |
*** Special note: The -1th element of nz_header arrays is NOT allocated. |
155 |
|
|
**/ |
156 |
jds |
54 |
struct nz_headers_t { |
157 |
|
|
struct element_t **row; |
158 |
|
|
struct element_t **col; |
159 |
|
|
}; |
160 |
aw0a |
1 |
|
161 |
jds |
54 |
/**< |
162 |
aw0a |
1 |
*** We maintain, rather than rederiving, the information required to |
163 |
|
|
*** answer all possible permutation questions. |
164 |
|
|
*** This is a policy decision based on the fact that mtx is research |
165 |
jds |
54 |
*** code that needs maximal flexibility at reasonable speed.<br><br> |
166 |
|
|
*** |
167 |
aw0a |
1 |
*** The -1th element of org_to_cur and cur_to_org are defined because |
168 |
|
|
*** -1 is used all over mtx as an error return. It's easier to debug |
169 |
|
|
*** things without the memory access errors that would happen if |
170 |
jds |
54 |
*** -1 were not allocated or were part of memory in some other object.<br><br> |
171 |
aw0a |
1 |
*** |
172 |
jds |
54 |
*** Special note: The -1th element of nz_header arrays is NOT allocated.<br><br> |
173 |
|
|
*** |
174 |
|
|
*** Do not access the parity field of a slave matrix, refer to its master. |
175 |
|
|
*** Conduct all permuting operations on the master. |
176 |
aw0a |
1 |
**/ |
177 |
jds |
54 |
struct permutation_t { |
178 |
|
|
int32 *org_to_cur; /**< org_to_cur[-1] = -1 */ |
179 |
|
|
int32 *cur_to_org; /**< cur_to_org[-1] = -1 */ |
180 |
|
|
boolean parity; |
181 |
|
|
}; |
182 |
aw0a |
1 |
|
183 |
|
|
struct permutations_t { |
184 |
|
|
struct permutation_t row; |
185 |
|
|
struct permutation_t col; |
186 |
|
|
int32 transpose; |
187 |
|
|
}; |
188 |
|
|
|
189 |
jds |
54 |
/**< |
190 |
aw0a |
1 |
*** There is a list of blocks associated with a matrix. |
191 |
|
|
*** This is an artifact of POOR solver API design between |
192 |
|
|
*** Peter Piela and Karl Westerberg. The blockwise decomposition |
193 |
|
|
*** information properly belongs to a linear or nonlinear solver |
194 |
|
|
*** and not to the mtx. |
195 |
|
|
*** |
196 |
jds |
54 |
*** @todo We intend to fix this soon. |
197 |
aw0a |
1 |
**/ |
198 |
jds |
54 |
struct structural_data_t { |
199 |
|
|
int32 symbolic_rank; /**< Symbolic rank (< 0 if invalid) */ |
200 |
|
|
int32 nblocks; /**< # blocks in matrix */ |
201 |
|
|
mtx_region_t *block; /**< Pointer to array of blocks */ |
202 |
|
|
}; |
203 |
aw0a |
1 |
|
204 |
jds |
54 |
/**< |
205 |
aw0a |
1 |
*** capacity may be > order. |
206 |
|
|
*** A matrix of capacity 0 doesn't have a mem_store_t yet and elements |
207 |
|
|
*** cannot be queried about without a core dump. |
208 |
|
|
**/ |
209 |
jds |
54 |
struct mtx_header { |
210 |
|
|
int integrity; /**< Integrity integer */ |
211 |
|
|
int32 order; /**< Order of the matrix */ |
212 |
|
|
int32 capacity; /**< Capacity of all the arrays */ |
213 |
|
|
int32 nslaves; /**< number of slave matrices */ |
214 |
|
|
struct nz_headers_t hdr; /**< Non-zero headers of the matrix */ |
215 |
|
|
struct element_t *last_value; /**< value/set_value memory */ |
216 |
|
|
mem_store_t ms; /**< element cache memory */ |
217 |
|
|
struct permutations_t perm; /**< Permutation vectors */ |
218 |
|
|
struct structural_data_t *data; /**< Pointer to structural information */ |
219 |
|
|
mtx_matrix_t master; /**< the master of this mtx, if slave */ |
220 |
|
|
mtx_matrix_t *slaves; /**< array of slave matrices */ |
221 |
|
|
}; |
222 |
aw0a |
1 |
|
223 |
jds |
54 |
/**< |
224 |
aw0a |
1 |
*** If you want to save a permutation for restoration, you |
225 |
|
|
*** have to make a copy of that data, eh? Here's the place you |
226 |
|
|
*** put it. Note that the block list should be disappearing from |
227 |
|
|
*** from the structural data soon. |
228 |
|
|
**/ |
229 |
jds |
54 |
struct mtx_block_perm_structure { |
230 |
|
|
int integrity; |
231 |
|
|
int32 order; /**< Order of the matrix */ |
232 |
|
|
int32 capacity; /**< Capacity of all the arrays */ |
233 |
|
|
mtx_matrix_t mtx; /**< matrix of origin */ |
234 |
|
|
struct permutations_t perm; /**< Permutation vectors */ |
235 |
|
|
struct structural_data_t *data; /**< Pointers to structural information */ |
236 |
|
|
}; |
237 |
aw0a |
1 |
|
238 |
|
|
#define OK ((int)201539237) |
239 |
jds |
54 |
/**< Matrix integrity (ok) value. */ |
240 |
aw0a |
1 |
#define DESTROYED ((int)531503871) |
241 |
jds |
54 |
/**< matrix integrity (destroyed) value. */ |
242 |
aw0a |
1 |
|
243 |
jds |
54 |
#define ZERO ((int32)0) |
244 |
|
|
#define D_ZERO ((real64)0.0) |
245 |
|
|
#define D_ONE ((real64)1.0) |
246 |
ben.allan |
33 |
/**< useful constants if your C compiler is not too bright about ANSI */ |
247 |
aw0a |
1 |
|
248 |
|
|
#define ISSLAVE(m) ((m)->master!=NULL) |
249 |
jds |
54 |
/**< Returns 1 if m is a slave matrix, 0 if not. */ |
250 |
aw0a |
1 |
|
251 |
|
|
#define ordered3(a,b,c) ((a) <= (b) && (b) <= (c)) |
252 |
|
|
#define in_range(rng,ndx) ordered3((rng)->low,ndx,(rng)->high) |
253 |
|
|
#define legal(mtx,ndx) ordered3(ZERO,ndx,(mtx)->order-1) |
254 |
ben.allan |
33 |
/**< |
255 |
aw0a |
1 |
*** Boolean operators to compare a row or column |
256 |
|
|
*** index with some specified range or the maximum |
257 |
|
|
*** range of the matrix in which it is used. |
258 |
|
|
**/ |
259 |
|
|
|
260 |
|
|
#define fast_in_range(l,h,i) ( ordered3(l,i,h) ) |
261 |
|
|
#define not_in_range(l,h,i) ( (i)<(l) || (i)>(h) ) |
262 |
ben.allan |
33 |
/**< |
263 |
aw0a |
1 |
*** Boolean operators to compare 3 integers. |
264 |
|
|
*** l <= h must be TRUE or these will lie. In many cases, |
265 |
|
|
*** this condition can (or should) be met before in_range |
266 |
|
|
*** is called. Sometimes these are not faster since the lo,hi vals cost. |
267 |
|
|
*** In particular, queries like next_col do not profit while calls |
268 |
|
|
*** which must traverse an entire row/col do. |
269 |
|
|
*** Gains in cycle count on dec alphas+cc are about 10% per function, |
270 |
|
|
*** but the gains in time are more like 1%, so alpha pixie is lying a little. |
271 |
|
|
*** For compilers which are not as clever as Decs, (gcc, sun acc) the |
272 |
|
|
*** gains should be much more visible. (some do not realize rng->low |
273 |
|
|
*** is invariant even with -O.) |
274 |
|
|
*** Note that these are 'loose' comparisons if !(l<=h) |
275 |
|
|
**/ |
276 |
|
|
|
277 |
|
|
#define zero(ptr,nelts,type) \ |
278 |
|
|
mem_zero_byte_cast((ptr),0,(nelts)*sizeof(type)) |
279 |
ben.allan |
33 |
/**< |
280 |
aw0a |
1 |
*** Zeros a vector of specified length and type. |
281 |
|
|
*** It is inefficient to use, however, if you know the type |
282 |
|
|
*** is one of the basic types (int,double,ptr,char) |
283 |
|
|
**/ |
284 |
|
|
|
285 |
|
|
|
286 |
jds |
54 |
/* ************************************************************************ *\ |
287 |
aw0a |
1 |
Private check routines |
288 |
jds |
54 |
\* ************************************************************************ */ |
289 |
|
|
extern int super_check_matrix(mtx_matrix_t mtx); |
290 |
ben.allan |
33 |
/**< |
291 |
aw0a |
1 |
*** After somevery extensive checking, returns an error count. |
292 |
|
|
*** More or less assume MTX_DEBUG is TRUE, and that is the only |
293 |
|
|
*** condition under which this should be called. |
294 |
|
|
**/ |
295 |
|
|
|
296 |
jds |
54 |
/* ************************************************************************ *\ |
297 |
aw0a |
1 |
Element CREATE/find routines. Please try to confine use of these to |
298 |
|
|
mtx_basic.c as much as possible. |
299 |
jds |
54 |
Use of find should be avoided at all costs, and in particular |
300 |
aw0a |
1 |
absolutely noone outside mtx should put their fingers on elements. |
301 |
|
|
|
302 |
|
|
These functions are not exported to generic users because they are |
303 |
|
|
on the critical path and we cannot afford the sanity checking required. |
304 |
|
|
They should only be called in contexts where the arguments are |
305 |
|
|
guaranteed valid. |
306 |
jds |
54 |
\* ************************************************************************ */ |
307 |
aw0a |
1 |
|
308 |
jds |
54 |
struct element_t *mtx_find_element(mtx_matrix_t mtx, |
309 |
|
|
int32 org_row, |
310 |
|
|
int32 org_col); |
311 |
ben.allan |
33 |
/**< |
312 |
aw0a |
1 |
*** Searches for a given element of the matrix and returns a pointer to it |
313 |
|
|
*** if it exists, or NULL if it doesn't exist. |
314 |
|
|
*** It is *ASSUMED* that org_row |
315 |
|
|
*** and org_col are legal indices. May crash if they are not. |
316 |
|
|
**/ |
317 |
|
|
|
318 |
jds |
54 |
struct element_t *mtx_create_element(mtx_matrix_t mtx, |
319 |
|
|
int32 org_row, |
320 |
|
|
int32 org_col); |
321 |
|
|
/**< |
322 |
aw0a |
1 |
*** Creates the given element and returns a pointer to it. The value is |
323 |
|
|
*** initially zero. |
324 |
|
|
*** It is *ASSUMED* that org_row |
325 |
|
|
*** and org_col are legal indices. May crash if they are not. |
326 |
|
|
*** If mtx_DEBUG is TRUE, then we will whine if the element already |
327 |
|
|
*** exists, but go ahead and create it anyway. |
328 |
|
|
**/ |
329 |
|
|
|
330 |
jds |
54 |
struct element_t *mtx_create_element_value(mtx_matrix_t mtx, |
331 |
|
|
int32 org_row, |
332 |
|
|
int32 org_col, |
333 |
|
|
real64 val); |
334 |
|
|
/**< |
335 |
aw0a |
1 |
*** Creates the given element and returns a pointer to it. The value is |
336 |
|
|
*** initialzed to val. |
337 |
|
|
*** It is *ASSUMED* that org_row |
338 |
|
|
*** and org_col are legal indices. May crash if they are not. |
339 |
|
|
*** If mtx_DEBUG is TRUE, then we will whine if the element already |
340 |
|
|
*** exists, but go ahead and create it anyway. |
341 |
|
|
**/ |
342 |
|
|
|
343 |
jds |
54 |
/* ************************************************************************ *\ |
344 |
aw0a |
1 |
Element list traversals. No linear algebra programmer with an ounce of |
345 |
|
|
intelligence would ever need to use these in critical path functions. |
346 |
jds |
54 |
\* ************************************************************************ */ |
347 |
|
|
extern struct element_t *mtx_next_col(register struct element_t *elt, |
348 |
|
|
mtx_range_t *rng, |
349 |
|
|
int32 *tocur); |
350 |
ben.allan |
33 |
/**< |
351 |
aw0a |
1 |
*** Returns the next element after elt that is in the range |
352 |
|
|
*** rng according to the permutation vector tocur given. May return NULL. |
353 |
|
|
**/ |
354 |
|
|
|
355 |
jds |
54 |
extern struct element_t *mtx_next_row(register struct element_t *elt, |
356 |
|
|
mtx_range_t *rng, |
357 |
|
|
int32 *tocur); |
358 |
ben.allan |
33 |
/**< |
359 |
aw0a |
1 |
*** Returns the next element after elt that is in the range |
360 |
|
|
*** rng according to the permutation vector tocur given. May return NULL. |
361 |
|
|
**/ |
362 |
|
|
|
363 |
jds |
54 |
/* ************************************************************************ *\ |
364 |
aw0a |
1 |
Permutation memory management. |
365 |
jds |
54 |
\* ************************************************************************ */ |
366 |
|
|
extern int32 *mtx_alloc_perm(int32 cap); |
367 |
|
|
/**< |
368 |
aw0a |
1 |
*** Allocates a permutation vector. The user need |
369 |
|
|
*** not concern himself with the -1st element, which does exist. |
370 |
|
|
**/ |
371 |
|
|
|
372 |
jds |
54 |
extern void mtx_copy_perm(int32 *tarperm, int32 *srcperm, int32 cap); |
373 |
|
|
/**< |
374 |
aw0a |
1 |
*** Copies srcperm to tarperm given the capacity of srcperm. |
375 |
|
|
*** If tarperm was obtained from alloc_perm(), the -1 has already been copied. |
376 |
|
|
**/ |
377 |
|
|
|
378 |
jds |
54 |
extern void mtx_free_perm(int32 *perm); |
379 |
|
|
/**< |
380 |
|
|
*** Frees resources used by a permutation vector. |
381 |
aw0a |
1 |
**/ |
382 |
|
|
|
383 |
jds |
54 |
/* ************************************************************************ *\ |
384 |
aw0a |
1 |
It is advantageous in an interactive system to introduce reusable |
385 |
|
|
memory and monitor its integrity rather than to repeatedly allocate |
386 |
|
|
and zero it. The following code accomplishes this for mtx. |
387 |
|
|
A null_vector is an array of objects (size s, length n) with value 0. |
388 |
|
|
This sort of memory management is needed because there is always the chance |
389 |
|
|
that a floating point exception could cause premature return of an mtx |
390 |
|
|
client. This way we have a safe place to store pointers to the memory |
391 |
|
|
even if the user's algorithm loses them. |
392 |
jds |
54 |
\* ************************************************************************ */ |
393 |
aw0a |
1 |
|
394 |
|
|
struct reusable_data_vector { |
395 |
ben.allan |
33 |
void *arr; /**< pointer to array of objects size entrysize */ |
396 |
|
|
int capacity; /**< number of object slots in array */ |
397 |
|
|
size_t entry_size; /**< size of slots */ |
398 |
|
|
int last_line; /**< line most recently associated with this structure, |
399 |
aw0a |
1 |
should be 0 if the array is not in use. */ |
400 |
|
|
}; |
401 |
|
|
|
402 |
|
|
extern struct reusable_data_vector |
403 |
jds |
54 |
g_mtx_null_index_data, /**< bunch of int32 */ |
404 |
|
|
g_mtx_null_sum_data, /**< bunch of mtx_value_t */ |
405 |
|
|
g_mtx_null_mark_data, /**< bunch of char */ |
406 |
|
|
g_mtx_null_vector_data, /**< bunch of element pointers */ |
407 |
|
|
g_mtx_null_col_vector_data, /**< bunch of element pointers */ |
408 |
|
|
g_mtx_null_row_vector_data; /**< bunch of element pointers */ |
409 |
aw0a |
1 |
|
410 |
jds |
54 |
/* OLD GROUP COMMENTS */ |
411 |
|
|
/* |
412 |
aw0a |
1 |
*** vec = mtx_null_vector(nptrs); |
413 |
|
|
*** vec = mtx_null_col_vector(nptrs); |
414 |
|
|
*** vec = mtx_null_row_vector(nptrs); |
415 |
|
|
*** marks = mtx_null_mark(nchar); |
416 |
|
|
*** sums = mtx_null_sum(nnums); |
417 |
|
|
*** indexes = mtx_null_index(ninds); |
418 |
|
|
*** |
419 |
|
|
*** struct element_t **vec; |
420 |
|
|
*** char *marks; |
421 |
|
|
*** real64 *sums; |
422 |
|
|
*** int32 *indexes; |
423 |
|
|
*** int32 nptrs, nchar, nnums, ninds; |
424 |
|
|
*** |
425 |
|
|
*** Returns an array of chars, elt pointers, indexes or numbers all NULL/0. |
426 |
|
|
*** We need these a lot, but seldom simultaneously, and we know generally |
427 |
|
|
*** how to rezero them when done with them. |
428 |
|
|
*** These functions should not be |
429 |
|
|
*** called again until the vector is re-NULLED and out of use. |
430 |
|
|
*** If we detect a double call, we will whine loudly, renull |
431 |
|
|
*** the array ourselves, and give it to you again. |
432 |
|
|
*** To avoid whining, call the corresponding release functions |
433 |
|
|
*** each time you are done with one of these vectors. |
434 |
|
|
*** |
435 |
|
|
*** In the event of insufficient memory (alloc failed) we will |
436 |
|
|
*** return NULL. If we return NULL, you needn't call the release function. |
437 |
|
|
*** |
438 |
|
|
*** mtx_null_vector_release(); |
439 |
|
|
*** mtx_null_col_vector_release(); |
440 |
|
|
*** mtx_null_row_vector_release(); |
441 |
|
|
*** mtx_null_mark_release(); |
442 |
|
|
*** mtx_null_sum_release(); |
443 |
|
|
*** mtx_null_index_release(); |
444 |
|
|
*** |
445 |
|
|
*** These are a memory reuse promoter. |
446 |
|
|
*** Calling with cap==0 frees any memory in use. |
447 |
|
|
*** Clientlists -- PLEASE KEEP THIS UP TO DATE -- |
448 |
|
|
*** mtx_null_vector: |
449 |
|
|
*** expand_row,expand_col, mtx_assemble |
450 |
|
|
*** mtx_householder_transform |
451 |
|
|
*** mtx_null_row_vector: |
452 |
|
|
*** expand_row_series |
453 |
|
|
*** mtx_null_col_vector: |
454 |
|
|
*** expand_col_series |
455 |
|
|
*** mtx_null_mark: |
456 |
|
|
*** mtx_householder_transform |
457 |
|
|
*** mtx_null_sum: |
458 |
|
|
*** mtx_householder_transform |
459 |
|
|
*** mtx_null_index: |
460 |
|
|
*** mtx_householder_transform |
461 |
|
|
**/ |
462 |
jds |
54 |
#define mtx_null_vector(cap) \ |
463 |
|
|
((struct element_t **)mtx_null_vector_f(cap,__LINE__,__FILE__, \ |
464 |
aw0a |
1 |
&g_mtx_null_vector_data,"null_vector")) |
465 |
jds |
54 |
/**< |
466 |
|
|
* Returns an array of elt pointers all NULL/0. |
467 |
|
|
* This function should not be called again until the vector is |
468 |
|
|
* re-NULLED and out of use. If we detect a double call, we will |
469 |
|
|
* whine loudly, renull the array ourselves, and give it to you again. |
470 |
|
|
* To avoid whining, call mtx_null_vector_release() |
471 |
|
|
* each time you are done with the returned vector.<br><br> |
472 |
|
|
* |
473 |
|
|
* In the event of insufficient memory (alloc failed) we will |
474 |
|
|
* return NULL. If we return NULL, you needn't call the release function. |
475 |
|
|
* @param cap int32, the capacity of the matrix (0 to free memory). |
476 |
|
|
* @return No return value. |
477 |
|
|
* @see mtx_null_vector_f() |
478 |
|
|
*/ |
479 |
|
|
#define mtx_null_row_vector(cap) \ |
480 |
|
|
((struct element_t **)mtx_null_vector_f(cap,__LINE__,__FILE__, \ |
481 |
aw0a |
1 |
&g_mtx_null_row_vector_data,\ |
482 |
|
|
"null_row_vector")) |
483 |
jds |
54 |
/**< |
484 |
|
|
* Returns an array of elt pointers all NULL/0. |
485 |
|
|
* See mtx_null_vector() for more details. |
486 |
|
|
* @param cap int32, the capacity of the matrix (0 to free memory). |
487 |
|
|
* @return No return value. |
488 |
|
|
* @see mtx_null_vector_f() |
489 |
|
|
*/ |
490 |
|
|
#define mtx_null_col_vector(cap) \ |
491 |
|
|
((struct element_t **)mtx_null_vector_f(cap,__LINE__,__FILE__, \ |
492 |
aw0a |
1 |
&g_mtx_null_col_vector_data,\ |
493 |
|
|
"null_col_vector")) |
494 |
jds |
54 |
/**< |
495 |
|
|
* Returns an array of elt pointers all NULL/0. |
496 |
|
|
* See mtx_null_vector() for more details. |
497 |
|
|
* @param cap int32, the capacity of the matrix (0 to free memory). |
498 |
|
|
* @return No return value. |
499 |
|
|
* @see mtx_null_vector_f() |
500 |
|
|
*/ |
501 |
|
|
#define mtx_null_mark(cap) \ |
502 |
|
|
((char *)mtx_null_vector_f(cap,__LINE__,__FILE__, \ |
503 |
aw0a |
1 |
&g_mtx_null_mark_data,"null_mark")) |
504 |
jds |
54 |
/**< |
505 |
|
|
* Returns an array of chars all NULL/0. |
506 |
|
|
* This function should not be called again until the vector is |
507 |
|
|
* re-NULLED and out of use. If we detect a double call, we will |
508 |
|
|
* whine loudly, renull the array ourselves, and give it to you again. |
509 |
|
|
* To avoid whining, call mtx_null_mark_release() |
510 |
|
|
* each time you are done with the returned vector.<br><br> |
511 |
|
|
* |
512 |
|
|
* In the event of insufficient memory (alloc failed) we will |
513 |
|
|
* return NULL. If we return NULL, you needn't call the release function. |
514 |
|
|
* @param cap int32, the capacity of the array (0 to free memory). |
515 |
|
|
* @return No return value. |
516 |
|
|
* @see mtx_null_vector_f() |
517 |
|
|
*/ |
518 |
|
|
#define mtx_null_sum(cap) \ |
519 |
|
|
((real64 *)mtx_null_vector_f(cap,__LINE__,__FILE__, \ |
520 |
aw0a |
1 |
&g_mtx_null_sum_data,"null_sum")) |
521 |
jds |
54 |
/**< |
522 |
|
|
* Returns an array of real64 numbers all NULL/0. |
523 |
|
|
* This function should not be called again until the vector is |
524 |
|
|
* re-NULLED and out of use. If we detect a double call, we will |
525 |
|
|
* whine loudly, renull the array ourselves, and give it to you again. |
526 |
|
|
* To avoid whining, call mtx_null_sum_release() |
527 |
|
|
* each time you are done with the returned array.<br><br> |
528 |
|
|
* |
529 |
|
|
* In the event of insufficient memory (alloc failed) we will |
530 |
|
|
* return NULL. If we return NULL, you needn't call the release function. |
531 |
|
|
* @param cap int32, the capacity of the array (0 to free memory). |
532 |
|
|
* @return No return value. |
533 |
|
|
* @see mtx_null_vector_f() |
534 |
|
|
*/ |
535 |
|
|
#define mtx_null_index(cap) \ |
536 |
|
|
((int32 *)mtx_null_vector_f(cap,__LINE__,__FILE__, \ |
537 |
aw0a |
1 |
&g_mtx_null_index_data,"null_index")) |
538 |
|
|
|
539 |
jds |
54 |
/**< |
540 |
|
|
* Returns an array of int32 indexes all NULL/0. |
541 |
|
|
* This function should not be called again until the vector is |
542 |
|
|
* re-NULLED and out of use. If we detect a double call, we will |
543 |
|
|
* whine loudly, renull the array ourselves, and give it to you again. |
544 |
|
|
* To avoid whining, call mtx_null_index_release() |
545 |
|
|
* each time you are done with the returned array.<br><br> |
546 |
|
|
* |
547 |
|
|
* In the event of insufficient memory (alloc failed) we will |
548 |
|
|
* return NULL. If we return NULL, you needn't call the release function. |
549 |
|
|
* @param cap int32, the capacity of the array (0 to free memory). |
550 |
|
|
* @return No return value. |
551 |
|
|
* @see mtx_null_vector_f() |
552 |
|
|
*/ |
553 |
aw0a |
1 |
#define mtx_null_vector_release() \ |
554 |
|
|
mtx_null_vector_release_f(__LINE__,__FILE__, \ |
555 |
|
|
&g_mtx_null_vector_data,"null_vector") |
556 |
jds |
54 |
/**< |
557 |
|
|
* Marks a vector as not in use, or whines if it wasn't. |
558 |
|
|
* @param None. |
559 |
|
|
* @return No return value. |
560 |
|
|
* @see mtx_null_vector_release_f() |
561 |
|
|
*/ |
562 |
aw0a |
1 |
#define mtx_null_col_vector_release() \ |
563 |
|
|
mtx_null_vector_release_f(__LINE__,__FILE__, \ |
564 |
|
|
&g_mtx_null_col_vector_data,"null_col_vector") |
565 |
jds |
54 |
/**< |
566 |
|
|
* Marks a vector as not in use, or whines if it wasn't. |
567 |
|
|
* @param None. |
568 |
|
|
* @return No return value. |
569 |
|
|
* @see mtx_null_vector_release_f() |
570 |
|
|
*/ |
571 |
aw0a |
1 |
#define mtx_null_row_vector_release() \ |
572 |
|
|
mtx_null_vector_release_f(__LINE__,__FILE__, \ |
573 |
|
|
&g_mtx_null_row_vector_data,"null_row_vector") |
574 |
jds |
54 |
/**< |
575 |
|
|
* Marks a vector as not in use, or whines if it wasn't. |
576 |
|
|
* @param None. |
577 |
|
|
* @return No return value. |
578 |
|
|
* @see mtx_null_vector_release_f() |
579 |
|
|
*/ |
580 |
aw0a |
1 |
#define mtx_null_mark_release() \ |
581 |
|
|
mtx_null_vector_release_f(__LINE__,__FILE__, \ |
582 |
|
|
&g_mtx_null_mark_data,"null_mark") |
583 |
jds |
54 |
/**< |
584 |
|
|
* Marks a char array as not in use, or whines if it wasn't. |
585 |
|
|
* @param None. |
586 |
|
|
* @return No return value. |
587 |
|
|
* @see mtx_null_vector_release_f() |
588 |
|
|
*/ |
589 |
aw0a |
1 |
#define mtx_null_sum_release() \ |
590 |
|
|
mtx_null_vector_release_f(__LINE__,__FILE__, \ |
591 |
|
|
&g_mtx_null_sum_data,"null_sum") |
592 |
jds |
54 |
/**< |
593 |
|
|
* Marks a number array as not in use, or whines if it wasn't. |
594 |
|
|
* @param None. |
595 |
|
|
* @return No return value. |
596 |
|
|
* @see mtx_null_vector_release_f() |
597 |
|
|
*/ |
598 |
aw0a |
1 |
#define mtx_null_index_release() \ |
599 |
|
|
mtx_null_vector_release_f(__LINE__,__FILE__, \ |
600 |
|
|
&g_mtx_null_index_data,"null_index") |
601 |
jds |
54 |
/**< |
602 |
|
|
* Marks an index array as not in use, or whines if it wasn't. |
603 |
|
|
* @param None. |
604 |
|
|
* @return No return value. |
605 |
|
|
* @see mtx_null_vector_release_f() |
606 |
|
|
*/ |
607 |
aw0a |
1 |
|
608 |
jds |
54 |
extern void *mtx_null_vector_f(int32 cap, int line, CONST char *file, |
609 |
|
|
struct reusable_data_vector *ptr, char *fn); |
610 |
|
|
/**< |
611 |
|
|
*** Implementation function for macros generating vectors of NULL |
612 |
|
|
*** elements. This includes: |
613 |
|
|
*** - mtx_null_vector() |
614 |
|
|
*** - mtx_null_col_vector() |
615 |
|
|
*** - mtx_null_row_vector() |
616 |
|
|
*** - mtx_null_mark() |
617 |
|
|
*** - mtx_null_sum() |
618 |
|
|
*** - mtx_null_index() |
619 |
|
|
*** |
620 |
|
|
*** Do not call this function directly - use the appropriate macro |
621 |
|
|
*** instead. |
622 |
|
|
*** Returns a pointer to cap*ptr->entry_size bytes, which must be cast. |
623 |
|
|
*** The memory pointed at is believed to be zero, and will be if the |
624 |
|
|
*** user is properly rezeroing the vector before it is released. |
625 |
|
|
*** If insufficient memory is available, this whines and returns NULL. |
626 |
|
|
*** Calling this with cap==0 causes the reused memory to be deallocated and |
627 |
|
|
*** returns NULL. |
628 |
aw0a |
1 |
**/ |
629 |
|
|
|
630 |
jds |
54 |
extern void mtx_null_vector_release_f(int line, |
631 |
|
|
CONST char *file, |
632 |
|
|
struct reusable_data_vector *ptr, |
633 |
|
|
char *fn); |
634 |
|
|
/**< |
635 |
|
|
*** Implementation function for macros releasing reusable vectors. |
636 |
|
|
*** This includes: |
637 |
|
|
*** - mtx_null_vector_release() |
638 |
|
|
*** - mtx_null_col_vector_release() |
639 |
|
|
*** - mtx_null_row_vector_release() |
640 |
|
|
*** - mtx_null_mark_release() |
641 |
|
|
*** - mtx_null_sum_release() |
642 |
|
|
*** - mtx_null_index_release() |
643 |
|
|
*** |
644 |
|
|
*** Do not call this function directly - use the appropriate macro |
645 |
|
|
*** instead. |
646 |
|
|
*** Marks a vector as not in use, or whines if it wasn't. |
647 |
|
|
*** Does no other checking. Uses line, file and fn in error reporting. |
648 |
aw0a |
1 |
**/ |
649 |
|
|
|
650 |
|
|
extern void mtx_reset_null_vectors(void); |
651 |
jds |
54 |
/**< |
652 |
aw0a |
1 |
*** This resets the reusable arrays of zeroes to zero in the event |
653 |
|
|
*** that they may have been corrupted. |
654 |
|
|
**/ |
655 |
|
|
|
656 |
jds |
54 |
/* |
657 |
|
|
* INTERNAL element vector operations of some utility. |
658 |
aw0a |
1 |
*/ |
659 |
|
|
|
660 |
jds |
54 |
extern struct element_t **mtx_expand_row(mtx_matrix_t mtx, int32 orgrow); |
661 |
|
|
/**< |
662 |
aw0a |
1 |
*** Expands the given row into an array of pointers, indexed on original |
663 |
|
|
*** col number. The array is obtained from mtx_null_vector(). |
664 |
|
|
*** Be sure to call mtx_null_vector_release() when done with the vector and |
665 |
|
|
*** you have rezeroed it. |
666 |
jds |
54 |
*** You cannot call this twice without releasing first or call |
667 |
|
|
*** mtx_expand_col(). |
668 |
aw0a |
1 |
**/ |
669 |
|
|
|
670 |
jds |
54 |
extern struct element_t **mtx_expand_col(mtx_matrix_t mtx, int32 orgcol); |
671 |
|
|
/**< |
672 |
aw0a |
1 |
*** Expands the given col into an array of pointers, indexed on original |
673 |
|
|
*** row number. The array is obtained from mtx_null_vector(). |
674 |
|
|
*** Be sure to call mtx_null_vector_release() when done with the vector and |
675 |
|
|
*** you have rezeroed it. |
676 |
jds |
54 |
*** You cannot call this twice without releasing first or call |
677 |
|
|
*** mtx_expand_row(). |
678 |
aw0a |
1 |
**/ |
679 |
|
|
|
680 |
jds |
54 |
extern void mtx_renull_using_row(mtx_matrix_t mtx, |
681 |
|
|
int32 orgrow, |
682 |
|
|
struct element_t **arr); |
683 |
|
|
/**< |
684 |
aw0a |
1 |
*** Makes arr NULLed again, assuming that the only non-NULL elements |
685 |
|
|
*** must correspond to original col numbers that exist in the given |
686 |
|
|
*** orgrow. |
687 |
|
|
**/ |
688 |
|
|
|
689 |
jds |
54 |
extern void mtx_renull_using_col(mtx_matrix_t mtx, |
690 |
|
|
int32 orgcol, |
691 |
|
|
struct element_t **arr); |
692 |
|
|
/**< |
693 |
aw0a |
1 |
*** Makes arr NULLed again, assuming that the only non-NULL elements |
694 |
|
|
*** must correspond to original row numbers that exist in the given |
695 |
|
|
*** orgcol. |
696 |
|
|
**/ |
697 |
|
|
|
698 |
jds |
54 |
extern void mtx_renull_all(mtx_matrix_t mtx, struct element_t **arr); |
699 |
|
|
/**< |
700 |
aw0a |
1 |
*** Makes arr NULLed again, assuming it is size mtx->order. |
701 |
|
|
**/ |
702 |
|
|
|
703 |
johnpye |
1013 |
/** @} */ |
704 |
|
|
|
705 |
jds |
54 |
#endif /* __MTX_INTERNAL_USE_ONLY_H__ */ |
706 |
|
|
#endif /* none of your business if you aren't mtx_*.c */ |
707 |
|
|
|