1 |
dashley |
71 |
//$Header$ |
2 |
|
|
//------------------------------------------------------------------------------------------------- |
3 |
|
|
//This file is part of "David T. Ashley's Shared Source Code", a set of shared components |
4 |
|
|
//integrated into many of David T. Ashley's projects. |
5 |
|
|
//------------------------------------------------------------------------------------------------- |
6 |
|
|
//This source code and any program in which it is compiled/used is provided under the MIT License, |
7 |
|
|
//reproduced below. |
8 |
|
|
//------------------------------------------------------------------------------------------------- |
9 |
|
|
//Permission is hereby granted, free of charge, to any person obtaining a copy of |
10 |
|
|
//this software and associated documentation files(the "Software"), to deal in the |
11 |
|
|
//Software without restriction, including without limitation the rights to use, |
12 |
|
|
//copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the |
13 |
|
|
//Software, and to permit persons to whom the Software is furnished to do so, |
14 |
|
|
//subject to the following conditions : |
15 |
|
|
// |
16 |
|
|
//The above copyright notice and this permission notice shall be included in all |
17 |
|
|
//copies or substantial portions of the Software. |
18 |
|
|
// |
19 |
|
|
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 |
|
|
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 |
|
|
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE |
22 |
|
|
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 |
|
|
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 |
|
|
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
25 |
|
|
//SOFTWARE. |
26 |
|
|
//------------------------------------------------------------------------------------------------- |
27 |
|
|
#ifndef CVXZONE_H_INCLUDED |
28 |
|
|
#define CVXZONE_H_INCLUDED |
29 |
|
|
|
30 |
|
|
#ifdef MODULE_CVXZONE |
31 |
|
|
#define DECMOD_CVXZONE |
32 |
|
|
#else |
33 |
|
|
#define DECMOD_CVXZONE extern |
34 |
|
|
#endif |
35 |
|
|
|
36 |
|
|
#define CVXZONE_ZONE_CONST_ALLOC_INC (20) |
37 |
|
|
/* The allocation increment for constraints which make up |
38 |
|
|
** a convex zone. This is the number of slots that will |
39 |
|
|
** be allocated at a time. A larger value here creates more |
40 |
|
|
** run-time efficiency but wastes more memory. |
41 |
|
|
*/ |
42 |
|
|
|
43 |
|
|
/* Types of equalities and inequalities. |
44 |
|
|
*/ |
45 |
|
|
#define CVXZONE_INEQ_LT (0) /* < */ |
46 |
|
|
#define CVXZONE_INEQ_LE (1) /* <= */ |
47 |
|
|
#define CVXZONE_INEQ_EQ (2) /* == */ |
48 |
|
|
#define CVXZONE_INEQ_GE (3) /* > */ |
49 |
|
|
#define CVXZONE_INEQ_GT (4) /* >= */ |
50 |
|
|
#define CVXZONE_INEQ_UDF (5) /* Unknown or undefined. */ |
51 |
|
|
#define CVXZONE_INEQ_MAX (6) /* Max for bounds checking. */ |
52 |
|
|
|
53 |
|
|
|
54 |
|
|
/* Defines a single constraint, i.e. x[a]-x[b] <|<= K as known |
55 |
|
|
** to this module. x[0] is always the value of zero. Any given |
56 |
|
|
** convex region or zone is a conjunction of such inequalities. |
57 |
|
|
*/ |
58 |
|
|
typedef struct |
59 |
|
|
{ |
60 |
|
|
unsigned valid : 1; |
61 |
|
|
/* TRUE if record is valid, i.e. used. |
62 |
|
|
*/ |
63 |
|
|
unsigned eq : 1; |
64 |
|
|
/* TRUE if the inequality is <= rather than |
65 |
|
|
** <. |
66 |
|
|
*/ |
67 |
|
|
int v1; |
68 |
|
|
int v2; |
69 |
|
|
/* Subscripts of variables in v1 - v2 <|<= k. |
70 |
|
|
*/ |
71 |
|
|
int k; |
72 |
|
|
/* The constant involved. |
73 |
|
|
*/ |
74 |
|
|
} CVXZONE_constraint, *CVXZONE_constraint_ptr; |
75 |
|
|
|
76 |
|
|
/* Fundamental data structure that is a convex zone bounded |
77 |
|
|
** by inequalities. All of the clock variables are represented |
78 |
|
|
** as integers. The variable with index 0 (i.e. x[0]) is the |
79 |
|
|
** special value 0. Therefore, all clocks must be subscripted |
80 |
|
|
** starting with the value "1" and go contiguously upwards, and |
81 |
|
|
** this inconvenience is visible to the client, i.e. the client |
82 |
|
|
** must communicate with this module in these terms. |
83 |
|
|
** |
84 |
|
|
** Note that there is some ambiguity in this data structure |
85 |
|
|
** because the order of the space which is being considered |
86 |
|
|
** is not specified anywhere (because there is no need to |
87 |
|
|
** specify it). This module will fatally terminate |
88 |
|
|
** the program in any context where a constraint exists for a variable |
89 |
|
|
** that can't exist (so far there is only one such place this can |
90 |
|
|
** occur). The caller needs to be consistent in the order of the |
91 |
|
|
** space (i.e. the caller needs to know the assumed order of the |
92 |
|
|
** space). |
93 |
|
|
*/ |
94 |
|
|
typedef struct |
95 |
|
|
{ |
96 |
|
|
unsigned is_canonical : 1; |
97 |
|
|
/* TRUE if the data structure is in canonical form. This |
98 |
|
|
** flag is maintained so that repeated needs to put in |
99 |
|
|
** canonical form will not take any CPU time. Essentially |
100 |
|
|
** any operation that modifies this data structure will |
101 |
|
|
** violate the canonical form and cause this flag to be |
102 |
|
|
** set to 0. |
103 |
|
|
*/ |
104 |
|
|
unsigned is_empty : 1; |
105 |
|
|
/* By default, a space with no constraints is taken to be |
106 |
|
|
** full, i.e. to contain all of R-space. This flag negates |
107 |
|
|
** that, i.e. signals the empty set. The canonical form |
108 |
|
|
** of all-space is no constraints and this flag FALSE. The |
109 |
|
|
** canonical form of no-space is no constraints and this |
110 |
|
|
** flag TRUE. |
111 |
|
|
*/ |
112 |
|
|
unsigned n_allocd; |
113 |
|
|
/* The number of slots allocated for constraints in this |
114 |
|
|
** data structure. This value grows, but never shrinks. |
115 |
|
|
** This is the number allocated, but not necessarily the |
116 |
|
|
** number used. This value grows in steps of |
117 |
|
|
** CVXZONE_ZONE_CONST_ALLOC_INC. If this value is zero, |
118 |
|
|
** the pointer below must be NULL. |
119 |
|
|
*/ |
120 |
|
|
unsigned n_used; |
121 |
|
|
/* The number of slots which are used. This means that the |
122 |
|
|
** used slots range from 0 through this value - 1. |
123 |
|
|
** This only flags the constraints which must be inspected |
124 |
|
|
** and potentially apply, but not necessarily every constraint |
125 |
|
|
** in this range applies. In addition to the constraint being |
126 |
|
|
** subscripted in 0..n-1, the constraint must also have its |
127 |
|
|
** valid bit set. The set of active constraints is thus |
128 |
|
|
** those in the range of 0..n-1 with their valid bits set. |
129 |
|
|
*/ |
130 |
|
|
CVXZONE_constraint_ptr constraints; |
131 |
|
|
/* Pointer to the allocated block of constraints. The number |
132 |
|
|
** allocated is realloc'd up by CVXZONE_ZONE_CONST_ALLOC_INC |
133 |
|
|
** slots each time one runs out of memory. |
134 |
|
|
*/ |
135 |
|
|
} CVXZONE_zone, *CVXZONE_zone_ptr; |
136 |
|
|
|
137 |
|
|
/**************************************************************************/ |
138 |
|
|
/***** ALLOCATION, DEALLOCATION, AND COPY FUNCTIONS |
139 |
|
|
/**************************************************************************/ |
140 |
|
|
/* Allocates a new zone and fills in the caller's pointer. The |
141 |
|
|
** pointed-to pointer must be NULL. Zones begin life as "full"--containing |
142 |
|
|
** all of R-space. |
143 |
|
|
*/ |
144 |
|
|
DECMOD_CVXZONE void CVXZONE_new(CVXZONE_zone_ptr *arg); |
145 |
|
|
|
146 |
|
|
/* Deallocates a zone and fills in the caller's pointer to NULL. Previous |
147 |
|
|
** pointer to zone must not be NULL. |
148 |
|
|
*/ |
149 |
|
|
DECMOD_CVXZONE void CVXZONE_delete(CVXZONE_zone_ptr *arg); |
150 |
|
|
|
151 |
|
|
/* Copies one zone to another. The destination zone, which must |
152 |
|
|
** already exist, is overwritten. |
153 |
|
|
*/ |
154 |
|
|
DECMOD_CVXZONE void CVXZONE_copy(CVXZONE_zone_ptr *dst, CVXZONE_zone_ptr *src); |
155 |
|
|
|
156 |
|
|
/* Clones a zone. To clone means to create and copy in one step. |
157 |
|
|
*/ |
158 |
|
|
DECMOD_CVXZONE void CVXZONE_clone(CVXZONE_zone_ptr *clone, CVXZONE_zone_ptr *orig); |
159 |
|
|
|
160 |
|
|
/**************************************************************************/ |
161 |
|
|
/***** MAINTENANCE FUNCTIONS |
162 |
|
|
/**************************************************************************/ |
163 |
|
|
/* Trims extra memory from a zone (but won't convert it to canonical form). |
164 |
|
|
** The default behavior for a zone is that memory is never reclaimed (this is |
165 |
|
|
** probably the desired behavior--reclaiming memory costs time with no real |
166 |
|
|
** benefit). Note that trimming memory goes beyond canonical form ... it is |
167 |
|
|
** not part of making something canonical. |
168 |
|
|
*/ |
169 |
|
|
DECMOD_CVXZONE void CVXZONE_maintain_memory_trim(CVXZONE_zone_ptr *arg); |
170 |
|
|
|
171 |
|
|
/* Converts a zone to canonical form. Normally this type of operation is |
172 |
|
|
** never necessary explicitly, because any function call that needs a zone |
173 |
|
|
** to be in canonical form will ensure this first. This function call |
174 |
|
|
** might never be used except for testing. |
175 |
|
|
*/ |
176 |
|
|
DECMOD_CVXZONE void CVXZONE_maintain_canonize(CVXZONE_zone_ptr *arg); |
177 |
|
|
|
178 |
|
|
|
179 |
|
|
/**************************************************************************/ |
180 |
|
|
/***** ASSIGNMENT FUNCTIONS |
181 |
|
|
/**************************************************************************/ |
182 |
|
|
/* Assigns a zone, which must already exist, to be the empty set. |
183 |
|
|
*/ |
184 |
|
|
DECMOD_CVXZONE void CVXZONE_assign_empty(CVXZONE_zone_ptr *arg); |
185 |
|
|
|
186 |
|
|
/* Assigns a zone, which must already exist, to be the full set (all of R^N). |
187 |
|
|
*/ |
188 |
|
|
DECMOD_CVXZONE void CVXZONE_assign_full(CVXZONE_zone_ptr *arg); |
189 |
|
|
|
190 |
|
|
|
191 |
|
|
/**************************************************************************/ |
192 |
|
|
/***** TEST FUNCTIONS |
193 |
|
|
/**************************************************************************/ |
194 |
|
|
/* Set testing functions. In general these functions may modify even |
195 |
|
|
** operands that are not identified as outputs, because it may be necessary |
196 |
|
|
** to convert sets to canonical form before operations can be performed. |
197 |
|
|
** However, the sets will not be modified so as to change their logical |
198 |
|
|
** value. |
199 |
|
|
*/ |
200 |
|
|
/* Tests whether a zone is empty. Returns TRUE if empty. |
201 |
|
|
*/ |
202 |
|
|
DECMOD_CVXZONE int CVXZONE_test_empty(CVXZONE_zone_ptr *arg); |
203 |
|
|
|
204 |
|
|
/* Tests whether a zone is full. Returns TRUE if full. "Full" means covers all of |
205 |
|
|
** N-dimensional space. |
206 |
|
|
*/ |
207 |
|
|
DECMOD_CVXZONE int CVXZONE_test_full(CVXZONE_zone_ptr *arg); |
208 |
|
|
|
209 |
|
|
/* Tests whether one set is equal to another. Returns TRUE if equal. |
210 |
|
|
*/ |
211 |
|
|
DECMOD_CVXZONE int CVXZONE_test_proper_equal(CVXZONE_zone_ptr *set1, |
212 |
|
|
CVXZONE_zone_ptr *set2); |
213 |
|
|
|
214 |
|
|
/* Tests whether a point belongs to a set. The point is specified as |
215 |
|
|
** an integer array, with n entries, giving the successive coordinates. |
216 |
|
|
** Element [0] is ignored, and element [1] is the value of x_1, element |
217 |
|
|
** [2] is the value of x_2, etc. Specifying too many coordinates will |
218 |
|
|
** not be detected, as there will be simply no constraints on those |
219 |
|
|
** coordinates and so the extra coordinates will effectively being ignored. |
220 |
|
|
** Specifying too few coordinates may or may not be detected. If a |
221 |
|
|
** constraint is detected which cannot be applied, this will fatally |
222 |
|
|
** terminate the program. |
223 |
|
|
*/ |
224 |
|
|
DECMOD_CVXZONE int CVXZONE_test_point_membership(CVXZONE_zone_ptr *base_set, |
225 |
|
|
int n_coords, |
226 |
|
|
int *coords); |
227 |
|
|
|
228 |
|
|
/* Tests whether one set is a proper subset of another. Returns TRUE if |
229 |
|
|
** it is. |
230 |
|
|
*/ |
231 |
|
|
DECMOD_CVXZONE int CVXZONE_test_proper_subset(CVXZONE_zone_ptr *base_set, |
232 |
|
|
CVXZONE_zone_ptr *potential_subset); |
233 |
|
|
|
234 |
|
|
/* Tests whether one set is an improper subset of another. Returns TRUE if |
235 |
|
|
** it is. An improper subset is just like a subset, but equality is allowed. |
236 |
|
|
*/ |
237 |
|
|
DECMOD_CVXZONE int CVXZONE_test_improper_subset(CVXZONE_zone_ptr *base_set, |
238 |
|
|
CVXZONE_zone_ptr *potential_subset); |
239 |
|
|
|
240 |
|
|
/**************************************************************************/ |
241 |
|
|
/***** MODIFICATION FUNCTIONS |
242 |
|
|
/**************************************************************************/ |
243 |
|
|
/* Adds a constraint to a set. The constraint is of the form |
244 |
|
|
** arg1 - arg2 <|<= k. A variable with index 0 is a special case, |
245 |
|
|
** and this is treated as zero (i.e. it is a fictional variable). |
246 |
|
|
** The "eq" flag makes the difference between "<" and "<=". If "eq" is |
247 |
|
|
** TRUE, then "<=" is assumed. |
248 |
|
|
** |
249 |
|
|
** The set is the intersection of all the half-[hyper]regions formed by the |
250 |
|
|
** constraints. Note that forming a set by repeatedly adding constraints |
251 |
|
|
** only works if set used to start is the "full" set. Adding any constraints |
252 |
|
|
** to an empty set will only result in an empty set that will be cleaned up the |
253 |
|
|
** next time it is canonized. |
254 |
|
|
*/ |
255 |
|
|
DECMOD_CVXZONE void CVXZONE_modify_add_constraint(CVXZONE_zone_ptr *base_set, |
256 |
|
|
int arg1_idx, |
257 |
|
|
int arg2_idx, |
258 |
|
|
int eq, |
259 |
|
|
int k); |
260 |
|
|
|
261 |
|
|
|
262 |
|
|
/**************************************************************************/ |
263 |
|
|
/***** CALCULATION FUNCTIONS |
264 |
|
|
/**************************************************************************/ |
265 |
|
|
/* Calculates the intersection of two sets and assigns it to a third set, which |
266 |
|
|
** must exist. (BTW, note that union cannot be calculated in this framework, |
267 |
|
|
** because it might result in a set which is not convex. That is why no unioning |
268 |
|
|
** function is provided here.) |
269 |
|
|
*/ |
270 |
|
|
DECMOD_CVXZONE void CVXZONE_calculate_intersection(CVXZONE_zone_ptr *dst, |
271 |
|
|
CVXZONE_zone_ptr *src1, |
272 |
|
|
CVXZONE_zone_ptr *src2); |
273 |
|
|
|
274 |
|
|
#endif |
275 |
|
|
|
276 |
|
|
//End of ccvxzone.h. |