1 /*
2  * vec.h --  Vector macros for 2,3, and 4 dimensions,
3  *           for any  combination of C scalar types.
4  *
5  * Author:              Don Hatch (hatch@hadron.org)
6  * Last modified:       Tue Apr 13 21:58:39 PDT 1999
7  *
8  * General description:
9  *
10  *      The macro name describes its arguments; e.g.
11  *              MXS3 is "matrix times scalar in 3 dimensions";
12  *              VMV2 is "vector minus vector in 2 dimensions".
13  *
14  *      If the result of an operation is a scalar, then the macro "returns"
15  *      the value; e.g.
16  *              result = DOT3(v,w);
17  *              result = DET4(m);
18  *
19  *      If the result of an operation is a vector or matrix, then
20  *      the first argument is the destination; e.g.
21  *              SET2(tovec, fromvec);
22  *              MXM3(result, m1, m2);
23  *
24  *  WARNING: For the operations that are not done "componentwise"
25  *          (e.g. vector cross products and matrix multiplies)
26  *          the destination should not be either of the arguments,
27  *          for obvious reasons.  For example, the following is wrong:
28  *              VXM2(v,v,m);
29  *          For such "unsafe" macros, there are safe versions provided,
30  *          but you have to specify a type for the temporary
31  *          result vector or matrix.  For example, the safe versions
32  *          of VXM2 are:
33  *              VXM2d(v,v,m)    if v's scalar type is double or float
34  *              VXM2f(v,v,m)    if v's scalar type is float
35  *              VXM2i(v,v,m)    if v's scalar type is int or char
36  *              VXM2l(v,v,m)    if v's scalar type is long
37  *              VXM2r(v,v,m)    if v's scalar type is real
38  *              VXM2safe(type,v,v,m) for other scalar types.
39  *
40  *          These "safe" macros and INVERTMAT do not evaluate to C expressions
41  *          (so, for example, they can't be used inside the parentheses of
42  *          a for(...)).
43  *
44  *  Specific descriptions:
45  *
46  *      The "?"'s in the following can be 2, 3, or 4.
47  *
48  *      EXPAND?(v)                      comma-separated list of elements of v
49  *
50  *      SET?(to,from)                   to = from
51  *      SETMAT?(to,from)                to = from
52  *      ROUNDVEC?(to,from)              to = from with entries rounded
53  *                                                      to nearest integer
54  *      ROUNDMAT?(to,from)              to = from with entries rounded
55  *                                                      to nearest integer
56  *      FILLVEC?(v,s)                   set each entry of vector v to be s
57  *      FILLMAT?(m,s)                   set each entry of matrix m to be s
58  *      ZEROVEC?(v)                     v = 0
59  *      ISZEROVEC?(v)                   v == 0
60  *      EQVEC?(v,w)                     v == w
61  *      EQMAT?(m1,m2)                   m1 == m2
62  *      ZEROMAT?(m)                     m = 0
63  *      IDENTMAT?(m)                    m = 1
64  *      TRANSPOSE?(to,from)             (matrix to) = (transpose of matrix from)
65  *      ADJOINT?(to,from)               (matrix to) = (adjoint of matrix from)
66  *                                       i.e. its determinant times its inverse
67  *      INVERTMAT?{d,f,i,l,r}(to,from)  (matrix to) = (inverse of matrix from)
68  *                               with temp adjoint and determinant type
69  *                               double, float, int, long, or real respectively
70  *
71  *      V{P,M}V?(to,v,w)                to = v {+,-} w
72  *      M{P,M}M?(to,m1,m2)              to = m1 {+,-} m2
73  *      SX{V,M}?(to,s,from)             to = s * from
74  *      VPSXV?(to,v,s,w)                to = v + s*w
75  *      VPVXS?(to,v,w,s)                to = v + w*s
76  *      M{V,M}?(to,from)                to = -from
77  *      {V,M}{X,D}S?(to,from,s)         to = from {*,/} s
78  *      MXM?(to,m1,m2)                  to = m1 * m2
79  *      VXM?(to,v,m)                    (row vec to) = (row vec v) * m
80  *      MXV?(to,m,v)                    (column vec to) = m * (column vec v)
81  *      VMODS?(to,v,s)                  to = v mod s (always >= 0)
82  *      VMODV?(to,v0,v1)                to = v0 mod v1 componentwise
83  *      VDIVS?(to,v,s)                  to = (v-(v mod s))/s
84  *      VDIVV?(to,v0,v1)                to = (v0-(v0 mod v1))/v1 componentwise
85  *      V{MIN,MAX}S?(to,v,s)            to = {MIN,MAX}(v, s)
86  *      V{MIN,MAX}V?(to,v0,v1)          to = {MIN,MAX}(v0, v1)
87  *      LERP?(to,v0,v1,t)               to = v0 + t*(v1-v0)
88  *
89  *      DET?(m)                         determinant of m
90  *      TRACE?(m)                       trace (sum of diagonal entries) of m
91  *      DOT?(v,w)                       dot (scalar) product of v and w
92  *      NORMSQRD?(v)                    square of |v|
93  *      DISTSQRD?(v,w)                  square of |v-w|
94  *
95  *      XV2(to,v)                       to = v rotated by 90 degrees
96  *      VXV3(to,v1,v2)                  to = cross (vector) product of v1 and v2
97  *      VXVXV4(to,v1,v2,v3)             to = 4-dimensional vector cross product
98  *                                       of v1,v2,v3 (a vector orthogonal to
99  *                                       v1,v2,v3 whose length equals the
100  *                                       volume of the spanned parallelotope)
101  *      VXV2(v0,v1)                     determinant of matrix with rows v0,v1
102  *      VXVXV3(v0,v1,v2)                determinant of matrix with rows v0,v1,v2
103  *      VXVXVXV4(v0,v1,v2,v3)           determinant of matrix with rows v0,..,v3
104  *
105  *   The following macros mix objects from different dimensions.
106  *   For example, V3XM4 would be used to apply a composite
107  *   4x4 rotation-and-translation matrix to a 3d vector.
108  *
109  *      SET3from2(to,from,pad)          (3d vec to) = (2d vec from) with pad
110  *      SET4from3(to,from,pad)          (4d vec to) = (3d vec from) with pad
111  *      SETMAT3from2(to,from,pad0,pad1) (3x3 mat to) = (2x2 mat from)
112  *                                       padded with pad0 on the sides
113  *                                       and pad1 in the corner
114  *      SETMAT4from3(to,from,pad0,pad1) (4x4 mat to) = (3x3 mat from)
115  *                                       padded with pad0 on the sides
116  *                                       and pad1 in the corner
117  *      V2XM3(to2,v2,m3)       (2d row vec to2) = (2d row vec v2) * (3x3 mat m3)
118  *      V3XM4(to3,v3,m4)       (3d row vec to3) = (3d row vec v2) * (4x4 mat m4)
119  *      M3XV2(to2,m3,v2)       (2d col vec to2) = (3x3 mat m3) * (2d col vec v2)
120  *      M4XV3(to3,m4,v3)       (3d col vec to3) = (4x4 mat m4) * (3d col vec v3)
121  *      M2XM3(to3,m2,m3)       (3x3 mat to3) = (2x2 mat m2) * (3x3 mat m3)
122  *      M3XM4(to4,m3,m4)       (4x4 mat to4) = (3x3 mat m3) * (4x4 mat m4)
123  *      M3XM2(to3,m3,m2)       (3x3 mat to3) = (3x3 mat m3) * (2x2 mat m2)
124  *      M4XM3(to4,m4,m3)       (4x4 mat to4) = (4x4 mat m4) * (3x3 mat m3)
125  *
126  *
127  *   This file is machine-generated and can be regenerated
128  *   for any number of dimensions.
129  *   The program that generated it is available upon request.
130  */
131 
132 #ifndef VEC_H
133 #define VEC_H 4
134 
135 #undef TRACE2
136 #undef TRACE3
137 
138 #include <math.h>   /* for definition of floor() */
139 
140 #define EXPAND2(v) (v)[0], (v)[1]
141 #define EXPAND3(v) (v)[0], (v)[1], (v)[2]
142 #define EXPAND4(v) (v)[0], (v)[1], (v)[2], (v)[3]
143 #define SET2(to,from)	\
144 		((to)[0] = (from)[0], \
145 		 (to)[1] = (from)[1])
146 #define SETMAT2(to,from)	\
147 		(SET2((to)[0], (from)[0]), \
148 		 SET2((to)[1], (from)[1]))
149 #define ROUNDVEC2(to,from)	\
150 		((to)[0] = (int)floor((from)[0]+.5), \
151 		 (to)[1] = (int)floor((from)[1]+.5))
152 #define ROUNDMAT2(to,from)	\
153 		(ROUNDVEC2((to)[0], (from)[0]), \
154 		 ROUNDVEC2((to)[1], (from)[1]))
155 #define FILLVEC2(v,s)	\
156 		((v)[0] = (s), \
157 		 (v)[1] = (s))
158 #define FILLMAT2(m,s)	\
159 		(FILLVEC2((m)[0], s), \
160 		 FILLVEC2((m)[1], s))
161 #define ZEROVEC2(v)	\
162 		((v)[0] = 0, \
163 		 (v)[1] = 0)
164 #define ISZEROVEC2(v)	\
165 		((v)[0] == 0 && \
166 		 (v)[1] == 0)
167 #define EQVEC2(v,w)	\
168 		((v)[0] == (w)[0] && \
169 		 (v)[1] == (w)[1])
170 #define EQMAT2(m1,m2)	\
171 		(EQVEC2((m1)[0], (m2)[0]) && \
172 		 EQVEC2((m1)[1], (m2)[1]))
173 #define ZEROMAT2(m)	\
174 		(ZEROVEC2((m)[0]), \
175 		 ZEROVEC2((m)[1]))
176 #define IDENTMAT2(m)	\
177 		(ZEROVEC2((m)[0]), (m)[0][0]=1, \
178 		 ZEROVEC2((m)[1]), (m)[1][1]=1)
179 #define TRANSPOSE2(to,from)	\
180 		(_SETcol2((to)[0], from, 0), \
181 		 _SETcol2((to)[1], from, 1))
182 #define VPSXV2(to,v,s,w)	\
183 		((to)[0] = (v)[0] + (s) * (w)[0], \
184 		 (to)[1] = (v)[1] + (s) * (w)[1])
185 #define VPVXS2(to,v,w,s)	\
186 		((to)[0] = (v)[0] + (w)[0] * (s), \
187 		 (to)[1] = (v)[1] + (w)[1] * (s))
188 #define VPV2(to,v,w)	\
189 		((to)[0] = (v)[0] + (w)[0], \
190 		 (to)[1] = (v)[1] + (w)[1])
191 #define VMV2(to,v,w)	\
192 		((to)[0] = (v)[0] - (w)[0], \
193 		 (to)[1] = (v)[1] - (w)[1])
194 #define MPM2(to,m1,m2)	\
195 		(VPV2((to)[0], (m1)[0], (m2)[0]), \
196 		 VPV2((to)[1], (m1)[1], (m2)[1]))
197 #define MMM2(to,m1,m2)	\
198 		(VMV2((to)[0], (m1)[0], (m2)[0]), \
199 		 VMV2((to)[1], (m1)[1], (m2)[1]))
200 #define SXV2(to,s,from)	\
201 		((to)[0] = (s) * (from)[0], \
202 		 (to)[1] = (s) * (from)[1])
203 #define SXM2(to,s,from)	\
204 		(SXV2((to)[0], s, (from)[0]), \
205 		 SXV2((to)[1], s, (from)[1]))
206 #define MV2(to,from)	\
207 		((to)[0] = -(from)[0], \
208 		 (to)[1] = -(from)[1])
209 #define MM2(to,from)	\
210 		(MV2((to)[0], (from)[0]), \
211 		 MV2((to)[1], (from)[1]))
212 #define VXS2(to,from,s)	\
213 		((to)[0] = (from)[0] * (s), \
214 		 (to)[1] = (from)[1] * (s))
215 #define VDS2(to,from,s)	\
216 		((to)[0] = (from)[0] / (s), \
217 		 (to)[1] = (from)[1] / (s))
218 #define MXS2(to,from,s)	\
219 		(VXS2((to)[0], (from)[0], s), \
220 		 VXS2((to)[1], (from)[1], s))
221 #define MDS2(to,from,s)	\
222 		(VDS2((to)[0], (from)[0], s), \
223 		 VDS2((to)[1], (from)[1], s))
224 #define MXM2(to,m1,m2)	\
225 		(VXM2((to)[0], (m1)[0], m2), \
226 		 VXM2((to)[1], (m1)[1], m2))
227 #define VXM2(to,v,m)	\
228 		((to)[0] = _DOTcol2(v, m, 0), \
229 		 (to)[1] = _DOTcol2(v, m, 1))
230 #define MXV2(to,m,v)	\
231 		((to)[0] = DOT2((m)[0], v), \
232 		 (to)[1] = DOT2((m)[1], v))
233 #define VMODS2(to,v,s)	\
234 		((to)[0] = SMODS1((v)[0], s), \
235 		 (to)[1] = SMODS1((v)[1], s))
236 #define VMODV2(to,v0,v1)	\
237 		((to)[0] = SMODS1((v0)[0], (v1)[0]), \
238 		 (to)[1] = SMODS1((v0)[1], (v1)[1]))
239 #define VDIVS2(to,v,s)	\
240 		((to)[0] = SDIVS1((v)[0], s), \
241 		 (to)[1] = SDIVS1((v)[1], s))
242 #define VDIVV2(to,v0,v1)	\
243 		((to)[0] = SDIVS1((v0)[0], (v1)[0]), \
244 		 (to)[1] = SDIVS1((v0)[1], (v1)[1]))
245 #define VMINS2(to,v,s)	\
246 		((to)[0] = SMINS1((v)[0], s), \
247 		 (to)[1] = SMINS1((v)[1], s))
248 #define VMINV2(to,v0,v1)	\
249 		((to)[0] = SMINS1((v0)[0], (v1)[0]), \
250 		 (to)[1] = SMINS1((v0)[1], (v1)[1]))
251 #define VMAXS2(to,v,s)	\
252 		((to)[0] = SMAXS1((v)[0], s), \
253 		 (to)[1] = SMAXS1((v)[1], s))
254 #define VMAXV2(to,v0,v1)	\
255 		((to)[0] = SMAXS1((v0)[0], (v1)[0]), \
256 		 (to)[1] = SMAXS1((v0)[1], (v1)[1]))
257 #define LERP2(to,v0,v1,t)	\
258 		((to)[0]=(v0)[0]+(t)*((v1)[0]-(v0)[0]), \
259 		 (to)[1]=(v0)[1]+(t)*((v1)[1]-(v0)[1]))
260 #define TRACE2(m)	\
261 		((m)[0][0] + \
262 		 (m)[1][1])
263 #define DOT2(v,w)	\
264 		((v)[0] * (w)[0] + \
265 		 (v)[1] * (w)[1])
266 #define NORMSQRD2(v)	\
267 		((v)[0] * (v)[0] + \
268 		 (v)[1] * (v)[1])
269 #define DISTSQRD2(v,w)	\
270 		(((v)[0]-(w)[0])*((v)[0]-(w)[0]) + \
271 		 ((v)[1]-(w)[1])*((v)[1]-(w)[1]))
272 #define _DOTcol2(v,m,j)	\
273 		((v)[0] * (m)[0][j] + \
274 		 (v)[1] * (m)[1][j])
275 #define _SETcol2(v,m,j)	\
276 		((v)[0] = (m)[0][j], \
277 		 (v)[1] = (m)[1][j])
278 #define _MXVcol2(to,m,M,j)	\
279 		((to)[0][j] = _DOTcol2((m)[0],M,j), \
280 		 (to)[1][j] = _DOTcol2((m)[1],M,j))
281 #define _DET2(v0,v1,i0,i1)	\
282 		((v0)[i0]* _DET1(v1,i1) + \
283 		 (v0)[i1]*-_DET1(v1,i0))
284 #define XV2(to,v1)	\
285 		((to)[0] = -_DET1(v1, 1), \
286 		 (to)[1] =  _DET1(v1, 0))
287 #define V2XM3(to2,v2,m3)	\
288 		((to2)[0] = _DOTcol2(v2,m3,0) + (m3)[2][0], \
289 		 (to2)[1] = _DOTcol2(v2,m3,1) + (m3)[2][1])
290 #define M3XV2(to2,m3,v2)	\
291 		((to2)[0] = DOT2((m3)[0],v2) + (m3)[0][2], \
292 		 (to2)[1] = DOT2((m3)[1],v2) + (m3)[1][2])
293 #define _DET1(v0,i0)	\
294 		((v0)[i0])
295 #define VXV2(v0,v1)	\
296 		(_DET2(v0,v1,0,1))
297 #define DET2(m)	\
298 		(VXV2((m)[0],(m)[1]))
299 #define SMODS1(a,b)	\
300 		((((a)%(b)+(b))%(b)))
301 #define SDIVS1(a,b)	\
302 		((((a)-SMODS1(a,b))/(b)))
303 #define SMINS1(a,b)	\
304 		(((a) < (b) ? (a) : (b)))
305 #define SMAXS1(a,b)	\
306 		(((a) > (b) ? (a) : (b)))
307 #define ADJOINT2(to,m)	\
308 		( _ADJOINTcol2(to,0,m,1), \
309 		 __ADJOINTcol2(to,1,m,0))
310 #define _ADJOINTcol2(to,col,m,i1)	\
311 		((to)[0][col] =  _DET1((m)[i1], 1), \
312 		 (to)[1][col] = -_DET1((m)[i1], 0))
313 #define __ADJOINTcol2(to,col,m,i1)	\
314 		((to)[0][col] = -_DET1((m)[i1], 1), \
315 		 (to)[1][col] =  _DET1((m)[i1], 0))
316 #define SET3(to,from)	\
317 		((to)[0] = (from)[0], \
318 		 (to)[1] = (from)[1], \
319 		 (to)[2] = (from)[2])
320 #define SETMAT3(to,from)	\
321 		(SET3((to)[0], (from)[0]), \
322 		 SET3((to)[1], (from)[1]), \
323 		 SET3((to)[2], (from)[2]))
324 #define ROUNDVEC3(to,from)	\
325 		((to)[0] = (int)floor((from)[0]+.5), \
326 		 (to)[1] = (int)floor((from)[1]+.5), \
327 		 (to)[2] = (int)floor((from)[2]+.5))
328 #define ROUNDMAT3(to,from)	\
329 		(ROUNDVEC3((to)[0], (from)[0]), \
330 		 ROUNDVEC3((to)[1], (from)[1]), \
331 		 ROUNDVEC3((to)[2], (from)[2]))
332 #define FILLVEC3(v,s)	\
333 		((v)[0] = (s), \
334 		 (v)[1] = (s), \
335 		 (v)[2] = (s))
336 #define FILLMAT3(m,s)	\
337 		(FILLVEC3((m)[0], s), \
338 		 FILLVEC3((m)[1], s), \
339 		 FILLVEC3((m)[2], s))
340 #define ZEROVEC3(v)	\
341 		((v)[0] = 0, \
342 		 (v)[1] = 0, \
343 		 (v)[2] = 0)
344 #define ISZEROVEC3(v)	\
345 		((v)[0] == 0 && \
346 		 (v)[1] == 0 && \
347 		 (v)[2] == 0)
348 #define EQVEC3(v,w)	\
349 		((v)[0] == (w)[0] && \
350 		 (v)[1] == (w)[1] && \
351 		 (v)[2] == (w)[2])
352 #define EQMAT3(m1,m2)	\
353 		(EQVEC3((m1)[0], (m2)[0]) && \
354 		 EQVEC3((m1)[1], (m2)[1]) && \
355 		 EQVEC3((m1)[2], (m2)[2]))
356 #define ZEROMAT3(m)	\
357 		(ZEROVEC3((m)[0]), \
358 		 ZEROVEC3((m)[1]), \
359 		 ZEROVEC3((m)[2]))
360 #define IDENTMAT3(m)	\
361 		(ZEROVEC3((m)[0]), (m)[0][0]=1, \
362 		 ZEROVEC3((m)[1]), (m)[1][1]=1, \
363 		 ZEROVEC3((m)[2]), (m)[2][2]=1)
364 #define TRANSPOSE3(to,from)	\
365 		(_SETcol3((to)[0], from, 0), \
366 		 _SETcol3((to)[1], from, 1), \
367 		 _SETcol3((to)[2], from, 2))
368 #define VPSXV3(to,v,s,w)	\
369 		((to)[0] = (v)[0] + (s) * (w)[0], \
370 		 (to)[1] = (v)[1] + (s) * (w)[1], \
371 		 (to)[2] = (v)[2] + (s) * (w)[2])
372 #define VPVXS3(to,v,w,s)	\
373 		((to)[0] = (v)[0] + (w)[0] * (s), \
374 		 (to)[1] = (v)[1] + (w)[1] * (s), \
375 		 (to)[2] = (v)[2] + (w)[2] * (s))
376 #define VPV3(to,v,w)	\
377 		((to)[0] = (v)[0] + (w)[0], \
378 		 (to)[1] = (v)[1] + (w)[1], \
379 		 (to)[2] = (v)[2] + (w)[2])
380 #define VMV3(to,v,w)	\
381 		((to)[0] = (v)[0] - (w)[0], \
382 		 (to)[1] = (v)[1] - (w)[1], \
383 		 (to)[2] = (v)[2] - (w)[2])
384 #define MPM3(to,m1,m2)	\
385 		(VPV3((to)[0], (m1)[0], (m2)[0]), \
386 		 VPV3((to)[1], (m1)[1], (m2)[1]), \
387 		 VPV3((to)[2], (m1)[2], (m2)[2]))
388 #define MMM3(to,m1,m2)	\
389 		(VMV3((to)[0], (m1)[0], (m2)[0]), \
390 		 VMV3((to)[1], (m1)[1], (m2)[1]), \
391 		 VMV3((to)[2], (m1)[2], (m2)[2]))
392 #define SXV3(to,s,from)	\
393 		((to)[0] = (s) * (from)[0], \
394 		 (to)[1] = (s) * (from)[1], \
395 		 (to)[2] = (s) * (from)[2])
396 #define SXM3(to,s,from)	\
397 		(SXV3((to)[0], s, (from)[0]), \
398 		 SXV3((to)[1], s, (from)[1]), \
399 		 SXV3((to)[2], s, (from)[2]))
400 #define MV3(to,from)	\
401 		((to)[0] = -(from)[0], \
402 		 (to)[1] = -(from)[1], \
403 		 (to)[2] = -(from)[2])
404 #define MM3(to,from)	\
405 		(MV3((to)[0], (from)[0]), \
406 		 MV3((to)[1], (from)[1]), \
407 		 MV3((to)[2], (from)[2]))
408 #define VXS3(to,from,s)	\
409 		((to)[0] = (from)[0] * (s), \
410 		 (to)[1] = (from)[1] * (s), \
411 		 (to)[2] = (from)[2] * (s))
412 #define VDS3(to,from,s)	\
413 		((to)[0] = (from)[0] / (s), \
414 		 (to)[1] = (from)[1] / (s), \
415 		 (to)[2] = (from)[2] / (s))
416 #define MXS3(to,from,s)	\
417 		(VXS3((to)[0], (from)[0], s), \
418 		 VXS3((to)[1], (from)[1], s), \
419 		 VXS3((to)[2], (from)[2], s))
420 #define MDS3(to,from,s)	\
421 		(VDS3((to)[0], (from)[0], s), \
422 		 VDS3((to)[1], (from)[1], s), \
423 		 VDS3((to)[2], (from)[2], s))
424 #define MXM3(to,m1,m2)	\
425 		(VXM3((to)[0], (m1)[0], m2), \
426 		 VXM3((to)[1], (m1)[1], m2), \
427 		 VXM3((to)[2], (m1)[2], m2))
428 #define VXM3(to,v,m)	\
429 		((to)[0] = _DOTcol3(v, m, 0), \
430 		 (to)[1] = _DOTcol3(v, m, 1), \
431 		 (to)[2] = _DOTcol3(v, m, 2))
432 #define MXV3(to,m,v)	\
433 		((to)[0] = DOT3((m)[0], v), \
434 		 (to)[1] = DOT3((m)[1], v), \
435 		 (to)[2] = DOT3((m)[2], v))
436 #define VMODS3(to,v,s)	\
437 		((to)[0] = SMODS1((v)[0], s), \
438 		 (to)[1] = SMODS1((v)[1], s), \
439 		 (to)[2] = SMODS1((v)[2], s))
440 #define VMODV3(to,v0,v1)	\
441 		((to)[0] = SMODS1((v0)[0], (v1)[0]), \
442 		 (to)[1] = SMODS1((v0)[1], (v1)[1]), \
443 		 (to)[2] = SMODS1((v0)[2], (v1)[2]))
444 #define VDIVS3(to,v,s)	\
445 		((to)[0] = SDIVS1((v)[0], s), \
446 		 (to)[1] = SDIVS1((v)[1], s), \
447 		 (to)[2] = SDIVS1((v)[2], s))
448 #define VDIVV3(to,v0,v1)	\
449 		((to)[0] = SDIVS1((v0)[0], (v1)[0]), \
450 		 (to)[1] = SDIVS1((v0)[1], (v1)[1]), \
451 		 (to)[2] = SDIVS1((v0)[2], (v1)[2]))
452 #define VMINS3(to,v,s)	\
453 		((to)[0] = SMINS1((v)[0], s), \
454 		 (to)[1] = SMINS1((v)[1], s), \
455 		 (to)[2] = SMINS1((v)[2], s))
456 #define VMINV3(to,v0,v1)	\
457 		((to)[0] = SMINS1((v0)[0], (v1)[0]), \
458 		 (to)[1] = SMINS1((v0)[1], (v1)[1]), \
459 		 (to)[2] = SMINS1((v0)[2], (v1)[2]))
460 #define VMAXS3(to,v,s)	\
461 		((to)[0] = SMAXS1((v)[0], s), \
462 		 (to)[1] = SMAXS1((v)[1], s), \
463 		 (to)[2] = SMAXS1((v)[2], s))
464 #define VMAXV3(to,v0,v1)	\
465 		((to)[0] = SMAXS1((v0)[0], (v1)[0]), \
466 		 (to)[1] = SMAXS1((v0)[1], (v1)[1]), \
467 		 (to)[2] = SMAXS1((v0)[2], (v1)[2]))
468 #define LERP3(to,v0,v1,t)	\
469 		((to)[0]=(v0)[0]+(t)*((v1)[0]-(v0)[0]), \
470 		 (to)[1]=(v0)[1]+(t)*((v1)[1]-(v0)[1]), \
471 		 (to)[2]=(v0)[2]+(t)*((v1)[2]-(v0)[2]))
472 #define TRACE3(m)	\
473 		((m)[0][0] + \
474 		 (m)[1][1] + \
475 		 (m)[2][2])
476 #define DOT3(v,w)	\
477 		((v)[0] * (w)[0] + \
478 		 (v)[1] * (w)[1] + \
479 		 (v)[2] * (w)[2])
480 #define NORMSQRD3(v)	\
481 		((v)[0] * (v)[0] + \
482 		 (v)[1] * (v)[1] + \
483 		 (v)[2] * (v)[2])
484 #define DISTSQRD3(v,w)	\
485 		(((v)[0]-(w)[0])*((v)[0]-(w)[0]) + \
486 		 ((v)[1]-(w)[1])*((v)[1]-(w)[1]) + \
487 		 ((v)[2]-(w)[2])*((v)[2]-(w)[2]))
488 #define _DOTcol3(v,m,j)	\
489 		((v)[0] * (m)[0][j] + \
490 		 (v)[1] * (m)[1][j] + \
491 		 (v)[2] * (m)[2][j])
492 #define _SETcol3(v,m,j)	\
493 		((v)[0] = (m)[0][j], \
494 		 (v)[1] = (m)[1][j], \
495 		 (v)[2] = (m)[2][j])
496 #define _MXVcol3(to,m,M,j)	\
497 		((to)[0][j] = _DOTcol3((m)[0],M,j), \
498 		 (to)[1][j] = _DOTcol3((m)[1],M,j), \
499 		 (to)[2][j] = _DOTcol3((m)[2],M,j))
500 #define _DET3(v0,v1,v2,i0,i1,i2)	\
501 		((v0)[i0]* _DET2(v1,v2,i1,i2) + \
502 		 (v0)[i1]*-_DET2(v1,v2,i0,i2) + \
503 		 (v0)[i2]* _DET2(v1,v2,i0,i1))
504 #define VXV3(to,v1,v2)	\
505 		((to)[0] =  _DET2(v1,v2, 1,2), \
506 		 (to)[1] = -_DET2(v1,v2, 0,2), \
507 		 (to)[2] =  _DET2(v1,v2, 0,1))
508 #define SET3from2(to,from,pad)	\
509 		((to)[0] = (from)[0], \
510 		 (to)[1] = (from)[1], \
511 		 (to)[2] = (pad))
512 #define SETMAT3from2(to,from,pad0,pad1)	\
513 		(SET3from2((to)[0], (from)[0], pad0), \
514 		 SET3from2((to)[1], (from)[1], pad0), \
515 		 FILLVEC2((to)[2], (pad0)), (to)[2][2] = (pad1))
516 #define M2XM3(to3,m2,m3)	\
517 		(_MXVcol2(to3,m2,m3,0), (to3)[2][0]=(m3)[2][0], \
518 		 _MXVcol2(to3,m2,m3,1), (to3)[2][1]=(m3)[2][1], \
519 		 _MXVcol2(to3,m2,m3,2), (to3)[2][2]=(m3)[2][2])
520 #define M3XM2(to3,m3,m2)	\
521 		(VXM2((to3)[0],(m3)[0],m2), (to3)[0][2]=(m3)[0][2], \
522 		 VXM2((to3)[1],(m3)[1],m2), (to3)[1][2]=(m3)[1][2], \
523 		 VXM2((to3)[2],(m3)[2],m2), (to3)[2][2]=(m3)[2][2])
524 #define V3XM4(to3,v3,m4)	\
525 		((to3)[0] = _DOTcol3(v3,m4,0) + (m4)[3][0], \
526 		 (to3)[1] = _DOTcol3(v3,m4,1) + (m4)[3][1], \
527 		 (to3)[2] = _DOTcol3(v3,m4,2) + (m4)[3][2])
528 #define M4XV3(to3,m4,v3)	\
529 		((to3)[0] = DOT3((m4)[0],v3) + (m4)[0][3], \
530 		 (to3)[1] = DOT3((m4)[1],v3) + (m4)[1][3], \
531 		 (to3)[2] = DOT3((m4)[2],v3) + (m4)[2][3])
532 #define VXVXV3(v0,v1,v2)	\
533 		(_DET3(v0,v1,v2,0,1,2))
534 #define DET3(m)	\
535 		(VXVXV3((m)[0],(m)[1],(m)[2]))
536 #define ADJOINT3(to,m)	\
537 		( _ADJOINTcol3(to,0,m,1,2), \
538 		 __ADJOINTcol3(to,1,m,0,2), \
539 		  _ADJOINTcol3(to,2,m,0,1))
540 #define _ADJOINTcol3(to,col,m,i1,i2)	\
541 		((to)[0][col] =  _DET2((m)[i1],(m)[i2], 1,2), \
542 		 (to)[1][col] = -_DET2((m)[i1],(m)[i2], 0,2), \
543 		 (to)[2][col] =  _DET2((m)[i1],(m)[i2], 0,1))
544 #define __ADJOINTcol3(to,col,m,i1,i2)	\
545 		((to)[0][col] = -_DET2((m)[i1],(m)[i2], 1,2), \
546 		 (to)[1][col] =  _DET2((m)[i1],(m)[i2], 0,2), \
547 		 (to)[2][col] = -_DET2((m)[i1],(m)[i2], 0,1))
548 #define SET4(to,from)	\
549 		((to)[0] = (from)[0], \
550 		 (to)[1] = (from)[1], \
551 		 (to)[2] = (from)[2], \
552 		 (to)[3] = (from)[3])
553 #define SETMAT4(to,from)	\
554 		(SET4((to)[0], (from)[0]), \
555 		 SET4((to)[1], (from)[1]), \
556 		 SET4((to)[2], (from)[2]), \
557 		 SET4((to)[3], (from)[3]))
558 #define ROUNDVEC4(to,from)	\
559 		((to)[0] = (int)floor((from)[0]+.5), \
560 		 (to)[1] = (int)floor((from)[1]+.5), \
561 		 (to)[2] = (int)floor((from)[2]+.5), \
562 		 (to)[3] = (int)floor((from)[3]+.5))
563 #define ROUNDMAT4(to,from)	\
564 		(ROUNDVEC4((to)[0], (from)[0]), \
565 		 ROUNDVEC4((to)[1], (from)[1]), \
566 		 ROUNDVEC4((to)[2], (from)[2]), \
567 		 ROUNDVEC4((to)[3], (from)[3]))
568 #define FILLVEC4(v,s)	\
569 		((v)[0] = (s), \
570 		 (v)[1] = (s), \
571 		 (v)[2] = (s), \
572 		 (v)[3] = (s))
573 #define FILLMAT4(m,s)	\
574 		(FILLVEC4((m)[0], s), \
575 		 FILLVEC4((m)[1], s), \
576 		 FILLVEC4((m)[2], s), \
577 		 FILLVEC4((m)[3], s))
578 #define ZEROVEC4(v)	\
579 		((v)[0] = 0, \
580 		 (v)[1] = 0, \
581 		 (v)[2] = 0, \
582 		 (v)[3] = 0)
583 #define ISZEROVEC4(v)	\
584 		((v)[0] == 0 && \
585 		 (v)[1] == 0 && \
586 		 (v)[2] == 0 && \
587 		 (v)[3] == 0)
588 #define EQVEC4(v,w)	\
589 		((v)[0] == (w)[0] && \
590 		 (v)[1] == (w)[1] && \
591 		 (v)[2] == (w)[2] && \
592 		 (v)[3] == (w)[3])
593 #define EQMAT4(m1,m2)	\
594 		(EQVEC4((m1)[0], (m2)[0]) && \
595 		 EQVEC4((m1)[1], (m2)[1]) && \
596 		 EQVEC4((m1)[2], (m2)[2]) && \
597 		 EQVEC4((m1)[3], (m2)[3]))
598 #define ZEROMAT4(m)	\
599 		(ZEROVEC4((m)[0]), \
600 		 ZEROVEC4((m)[1]), \
601 		 ZEROVEC4((m)[2]), \
602 		 ZEROVEC4((m)[3]))
603 #define IDENTMAT4(m)	\
604 		(ZEROVEC4((m)[0]), (m)[0][0]=1, \
605 		 ZEROVEC4((m)[1]), (m)[1][1]=1, \
606 		 ZEROVEC4((m)[2]), (m)[2][2]=1, \
607 		 ZEROVEC4((m)[3]), (m)[3][3]=1)
608 #define TRANSPOSE4(to,from)	\
609 		(_SETcol4((to)[0], from, 0), \
610 		 _SETcol4((to)[1], from, 1), \
611 		 _SETcol4((to)[2], from, 2), \
612 		 _SETcol4((to)[3], from, 3))
613 #define VPSXV4(to,v,s,w)	\
614 		((to)[0] = (v)[0] + (s) * (w)[0], \
615 		 (to)[1] = (v)[1] + (s) * (w)[1], \
616 		 (to)[2] = (v)[2] + (s) * (w)[2], \
617 		 (to)[3] = (v)[3] + (s) * (w)[3])
618 #define VPVXS4(to,v,w,s)	\
619 		((to)[0] = (v)[0] + (w)[0] * (s), \
620 		 (to)[1] = (v)[1] + (w)[1] * (s), \
621 		 (to)[2] = (v)[2] + (w)[2] * (s), \
622 		 (to)[3] = (v)[3] + (w)[3] * (s))
623 #define VPV4(to,v,w)	\
624 		((to)[0] = (v)[0] + (w)[0], \
625 		 (to)[1] = (v)[1] + (w)[1], \
626 		 (to)[2] = (v)[2] + (w)[2], \
627 		 (to)[3] = (v)[3] + (w)[3])
628 #define VMV4(to,v,w)	\
629 		((to)[0] = (v)[0] - (w)[0], \
630 		 (to)[1] = (v)[1] - (w)[1], \
631 		 (to)[2] = (v)[2] - (w)[2], \
632 		 (to)[3] = (v)[3] - (w)[3])
633 #define MPM4(to,m1,m2)	\
634 		(VPV4((to)[0], (m1)[0], (m2)[0]), \
635 		 VPV4((to)[1], (m1)[1], (m2)[1]), \
636 		 VPV4((to)[2], (m1)[2], (m2)[2]), \
637 		 VPV4((to)[3], (m1)[3], (m2)[3]))
638 #define MMM4(to,m1,m2)	\
639 		(VMV4((to)[0], (m1)[0], (m2)[0]), \
640 		 VMV4((to)[1], (m1)[1], (m2)[1]), \
641 		 VMV4((to)[2], (m1)[2], (m2)[2]), \
642 		 VMV4((to)[3], (m1)[3], (m2)[3]))
643 #define SXV4(to,s,from)	\
644 		((to)[0] = (s) * (from)[0], \
645 		 (to)[1] = (s) * (from)[1], \
646 		 (to)[2] = (s) * (from)[2], \
647 		 (to)[3] = (s) * (from)[3])
648 #define SXM4(to,s,from)	\
649 		(SXV4((to)[0], s, (from)[0]), \
650 		 SXV4((to)[1], s, (from)[1]), \
651 		 SXV4((to)[2], s, (from)[2]), \
652 		 SXV4((to)[3], s, (from)[3]))
653 #define MV4(to,from)	\
654 		((to)[0] = -(from)[0], \
655 		 (to)[1] = -(from)[1], \
656 		 (to)[2] = -(from)[2], \
657 		 (to)[3] = -(from)[3])
658 #define MM4(to,from)	\
659 		(MV4((to)[0], (from)[0]), \
660 		 MV4((to)[1], (from)[1]), \
661 		 MV4((to)[2], (from)[2]), \
662 		 MV4((to)[3], (from)[3]))
663 #define VXS4(to,from,s)	\
664 		((to)[0] = (from)[0] * (s), \
665 		 (to)[1] = (from)[1] * (s), \
666 		 (to)[2] = (from)[2] * (s), \
667 		 (to)[3] = (from)[3] * (s))
668 #define VDS4(to,from,s)	\
669 		((to)[0] = (from)[0] / (s), \
670 		 (to)[1] = (from)[1] / (s), \
671 		 (to)[2] = (from)[2] / (s), \
672 		 (to)[3] = (from)[3] / (s))
673 #define MXS4(to,from,s)	\
674 		(VXS4((to)[0], (from)[0], s), \
675 		 VXS4((to)[1], (from)[1], s), \
676 		 VXS4((to)[2], (from)[2], s), \
677 		 VXS4((to)[3], (from)[3], s))
678 #define MDS4(to,from,s)	\
679 		(VDS4((to)[0], (from)[0], s), \
680 		 VDS4((to)[1], (from)[1], s), \
681 		 VDS4((to)[2], (from)[2], s), \
682 		 VDS4((to)[3], (from)[3], s))
683 #define MXM4(to,m1,m2)	\
684 		(VXM4((to)[0], (m1)[0], m2), \
685 		 VXM4((to)[1], (m1)[1], m2), \
686 		 VXM4((to)[2], (m1)[2], m2), \
687 		 VXM4((to)[3], (m1)[3], m2))
688 #define VXM4(to,v,m)	\
689 		((to)[0] = _DOTcol4(v, m, 0), \
690 		 (to)[1] = _DOTcol4(v, m, 1), \
691 		 (to)[2] = _DOTcol4(v, m, 2), \
692 		 (to)[3] = _DOTcol4(v, m, 3))
693 #define MXV4(to,m,v)	\
694 		((to)[0] = DOT4((m)[0], v), \
695 		 (to)[1] = DOT4((m)[1], v), \
696 		 (to)[2] = DOT4((m)[2], v), \
697 		 (to)[3] = DOT4((m)[3], v))
698 #define VMODS4(to,v,s)	\
699 		((to)[0] = SMODS1((v)[0], s), \
700 		 (to)[1] = SMODS1((v)[1], s), \
701 		 (to)[2] = SMODS1((v)[2], s), \
702 		 (to)[3] = SMODS1((v)[3], s))
703 #define VMODV4(to,v0,v1)	\
704 		((to)[0] = SMODS1((v0)[0], (v1)[0]), \
705 		 (to)[1] = SMODS1((v0)[1], (v1)[1]), \
706 		 (to)[2] = SMODS1((v0)[2], (v1)[2]), \
707 		 (to)[3] = SMODS1((v0)[3], (v1)[3]))
708 #define VDIVS4(to,v,s)	\
709 		((to)[0] = SDIVS1((v)[0], s), \
710 		 (to)[1] = SDIVS1((v)[1], s), \
711 		 (to)[2] = SDIVS1((v)[2], s), \
712 		 (to)[3] = SDIVS1((v)[3], s))
713 #define VDIVV4(to,v0,v1)	\
714 		((to)[0] = SDIVS1((v0)[0], (v1)[0]), \
715 		 (to)[1] = SDIVS1((v0)[1], (v1)[1]), \
716 		 (to)[2] = SDIVS1((v0)[2], (v1)[2]), \
717 		 (to)[3] = SDIVS1((v0)[3], (v1)[3]))
718 #define VMINS4(to,v,s)	\
719 		((to)[0] = SMINS1((v)[0], s), \
720 		 (to)[1] = SMINS1((v)[1], s), \
721 		 (to)[2] = SMINS1((v)[2], s), \
722 		 (to)[3] = SMINS1((v)[3], s))
723 #define VMINV4(to,v0,v1)	\
724 		((to)[0] = SMINS1((v0)[0], (v1)[0]), \
725 		 (to)[1] = SMINS1((v0)[1], (v1)[1]), \
726 		 (to)[2] = SMINS1((v0)[2], (v1)[2]), \
727 		 (to)[3] = SMINS1((v0)[3], (v1)[3]))
728 #define VMAXS4(to,v,s)	\
729 		((to)[0] = SMAXS1((v)[0], s), \
730 		 (to)[1] = SMAXS1((v)[1], s), \
731 		 (to)[2] = SMAXS1((v)[2], s), \
732 		 (to)[3] = SMAXS1((v)[3], s))
733 #define VMAXV4(to,v0,v1)	\
734 		((to)[0] = SMAXS1((v0)[0], (v1)[0]), \
735 		 (to)[1] = SMAXS1((v0)[1], (v1)[1]), \
736 		 (to)[2] = SMAXS1((v0)[2], (v1)[2]), \
737 		 (to)[3] = SMAXS1((v0)[3], (v1)[3]))
738 #define LERP4(to,v0,v1,t)	\
739 		((to)[0]=(v0)[0]+(t)*((v1)[0]-(v0)[0]), \
740 		 (to)[1]=(v0)[1]+(t)*((v1)[1]-(v0)[1]), \
741 		 (to)[2]=(v0)[2]+(t)*((v1)[2]-(v0)[2]), \
742 		 (to)[3]=(v0)[3]+(t)*((v1)[3]-(v0)[3]))
743 #define TRACE4(m)	\
744 		((m)[0][0] + \
745 		 (m)[1][1] + \
746 		 (m)[2][2] + \
747 		 (m)[3][3])
748 #define DOT4(v,w)	\
749 		((v)[0] * (w)[0] + \
750 		 (v)[1] * (w)[1] + \
751 		 (v)[2] * (w)[2] + \
752 		 (v)[3] * (w)[3])
753 #define NORMSQRD4(v)	\
754 		((v)[0] * (v)[0] + \
755 		 (v)[1] * (v)[1] + \
756 		 (v)[2] * (v)[2] + \
757 		 (v)[3] * (v)[3])
758 #define DISTSQRD4(v,w)	\
759 		(((v)[0]-(w)[0])*((v)[0]-(w)[0]) + \
760 		 ((v)[1]-(w)[1])*((v)[1]-(w)[1]) + \
761 		 ((v)[2]-(w)[2])*((v)[2]-(w)[2]) + \
762 		 ((v)[3]-(w)[3])*((v)[3]-(w)[3]))
763 #define _DOTcol4(v,m,j)	\
764 		((v)[0] * (m)[0][j] + \
765 		 (v)[1] * (m)[1][j] + \
766 		 (v)[2] * (m)[2][j] + \
767 		 (v)[3] * (m)[3][j])
768 #define _SETcol4(v,m,j)	\
769 		((v)[0] = (m)[0][j], \
770 		 (v)[1] = (m)[1][j], \
771 		 (v)[2] = (m)[2][j], \
772 		 (v)[3] = (m)[3][j])
773 #define _MXVcol4(to,m,M,j)	\
774 		((to)[0][j] = _DOTcol4((m)[0],M,j), \
775 		 (to)[1][j] = _DOTcol4((m)[1],M,j), \
776 		 (to)[2][j] = _DOTcol4((m)[2],M,j), \
777 		 (to)[3][j] = _DOTcol4((m)[3],M,j))
778 #define _DET4(v0,v1,v2,v3,i0,i1,i2,i3)	\
779 		((v0)[i0]* _DET3(v1,v2,v3,i1,i2,i3) + \
780 		 (v0)[i1]*-_DET3(v1,v2,v3,i0,i2,i3) + \
781 		 (v0)[i2]* _DET3(v1,v2,v3,i0,i1,i3) + \
782 		 (v0)[i3]*-_DET3(v1,v2,v3,i0,i1,i2))
783 #define VXVXV4(to,v1,v2,v3)	\
784 		((to)[0] = -_DET3(v1,v2,v3, 1,2,3), \
785 		 (to)[1] =  _DET3(v1,v2,v3, 0,2,3), \
786 		 (to)[2] = -_DET3(v1,v2,v3, 0,1,3), \
787 		 (to)[3] =  _DET3(v1,v2,v3, 0,1,2))
788 #define SET4from3(to,from,pad)	\
789 		((to)[0] = (from)[0], \
790 		 (to)[1] = (from)[1], \
791 		 (to)[2] = (from)[2], \
792 		 (to)[3] = (pad))
793 #define SETMAT4from3(to,from,pad0,pad1)	\
794 		(SET4from3((to)[0], (from)[0], pad0), \
795 		 SET4from3((to)[1], (from)[1], pad0), \
796 		 SET4from3((to)[2], (from)[2], pad0), \
797 		 FILLVEC3((to)[3], (pad0)), (to)[3][3] = (pad1))
798 #define M3XM4(to4,m3,m4)	\
799 		(_MXVcol3(to4,m3,m4,0), (to4)[3][0]=(m4)[3][0], \
800 		 _MXVcol3(to4,m3,m4,1), (to4)[3][1]=(m4)[3][1], \
801 		 _MXVcol3(to4,m3,m4,2), (to4)[3][2]=(m4)[3][2], \
802 		 _MXVcol3(to4,m3,m4,3), (to4)[3][3]=(m4)[3][3])
803 #define M4XM3(to4,m4,m3)	\
804 		(VXM3((to4)[0],(m4)[0],m3), (to4)[0][3]=(m4)[0][3], \
805 		 VXM3((to4)[1],(m4)[1],m3), (to4)[1][3]=(m4)[1][3], \
806 		 VXM3((to4)[2],(m4)[2],m3), (to4)[2][3]=(m4)[2][3], \
807 		 VXM3((to4)[3],(m4)[3],m3), (to4)[3][3]=(m4)[3][3])
808 #define VXVXVXV4(v0,v1,v2,v3)	\
809 		(_DET4(v0,v1,v2,v3,0,1,2,3))
810 #define DET4(m)	\
811 		(VXVXVXV4((m)[0],(m)[1],(m)[2],(m)[3]))
812 #define ADJOINT4(to,m)	\
813 		( _ADJOINTcol4(to,0,m,1,2,3), \
814 		 __ADJOINTcol4(to,1,m,0,2,3), \
815 		  _ADJOINTcol4(to,2,m,0,1,3), \
816 		 __ADJOINTcol4(to,3,m,0,1,2))
817 #define _ADJOINTcol4(to,col,m,i1,i2,i3)	\
818 		((to)[0][col] =  _DET3((m)[i1],(m)[i2],(m)[i3], 1,2,3), \
819 		 (to)[1][col] = -_DET3((m)[i1],(m)[i2],(m)[i3], 0,2,3), \
820 		 (to)[2][col] =  _DET3((m)[i1],(m)[i2],(m)[i3], 0,1,3), \
821 		 (to)[3][col] = -_DET3((m)[i1],(m)[i2],(m)[i3], 0,1,2))
822 #define __ADJOINTcol4(to,col,m,i1,i2,i3)	\
823 		((to)[0][col] = -_DET3((m)[i1],(m)[i2],(m)[i3], 1,2,3), \
824 		 (to)[1][col] =  _DET3((m)[i1],(m)[i2],(m)[i3], 0,2,3), \
825 		 (to)[2][col] = -_DET3((m)[i1],(m)[i2],(m)[i3], 0,1,3), \
826 		 (to)[3][col] =  _DET3((m)[i1],(m)[i2],(m)[i3], 0,1,2))
827 #define TRANSPOSE2safe(type,to,from) \
828 		do {type _vec_h_temp_[2][2]; \
829 		    TRANSPOSE2(_vec_h_temp_,from); \
830 		    SETMAT2(to, _vec_h_temp_); \
831 		} while (0)
832 #define TRANSPOSE2d(to,from) TRANSPOSE2safe(double,to,from)
833 #define TRANSPOSE2f(to,from) TRANSPOSE2safe(float,to,from)
834 #define TRANSPOSE2i(to,from) TRANSPOSE2safe(int,to,from)
835 #define TRANSPOSE2l(to,from) TRANSPOSE2safe(long,to,from)
836 #define TRANSPOSE2r(to,from) TRANSPOSE2safe(real,to,from)
837 #define MXM2safe(type,to,m1,m2) \
838 		do {type _vec_h_temp_[2][2]; \
839 		    MXM2(_vec_h_temp_,m1,m2); \
840 		    SETMAT2(to, _vec_h_temp_); \
841 		} while (0)
842 #define MXM2d(to,m1,m2) MXM2safe(double,to,m1,m2)
843 #define MXM2f(to,m1,m2) MXM2safe(float,to,m1,m2)
844 #define MXM2i(to,m1,m2) MXM2safe(int,to,m1,m2)
845 #define MXM2l(to,m1,m2) MXM2safe(long,to,m1,m2)
846 #define MXM2r(to,m1,m2) MXM2safe(real,to,m1,m2)
847 #define VXM2safe(type,to,v,m) \
848 		do {type _vec_h_temp_[2]; \
849 		    VXM2(_vec_h_temp_,v,m); \
850 		    SET2(to, _vec_h_temp_); \
851 		} while (0)
852 #define VXM2d(to,v,m) VXM2safe(double,to,v,m)
853 #define VXM2f(to,v,m) VXM2safe(float,to,v,m)
854 #define VXM2i(to,v,m) VXM2safe(int,to,v,m)
855 #define VXM2l(to,v,m) VXM2safe(long,to,v,m)
856 #define VXM2r(to,v,m) VXM2safe(real,to,v,m)
857 #define MXV2safe(type,to,m,v) \
858 		do {type _vec_h_temp_[2]; \
859 		    MXV2(_vec_h_temp_,m,v); \
860 		    SET2(to, _vec_h_temp_); \
861 		} while (0)
862 #define MXV2d(to,m,v) MXV2safe(double,to,m,v)
863 #define MXV2f(to,m,v) MXV2safe(float,to,m,v)
864 #define MXV2i(to,m,v) MXV2safe(int,to,m,v)
865 #define MXV2l(to,m,v) MXV2safe(long,to,m,v)
866 #define MXV2r(to,m,v) MXV2safe(real,to,m,v)
867 #define XV2safe(type,to,v1) \
868 		do {type _vec_h_temp_[2]; \
869 		    XV2(_vec_h_temp_,v1); \
870 		    SET2(to, _vec_h_temp_); \
871 		} while (0)
872 #define XV2d(to,v1) XV2safe(double,to,v1)
873 #define XV2f(to,v1) XV2safe(float,to,v1)
874 #define XV2i(to,v1) XV2safe(int,to,v1)
875 #define XV2l(to,v1) XV2safe(long,to,v1)
876 #define XV2r(to,v1) XV2safe(real,to,v1)
877 #define V2XM3safe(type,to2,v2,m3) \
878 		do {type _vec_h_temp_[2]; \
879 		    V2XM3(_vec_h_temp_,v2,m3); \
880 		    SET2(to2, _vec_h_temp_); \
881 		} while (0)
882 #define V2XM3d(to2,v2,m3) V2XM3safe(double,to2,v2,m3)
883 #define V2XM3f(to2,v2,m3) V2XM3safe(float,to2,v2,m3)
884 #define V2XM3i(to2,v2,m3) V2XM3safe(int,to2,v2,m3)
885 #define V2XM3l(to2,v2,m3) V2XM3safe(long,to2,v2,m3)
886 #define V2XM3r(to2,v2,m3) V2XM3safe(real,to2,v2,m3)
887 #define M3XV2safe(type,to2,m3,v2) \
888 		do {type _vec_h_temp_[2]; \
889 		    M3XV2(_vec_h_temp_,m3,v2); \
890 		    SET2(to2, _vec_h_temp_); \
891 		} while (0)
892 #define M3XV2d(to2,m3,v2) M3XV2safe(double,to2,m3,v2)
893 #define M3XV2f(to2,m3,v2) M3XV2safe(float,to2,m3,v2)
894 #define M3XV2i(to2,m3,v2) M3XV2safe(int,to2,m3,v2)
895 #define M3XV2l(to2,m3,v2) M3XV2safe(long,to2,m3,v2)
896 #define M3XV2r(to2,m3,v2) M3XV2safe(real,to2,m3,v2)
897 #define ADJOINT2safe(type,to,m) \
898 		do {type _vec_h_temp_[2][2]; \
899 		    ADJOINT2(_vec_h_temp_,m); \
900 		    SETMAT2(to, _vec_h_temp_); \
901 		} while (0)
902 #define ADJOINT2d(to,m) ADJOINT2safe(double,to,m)
903 #define ADJOINT2f(to,m) ADJOINT2safe(float,to,m)
904 #define ADJOINT2i(to,m) ADJOINT2safe(int,to,m)
905 #define ADJOINT2l(to,m) ADJOINT2safe(long,to,m)
906 #define ADJOINT2r(to,m) ADJOINT2safe(real,to,m)
907 #define INVERTMAT2safe(type,to,from) \
908 		do {type _vec_h_temp_[2][2]; \
909 		    type _vec_h_temp_invdet_;\
910 		    ADJOINT2(_vec_h_temp_, from); \
911 		    _vec_h_temp_invdet_ = (type)1/(type)DET2(from); \
912 		    SXM2(to, _vec_h_temp_invdet_, _vec_h_temp_); \
913 		} while (0)
914 #define INVERTMAT2d(to,from) INVERTMAT2safe(double,to,from)
915 #define INVERTMAT2f(to,from) INVERTMAT2safe(float,to,from)
916 #define INVERTMAT2i(to,from) INVERTMAT2safe(int,to,from)
917 #define INVERTMAT2l(to,from) INVERTMAT2safe(long,to,from)
918 #define INVERTMAT2r(to,from) INVERTMAT2safe(real,to,from)
919 #define TRANSPOSE3safe(type,to,from) \
920 		do {type _vec_h_temp_[3][3]; \
921 		    TRANSPOSE3(_vec_h_temp_,from); \
922 		    SETMAT3(to, _vec_h_temp_); \
923 		} while (0)
924 #define TRANSPOSE3d(to,from) TRANSPOSE3safe(double,to,from)
925 #define TRANSPOSE3f(to,from) TRANSPOSE3safe(float,to,from)
926 #define TRANSPOSE3i(to,from) TRANSPOSE3safe(int,to,from)
927 #define TRANSPOSE3l(to,from) TRANSPOSE3safe(long,to,from)
928 #define TRANSPOSE3r(to,from) TRANSPOSE3safe(real,to,from)
929 #define MXM3safe(type,to,m1,m2) \
930 		do {type _vec_h_temp_[3][3]; \
931 		    MXM3(_vec_h_temp_,m1,m2); \
932 		    SETMAT3(to, _vec_h_temp_); \
933 		} while (0)
934 #define MXM3d(to,m1,m2) MXM3safe(double,to,m1,m2)
935 #define MXM3f(to,m1,m2) MXM3safe(float,to,m1,m2)
936 #define MXM3i(to,m1,m2) MXM3safe(int,to,m1,m2)
937 #define MXM3l(to,m1,m2) MXM3safe(long,to,m1,m2)
938 #define MXM3r(to,m1,m2) MXM3safe(real,to,m1,m2)
939 #define VXM3safe(type,to,v,m) \
940 		do {type _vec_h_temp_[3]; \
941 		    VXM3(_vec_h_temp_,v,m); \
942 		    SET3(to, _vec_h_temp_); \
943 		} while (0)
944 #define VXM3d(to,v,m) VXM3safe(double,to,v,m)
945 #define VXM3f(to,v,m) VXM3safe(float,to,v,m)
946 #define VXM3i(to,v,m) VXM3safe(int,to,v,m)
947 #define VXM3l(to,v,m) VXM3safe(long,to,v,m)
948 #define VXM3r(to,v,m) VXM3safe(real,to,v,m)
949 #define MXV3safe(type,to,m,v) \
950 		do {type _vec_h_temp_[3]; \
951 		    MXV3(_vec_h_temp_,m,v); \
952 		    SET3(to, _vec_h_temp_); \
953 		} while (0)
954 #define MXV3d(to,m,v) MXV3safe(double,to,m,v)
955 #define MXV3f(to,m,v) MXV3safe(float,to,m,v)
956 #define MXV3i(to,m,v) MXV3safe(int,to,m,v)
957 #define MXV3l(to,m,v) MXV3safe(long,to,m,v)
958 #define MXV3r(to,m,v) MXV3safe(real,to,m,v)
959 #define VXV3safe(type,to,v1,v2) \
960 		do {type _vec_h_temp_[3]; \
961 		    VXV3(_vec_h_temp_,v1,v2); \
962 		    SET3(to, _vec_h_temp_); \
963 		} while (0)
964 #define VXV3d(to,v1,v2) VXV3safe(double,to,v1,v2)
965 #define VXV3f(to,v1,v2) VXV3safe(float,to,v1,v2)
966 #define VXV3i(to,v1,v2) VXV3safe(int,to,v1,v2)
967 #define VXV3l(to,v1,v2) VXV3safe(long,to,v1,v2)
968 #define VXV3r(to,v1,v2) VXV3safe(real,to,v1,v2)
969 #define M2XM3safe(type,to3,m2,m3) \
970 		do {type _vec_h_temp_[3][3]; \
971 		    M2XM3(_vec_h_temp_,m2,m3); \
972 		    SETMAT3(to3, _vec_h_temp_); \
973 		} while (0)
974 #define M2XM3d(to3,m2,m3) M2XM3safe(double,to3,m2,m3)
975 #define M2XM3f(to3,m2,m3) M2XM3safe(float,to3,m2,m3)
976 #define M2XM3i(to3,m2,m3) M2XM3safe(int,to3,m2,m3)
977 #define M2XM3l(to3,m2,m3) M2XM3safe(long,to3,m2,m3)
978 #define M2XM3r(to3,m2,m3) M2XM3safe(real,to3,m2,m3)
979 #define M3XM2safe(type,to3,m3,m2) \
980 		do {type _vec_h_temp_[3][3]; \
981 		    M3XM2(_vec_h_temp_,m3,m2); \
982 		    SETMAT3(to3, _vec_h_temp_); \
983 		} while (0)
984 #define M3XM2d(to3,m3,m2) M3XM2safe(double,to3,m3,m2)
985 #define M3XM2f(to3,m3,m2) M3XM2safe(float,to3,m3,m2)
986 #define M3XM2i(to3,m3,m2) M3XM2safe(int,to3,m3,m2)
987 #define M3XM2l(to3,m3,m2) M3XM2safe(long,to3,m3,m2)
988 #define M3XM2r(to3,m3,m2) M3XM2safe(real,to3,m3,m2)
989 #define V3XM4safe(type,to3,v3,m4) \
990 		do {type _vec_h_temp_[3]; \
991 		    V3XM4(_vec_h_temp_,v3,m4); \
992 		    SET3(to3, _vec_h_temp_); \
993 		} while (0)
994 #define V3XM4d(to3,v3,m4) V3XM4safe(double,to3,v3,m4)
995 #define V3XM4f(to3,v3,m4) V3XM4safe(float,to3,v3,m4)
996 #define V3XM4i(to3,v3,m4) V3XM4safe(int,to3,v3,m4)
997 #define V3XM4l(to3,v3,m4) V3XM4safe(long,to3,v3,m4)
998 #define V3XM4r(to3,v3,m4) V3XM4safe(real,to3,v3,m4)
999 #define M4XV3safe(type,to3,m4,v3) \
1000 		do {type _vec_h_temp_[3]; \
1001 		    M4XV3(_vec_h_temp_,m4,v3); \
1002 		    SET3(to3, _vec_h_temp_); \
1003 		} while (0)
1004 #define M4XV3d(to3,m4,v3) M4XV3safe(double,to3,m4,v3)
1005 #define M4XV3f(to3,m4,v3) M4XV3safe(float,to3,m4,v3)
1006 #define M4XV3i(to3,m4,v3) M4XV3safe(int,to3,m4,v3)
1007 #define M4XV3l(to3,m4,v3) M4XV3safe(long,to3,m4,v3)
1008 #define M4XV3r(to3,m4,v3) M4XV3safe(real,to3,m4,v3)
1009 #define ADJOINT3safe(type,to,m) \
1010 		do {type _vec_h_temp_[3][3]; \
1011 		    ADJOINT3(_vec_h_temp_,m); \
1012 		    SETMAT3(to, _vec_h_temp_); \
1013 		} while (0)
1014 #define ADJOINT3d(to,m) ADJOINT3safe(double,to,m)
1015 #define ADJOINT3f(to,m) ADJOINT3safe(float,to,m)
1016 #define ADJOINT3i(to,m) ADJOINT3safe(int,to,m)
1017 #define ADJOINT3l(to,m) ADJOINT3safe(long,to,m)
1018 #define ADJOINT3r(to,m) ADJOINT3safe(real,to,m)
1019 #define INVERTMAT3safe(type,to,from) \
1020 		do {type _vec_h_temp_[3][3]; \
1021 		    type _vec_h_temp_invdet_;\
1022 		    ADJOINT3(_vec_h_temp_, from); \
1023 		    _vec_h_temp_invdet_ = (type)1/(type)DET3(from); \
1024 		    SXM3(to, _vec_h_temp_invdet_, _vec_h_temp_); \
1025 		} while (0)
1026 #define INVERTMAT3d(to,from) INVERTMAT3safe(double,to,from)
1027 #define INVERTMAT3f(to,from) INVERTMAT3safe(float,to,from)
1028 #define INVERTMAT3i(to,from) INVERTMAT3safe(int,to,from)
1029 #define INVERTMAT3l(to,from) INVERTMAT3safe(long,to,from)
1030 #define INVERTMAT3r(to,from) INVERTMAT3safe(real,to,from)
1031 #define TRANSPOSE4safe(type,to,from) \
1032 		do {type _vec_h_temp_[4][4]; \
1033 		    TRANSPOSE4(_vec_h_temp_,from); \
1034 		    SETMAT4(to, _vec_h_temp_); \
1035 		} while (0)
1036 #define TRANSPOSE4d(to,from) TRANSPOSE4safe(double,to,from)
1037 #define TRANSPOSE4f(to,from) TRANSPOSE4safe(float,to,from)
1038 #define TRANSPOSE4i(to,from) TRANSPOSE4safe(int,to,from)
1039 #define TRANSPOSE4l(to,from) TRANSPOSE4safe(long,to,from)
1040 #define TRANSPOSE4r(to,from) TRANSPOSE4safe(real,to,from)
1041 #define MXM4safe(type,to,m1,m2) \
1042 		do {type _vec_h_temp_[4][4]; \
1043 		    MXM4(_vec_h_temp_,m1,m2); \
1044 		    SETMAT4(to, _vec_h_temp_); \
1045 		} while (0)
1046 #define MXM4d(to,m1,m2) MXM4safe(double,to,m1,m2)
1047 #define MXM4f(to,m1,m2) MXM4safe(float,to,m1,m2)
1048 #define MXM4i(to,m1,m2) MXM4safe(int,to,m1,m2)
1049 #define MXM4l(to,m1,m2) MXM4safe(long,to,m1,m2)
1050 #define MXM4r(to,m1,m2) MXM4safe(real,to,m1,m2)
1051 #define VXM4safe(type,to,v,m) \
1052 		do {type _vec_h_temp_[4]; \
1053 		    VXM4(_vec_h_temp_,v,m); \
1054 		    SET4(to, _vec_h_temp_); \
1055 		} while (0)
1056 #define VXM4d(to,v,m) VXM4safe(double,to,v,m)
1057 #define VXM4f(to,v,m) VXM4safe(float,to,v,m)
1058 #define VXM4i(to,v,m) VXM4safe(int,to,v,m)
1059 #define VXM4l(to,v,m) VXM4safe(long,to,v,m)
1060 #define VXM4r(to,v,m) VXM4safe(real,to,v,m)
1061 #define MXV4safe(type,to,m,v) \
1062 		do {type _vec_h_temp_[4]; \
1063 		    MXV4(_vec_h_temp_,m,v); \
1064 		    SET4(to, _vec_h_temp_); \
1065 		} while (0)
1066 #define MXV4d(to,m,v) MXV4safe(double,to,m,v)
1067 #define MXV4f(to,m,v) MXV4safe(float,to,m,v)
1068 #define MXV4i(to,m,v) MXV4safe(int,to,m,v)
1069 #define MXV4l(to,m,v) MXV4safe(long,to,m,v)
1070 #define MXV4r(to,m,v) MXV4safe(real,to,m,v)
1071 #define VXVXV4safe(type,to,v1,v2,v3) \
1072 		do {type _vec_h_temp_[4]; \
1073 		    VXVXV4(_vec_h_temp_,v1,v2,v3); \
1074 		    SET4(to, _vec_h_temp_); \
1075 		} while (0)
1076 #define VXVXV4d(to,v1,v2,v3) VXVXV4safe(double,to,v1,v2,v3)
1077 #define VXVXV4f(to,v1,v2,v3) VXVXV4safe(float,to,v1,v2,v3)
1078 #define VXVXV4i(to,v1,v2,v3) VXVXV4safe(int,to,v1,v2,v3)
1079 #define VXVXV4l(to,v1,v2,v3) VXVXV4safe(long,to,v1,v2,v3)
1080 #define VXVXV4r(to,v1,v2,v3) VXVXV4safe(real,to,v1,v2,v3)
1081 #define M3XM4safe(type,to4,m3,m4) \
1082 		do {type _vec_h_temp_[4][4]; \
1083 		    M3XM4(_vec_h_temp_,m3,m4); \
1084 		    SETMAT4(to4, _vec_h_temp_); \
1085 		} while (0)
1086 #define M3XM4d(to4,m3,m4) M3XM4safe(double,to4,m3,m4)
1087 #define M3XM4f(to4,m3,m4) M3XM4safe(float,to4,m3,m4)
1088 #define M3XM4i(to4,m3,m4) M3XM4safe(int,to4,m3,m4)
1089 #define M3XM4l(to4,m3,m4) M3XM4safe(long,to4,m3,m4)
1090 #define M3XM4r(to4,m3,m4) M3XM4safe(real,to4,m3,m4)
1091 #define M4XM3safe(type,to4,m4,m3) \
1092 		do {type _vec_h_temp_[4][4]; \
1093 		    M4XM3(_vec_h_temp_,m4,m3); \
1094 		    SETMAT4(to4, _vec_h_temp_); \
1095 		} while (0)
1096 #define M4XM3d(to4,m4,m3) M4XM3safe(double,to4,m4,m3)
1097 #define M4XM3f(to4,m4,m3) M4XM3safe(float,to4,m4,m3)
1098 #define M4XM3i(to4,m4,m3) M4XM3safe(int,to4,m4,m3)
1099 #define M4XM3l(to4,m4,m3) M4XM3safe(long,to4,m4,m3)
1100 #define M4XM3r(to4,m4,m3) M4XM3safe(real,to4,m4,m3)
1101 #define ADJOINT4safe(type,to,m) \
1102 		do {type _vec_h_temp_[4][4]; \
1103 		    ADJOINT4(_vec_h_temp_,m); \
1104 		    SETMAT4(to, _vec_h_temp_); \
1105 		} while (0)
1106 #define ADJOINT4d(to,m) ADJOINT4safe(double,to,m)
1107 #define ADJOINT4f(to,m) ADJOINT4safe(float,to,m)
1108 #define ADJOINT4i(to,m) ADJOINT4safe(int,to,m)
1109 #define ADJOINT4l(to,m) ADJOINT4safe(long,to,m)
1110 #define ADJOINT4r(to,m) ADJOINT4safe(real,to,m)
1111 #define INVERTMAT4safe(type,to,from) \
1112 		do {type _vec_h_temp_[4][4]; \
1113 		    type _vec_h_temp_invdet_;\
1114 		    ADJOINT4(_vec_h_temp_, from); \
1115 		    _vec_h_temp_invdet_ = (type)1/(type)DET4(from); \
1116 		    SXM4(to, _vec_h_temp_invdet_, _vec_h_temp_); \
1117 		} while (0)
1118 #define INVERTMAT4d(to,from) INVERTMAT4safe(double,to,from)
1119 #define INVERTMAT4f(to,from) INVERTMAT4safe(float,to,from)
1120 #define INVERTMAT4i(to,from) INVERTMAT4safe(int,to,from)
1121 #define INVERTMAT4l(to,from) INVERTMAT4safe(long,to,from)
1122 #define INVERTMAT4r(to,from) INVERTMAT4safe(real,to,from)
1123 #endif /* VEC_H */
1124