1 /*
2   Teem: Tools to process and visualize scientific data and images             .
3   Copyright (C) 2012, 2011, 2010, 2009  University of Chicago
4   Copyright (C) 2008, 2007, 2006, 2005  Gordon Kindlmann
5   Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998  University of Utah
6 
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public License
9   (LGPL) as published by the Free Software Foundation; either
10   version 2.1 of the License, or (at your option) any later version.
11   The terms of redistributing and/or modifying this software also
12   include exceptions to the LGPL that facilitate static linking.
13 
14   This library is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   Lesser General Public License for more details.
18 
19   You should have received a copy of the GNU Lesser General Public License
20   along with this library; if not, write to Free Software Foundation, Inc.,
21   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 */
23 
24 #ifndef TENMACROS_HAS_BEEN_INCLUDED
25 #define TENMACROS_HAS_BEEN_INCLUDED
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /*
32 ******** TEN_T2M, TEN_M2T
33 **
34 ** for going between 7-element list and 9-element matrix
35 ** representations of a symmetric tensor
36 **
37 ** the ordering of the tensor elements is assumed to be:
38 **
39 ** threshold        0
40 ** Dxx Dxy Dxz      1   2   3
41 ** Dxy Dyy Dyz  =  (2)  4   5
42 ** Dxz Dyz Dzz     (3) (5)  6
43 **
44 ** As in ell, the matrix ordering is given by:
45 **
46 **   0  1  2
47 **   3  4  5
48 **   6  7  8
49 **
50 ** Note that TEN_M2T does NOT set the threshold element (index 0),
51 ** and that the threshold value plays no role in TEN_T2M.
52 */
53 
54 #define TEN_T2M(m, t) ( \
55    (m)[0] = (t)[1], (m)[1] = (t)[2], (m)[2] = (t)[3], \
56    (m)[3] = (t)[2], (m)[4] = (t)[4], (m)[5] = (t)[5], \
57    (m)[6] = (t)[3], (m)[7] = (t)[5], (m)[8] = (t)[6] )
58 
59 /* Tue Feb 19 16:36:53 GMT 2008: trying averaging the off-diagonal
60    elements to make better sense of matrices which aren't quite
61    symmetric */
62 #define TEN_M2T(t, m) ( \
63    (t)[1] = (m)[0], \
64    (t)[2] = ((m)[1]+(m)[3])/2.0, \
65    (t)[3] = ((m)[2]+(m)[6])/2.0, \
66    (t)[4] = (m)[4], \
67    (t)[5] = ((m)[5]+(m)[7])/2.0, \
68    (t)[6] = (m)[8] )
69 
70 #define TEN_M2T_TT(t, TT, m) ( \
71    (t)[1] = AIR_CAST(TT, (m)[0]), \
72    (t)[2] = AIR_CAST(TT, ((m)[1]+(m)[3])/2.0), \
73    (t)[3] = AIR_CAST(TT, ((m)[2]+(m)[6])/2.0), \
74    (t)[4] = AIR_CAST(TT, (m)[4]), \
75    (t)[5] = AIR_CAST(TT, ((m)[5]+(m)[7])/2.0), \
76    (t)[6] = AIR_CAST(TT, (m)[8]))
77 
78 #define TEN_TV_MUL(v2, t, v1) \
79   ((v2)[0] = (t)[1]*(v1)[0] + (t)[2]*(v1)[1] + (t)[3]*(v1)[2], \
80    (v2)[1] = (t)[2]*(v1)[0] + (t)[4]*(v1)[1] + (t)[5]*(v1)[2], \
81    (v2)[2] = (t)[3]*(v1)[0] + (t)[5]*(v1)[1] + (t)[6]*(v1)[2])
82 
83 #define TEN_T_EXISTS(t) ( \
84     AIR_EXISTS((t)[0]) \
85  && AIR_EXISTS((t)[1]) \
86  && AIR_EXISTS((t)[2]) \
87  && AIR_EXISTS((t)[3]) \
88  && AIR_EXISTS((t)[4]) \
89  && AIR_EXISTS((t)[5]) \
90  && AIR_EXISTS((t)[6]) )
91 
92 #define TEN_T_SET(t, conf, a, b, c, d, e, f) ( \
93    (t)[0] = (conf), \
94    (t)[1] = (a), (t)[2] = (b), (t)[3] = (c), \
95                  (t)[4] = (d), (t)[5] = (e), \
96                                (t)[6] = (f) )
97 
98 #define TEN_T_SET_TT(t, TT, conf, a, b, c, d, e, f) ( \
99    (t)[0] = AIR_CAST(TT, (conf)), \
100    (t)[1] = AIR_CAST(TT, (a)), \
101    (t)[2] = AIR_CAST(TT, (b)), \
102    (t)[3] = AIR_CAST(TT, (c)), \
103    (t)[4] = AIR_CAST(TT, (d)), \
104    (t)[5] = AIR_CAST(TT, (e)), \
105    (t)[6] = AIR_CAST(TT, (f)))
106 
107 #define TEN_T_COPY(d, s) ( \
108    (d)[0] = (s)[0], \
109    (d)[1] = (s)[1], \
110    (d)[2] = (s)[2], \
111    (d)[3] = (s)[3], \
112    (d)[4] = (s)[4], \
113    (d)[5] = (s)[5], \
114    (d)[6] = (s)[6] )
115 
116 #define TEN_T_COPY_TT(d, TT, s) ( \
117    (d)[0] = AIR_CAST(TT, (s)[0]), \
118    (d)[1] = AIR_CAST(TT, (s)[1]), \
119    (d)[2] = AIR_CAST(TT, (s)[2]), \
120    (d)[3] = AIR_CAST(TT, (s)[3]), \
121    (d)[4] = AIR_CAST(TT, (s)[4]), \
122    (d)[5] = AIR_CAST(TT, (s)[5]), \
123    (d)[6] = AIR_CAST(TT, (s)[6]) )
124 
125 #define TEN_T_DET(t) ( \
126   (t)[1]*((t)[4]*(t)[6] - (t)[5]*(t)[5]) \
127   + (t)[2]*((t)[5]*(t)[3] - (t)[2]*(t)[6]) \
128   + (t)[3]*((t)[2]*(t)[5] - (t)[3]*(t)[4]))
129 
130 #define TEN_T_DET_XY(t) ( (t)[1]*(t)[4] - (t)[2]*(t)[2] )
131 #define TEN_T_DET_XZ(t) ( (t)[1]*(t)[6] - (t)[3]*(t)[3] )
132 #define TEN_T_DET_YZ(t) ( (t)[4]*(t)[6] - (t)[5]*(t)[5] )
133 
134 #define TEN_T_TRACE(t) ((t)[1] + (t)[4] + (t)[6])
135 
136 #define TEN_T_INV(i, t, det)                                 \
137   ((det) = TEN_T_DET(t),                                     \
138    (i)[0] = (t)[0],                                          \
139    (i)[1] =  _ELL_2M_DET((t)[4],(t)[5],(t)[5],(t)[6])/(det), \
140    (i)[2] = -_ELL_2M_DET((t)[2],(t)[5],(t)[3],(t)[6])/(det), \
141    (i)[3] =  _ELL_2M_DET((t)[2],(t)[4],(t)[3],(t)[5])/(det), \
142    (i)[4] =  _ELL_2M_DET((t)[1],(t)[3],(t)[3],(t)[6])/(det), \
143    (i)[5] = -_ELL_2M_DET((t)[1],(t)[2],(t)[3],(t)[5])/(det), \
144    (i)[6] =  _ELL_2M_DET((t)[1],(t)[2],(t)[2],(t)[4])/(det))
145 
146 #define TEN_T_DOT(A, B) ( \
147   (A)[1]*(B)[1] + 2*(A)[2]*(B)[2] + 2*(A)[3]*(B)[3] \
148                 +   (A)[4]*(B)[4] + 2*(A)[5]*(B)[5] \
149                                   +   (A)[6]*(B)[6] )
150 
151 #define TEN_T_NORM(A) (sqrt(TEN_T_DOT(A,A)))
152 
153 #define TEN_T_ADD(a, b, c) (  \
154   (a)[0] = ((b)[0] + (c)[0])/2.0, \
155   (a)[1] = (b)[1] + (c)[1], \
156   (a)[2] = (b)[2] + (c)[2], \
157   (a)[3] = (b)[3] + (c)[3], \
158   (a)[4] = (b)[4] + (c)[4], \
159   (a)[5] = (b)[5] + (c)[5], \
160   (a)[6] = (b)[6] + (c)[6])
161 
162 #define TEN_T_SUB(a, b, c) (  \
163   (a)[0] = ((b)[0] + (c)[0])/2.0, \
164   (a)[1] = (b)[1] - (c)[1], \
165   (a)[2] = (b)[2] - (c)[2], \
166   (a)[3] = (b)[3] - (c)[3], \
167   (a)[4] = (b)[4] - (c)[4], \
168   (a)[5] = (b)[5] - (c)[5], \
169   (a)[6] = (b)[6] - (c)[6])
170 
171 #define TEN_T_AFFINE(C, i, x, I, A, B) (              \
172   (C)[0] = AIR_AFFINE((i), (x), (I), (A)[0], (B)[0]), \
173   (C)[1] = AIR_AFFINE((i), (x), (I), (A)[1], (B)[1]), \
174   (C)[2] = AIR_AFFINE((i), (x), (I), (A)[2], (B)[2]), \
175   (C)[3] = AIR_AFFINE((i), (x), (I), (A)[3], (B)[3]), \
176   (C)[4] = AIR_AFFINE((i), (x), (I), (A)[4], (B)[4]), \
177   (C)[5] = AIR_AFFINE((i), (x), (I), (A)[5], (B)[5]), \
178   (C)[6] = AIR_AFFINE((i), (x), (I), (A)[6], (B)[6]))
179 
180 #define TEN_T_LERP(c, w, a, b) (          \
181   (c)[0] = AIR_LERP((w), (a)[0], (b)[0]), \
182   (c)[1] = AIR_LERP((w), (a)[1], (b)[1]), \
183   (c)[2] = AIR_LERP((w), (a)[2], (b)[2]), \
184   (c)[3] = AIR_LERP((w), (a)[3], (b)[3]), \
185   (c)[4] = AIR_LERP((w), (a)[4], (b)[4]), \
186   (c)[5] = AIR_LERP((w), (a)[5], (b)[5]), \
187   (c)[6] = AIR_LERP((w), (a)[6], (b)[6]))
188 
189 #define TEN_T_SCALE(a, s, b) ( \
190    (a)[0] = (b)[0],               \
191    (a)[1] = (s)*(b)[1],           \
192    (a)[2] = (s)*(b)[2],           \
193    (a)[3] = (s)*(b)[3],           \
194    (a)[4] = (s)*(b)[4],           \
195    (a)[5] = (s)*(b)[5],           \
196    (a)[6] = (s)*(b)[6])
197 
198 #define TEN_T_INCR(a, b) (    \
199    (a)[0] = (b)[0],           \
200    (a)[1] += (b)[1],          \
201    (a)[2] += (b)[2],          \
202    (a)[3] += (b)[3],          \
203    (a)[4] += (b)[4],          \
204    (a)[5] += (b)[5],          \
205    (a)[6] += (b)[6])
206 
207 #define TEN_T_SCALE_INCR(a, s, b) ( \
208    (a)[0] = (b)[0],               \
209    (a)[1] += (s)*(b)[1],          \
210    (a)[2] += (s)*(b)[2],          \
211    (a)[3] += (s)*(b)[3],          \
212    (a)[4] += (s)*(b)[4],          \
213    (a)[5] += (s)*(b)[5],          \
214    (a)[6] += (s)*(b)[6])
215 
216 #define TEN_T_SCALE_INCR2(a, s, b, t, c) ( \
217    (a)[0] = AIR_MIN((b)[0], (c)[0]),  \
218    (a)[1] += (s)*(b)[1] + (t)*(c)[1], \
219    (a)[2] += (s)*(b)[2] + (t)*(c)[2], \
220    (a)[3] += (s)*(b)[3] + (t)*(c)[3], \
221    (a)[4] += (s)*(b)[4] + (t)*(c)[4], \
222    (a)[5] += (s)*(b)[5] + (t)*(c)[5], \
223    (a)[6] += (s)*(b)[6] + (t)*(c)[6])
224 
225 #define TEN_T_SCALE_ADD2(a, s, b, t, c) ( \
226    (a)[0] = AIR_MIN((b)[0], (c)[0]),  \
227    (a)[1] = (s)*(b)[1] + (t)*(c)[1],  \
228    (a)[2] = (s)*(b)[2] + (t)*(c)[2],  \
229    (a)[3] = (s)*(b)[3] + (t)*(c)[3],  \
230    (a)[4] = (s)*(b)[4] + (t)*(c)[4],  \
231    (a)[5] = (s)*(b)[5] + (t)*(c)[5],  \
232    (a)[6] = (s)*(b)[6] + (t)*(c)[6])
233 
234 #define TEN_T3V_MUL(b, t, a) (                            \
235   (b)[0] = (t)[1]*(a)[0] + (t)[2]*(a)[1] + (t)[3]*(a)[2], \
236   (b)[1] = (t)[2]*(a)[0] + (t)[4]*(a)[1] + (t)[5]*(a)[2], \
237   (b)[2] = (t)[3]*(a)[0] + (t)[5]*(a)[1] + (t)[6]*(a)[2])
238 
239 #define TEN_T3V_OUTER(t, a) (                                             \
240   (t)[0] = 1.0,                                                           \
241   (t)[1] = (a)[0]*(a)[0], (t)[2] = (a)[0]*(a)[1], (t)[3] = (a)[0]*(a)[2], \
242                           (t)[4] = (a)[1]*(a)[1], (t)[5] = (a)[1]*(a)[2], \
243                                                   (t)[6] = (a)[2]*(a)[2])
244 
245 #define TEN_T3V_OUTER_INCR(t, a) (                                           \
246   (t)[1] += (a)[0]*(a)[0], (t)[2] += (a)[0]*(a)[1], (t)[3] += (a)[0]*(a)[2], \
247                            (t)[4] += (a)[1]*(a)[1], (t)[5] += (a)[1]*(a)[2], \
248                                                     (t)[6] += (a)[2]*(a)[2])
249 
250 /* NOTE: never looks at (t)[0] */
251 #define TEN_T3V_CONTR(t, v) (                                          \
252     (v)[0]*(t)[1]*(v)[0] + (v)[0]*(t)[2]*(v)[1] + (v)[0]*(t)[3]*(v)[2] \
253   + (v)[1]*(t)[2]*(v)[0] + (v)[1]*(t)[4]*(v)[1] + (v)[1]*(t)[5]*(v)[2] \
254   + (v)[2]*(t)[3]*(v)[0] + (v)[2]*(t)[5]*(v)[1] + (v)[2]*(t)[6]*(v)[2])
255 
256 #ifdef __cplusplus
257 }
258 #endif
259 
260 #endif /* TENMACROS_HAS_BEEN_INCLUDED */
261