sPyNNaker neural_modelling  7.4.2
maths-util.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 The University of Manchester
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * https://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
34 #ifndef _MATHS_UTIL_
35 #define _MATHS_UTIL_
36 
37 // disabled for production SpiNNaker builds but here for various testing
38 //#define FLOATING_POINT
39 
41 typedef unsigned int Card;
42 
44 #define START 0
45 
46 // this is where you switch between double precision (or float?) and
47 // fixed point accum (= signed 16.15)
48 #ifdef FLOATING_POINT
49 
50 #include <math.h>
51 
52 typedef double REAL;
53 typedef double UREAL;
54 typedef double FRACT;
55 typedef double UFRACT;
56 #define REAL_CONST(x) x
57 #define UREAL_CONST(x) x
58 #define FRACT_CONST(x) x
59 #define UFRACT_CONST(x) x
60 
61 static REAL macro_arg_1, macro_arg_2, macro_arg_3, macro_arg_4;
62 
63 #define ONE 1.00000000000000000
64 #define HALF 0.50000000000000000
65 #define ZERO 0.00000000000000000
66 
67 #define POW(x, p) pow((x), (p))
68 
69 #define SQRT(x) sqrt(x)
70 #define SQRTU(x) sqrt(x)
71 #define EXP(x) exp(x)
72 #define EXPU(x) exp(x)
73 #define LN(x) log(x)
74 #define ABS(x) fabs(x)
75 
76 //#define INV(x) ONE/(x)
77 
78 #define MAX(x, y) MAX_HR((x), (y))
79 #define SIGN(x, y) ((macro_arg_1=(y)) >= ZERO ? ABS(x) : -ABS(x))
80 
81 #define ACS_DBL_TINY 1.0e-300
82 
83 #else /* using fixed point types and functions */
84 
85 #include <stdfix.h>
86 #include <stdfix-full-iso.h>
87 #include <stdfix-exp.h>
88 #include <sqrt.h>
89 
91 typedef accum REAL;
92 
94 typedef unsigned accum UREAL;
95 
97 typedef long fract FRACT;
98 
100 typedef unsigned long fract UFRACT;
101 
104 #define REAL_CONST(x) x##k // accum -> k
105 
108 #define UREAL_CONST(x) x##uk // unsigned accum -> uk
109 
112 #define FRACT_CONST(x) x##lr
113 
116 #define UFRACT_CONST(x) x##ulr
117 
119 #define ONE REAL_CONST(1.0000)
121 #define HALF REAL_CONST(0.5000)
123 #define ZERO REAL_CONST(0.0000)
125 #define ACS_DBL_TINY REAL_CONST(0.000001)
126 
130 #define SQRT(x) sqrtk(x)
131 
135 #define SQRTU(x) sqrtuk(x)
136 
140 #define EXP(x) expk(x)
141 
145 #define EXPU(x) expuk(x)
146 
147 #if 0
151 #define LN(x) lnfx(x)
152 
157 #define POW(x, p) powfx(x, p) // strictly positive x only
158 #endif
159 
163 #define ABS(x) absfx(x)
164 
165 //#define INV(x)
166 
167 //#define MAX(x, y) maxfx(x, y)
168 
174 #define SIGN(x, y) ((macro_arg_1=(y)) >= ZERO ? ABS(x) : -ABS(x))
175 
176 #endif // FLOATING_POINT
177 
178 // some common operations that could be usefully speeded up
179 #ifdef FLOATING_POINT
180 
181 #define REAL_COMPARE(x, op, y) ((x) op (y))
182 #define REAL_TWICE(x) ((x) * 2.00000)
183 #define REAL_HALF(x) ((x) * 0.50000)
184 
185 #else // !FLOATING_POINT
186 
192 #define REAL_COMPARE(x, op, y) (bitsk((x)) op bitsk((y)))
193 
197 #define REAL_TWICE(x) ((x) * 2.000000k)
198 
202 #define REAL_HALF(x) ((x) * 0.500000k)
203 
204 #endif // FLOATING_POINT
205 
207 #define MIN_HR(a, b) ({\
208  __type_of__(a) _a = (a); \
209  __type_of__(b) _b = (b); \
210  _a <= _b? _a : _b;})
211 
213 #define MAX_HR(a, b) ({\
214  __type_of__(a) _a = (a); \
215  __type_of__(b) _b = (b); \
216  _a > _b? _a : _b;})
217 
219 #define SQR(a) ({\
220  __type_of__(a) _a = (a); \
221  _a == ZERO? ZERO: _a * _a;})
222 
224 #define CUBE(a) ({\
225  __type_of__(a) _a = (a); \
226  _a == ZERO? ZERO: _a * _a * _a;})
227 
228 extern uint64_t udiv64(uint64_t, uint64_t);
229 
234 static inline REAL kdivk(REAL a, REAL b) {
235  return kbits((uint32_t) udiv64(((uint64_t) bitsk(a) << 15), (uint64_t) bitsk(b)));
236 }
237 
242 static inline UREAL ukdivuk(UREAL a, UREAL b) {
243  return ukbits((uint32_t) udiv64(((uint64_t) bitsuk(a) << 16), (uint64_t) bitsuk(b)));
244 }
245 
250 static inline int32_t udivk(int32_t a, REAL b) {
251  return __LI(udiv64(__U64(a) << 15, __U64(bitsk(b))));
252 }
253 
258 static inline REAL kdivui(REAL a, uint32_t b) {
259  return kbits((uint32_t) __LI(udiv64(__U64(bitsk(a)), __U64(b))));
260 }
261 
265 static const uint32_t fract_powers_2[] = {
266  0x16a09, 0x1306f, 0x1172b, 0x10b55, 0x1059b, 0x102c9, 0x10163, 0x100b1,
267  0x10058, 0x1002c, 0x10016, 0x1000b, 0x10005, 0x10002, 0x10001
268 };
269 
270 
274 static const uint32_t fract_powers_half[] = {
275  0xb504, 0xd744, 0xeac0, 0xf525, 0xfa83, 0xfd3e, 0xfe9e, 0xff4e, 0xffa7,
276  0xffd3, 0xffe9, 0xfff4, 0xfffa, 0xfffd, 0xfffe
277 };
278 
283 static inline UREAL pow_of_2(REAL p) {
284 
285  // The variable that will hold the return value
286  uint32_t accumulator;
287 
288  // The fractional bits from the input
289  uint32_t fract_bits;
290 
291  // The powers to use in the calculation
292  const uint32_t *powers;
293 
294  if (p >= 0) {
295  if (p >= 16) {
296  return kbits(0xFFFFFFFF);
297  }
298  accumulator = bitsuk(UREAL_CONST(1)) << (bitsk(p) >> 15);
299  fract_bits = bitsk(p) & 0x7FFF;
300  powers = fract_powers_2;
301  } else {
302  if (p <= -16) {
303  return kbits(0);
304  }
305  REAL val = p * REAL_CONST(-1);
306  accumulator = bitsuk(UREAL_CONST(1)) >> (bitsk(val) >> 15);
307  fract_bits = bitsk(val) & 0x7FFF;
308  powers = fract_powers_half;
309  }
310 
311  // Multiply in fractional powers for each non-zero fractional bits
312  for (uint32_t i = 0; i < 15; i++) {
313  uint32_t bit = (fract_bits >> (14 - i)) & 0x1;
314  if (bit) {
315  uint32_t f = bit * powers[i];
316  accumulator = __stdfix_smul_uk(accumulator, f);
317  }
318  }
319 
320  return ukbits(accumulator);
321 }
322 
323 #endif // _MATHS_UTIL_
static UREAL pow_of_2(REAL p)
Calculates 2^p where p is a real number (rather than just an integer). This is still quicker than gen...
Definition: maths-util.h:283
#define REAL_CONST(x)
Define a constant of type REAL.
Definition: maths-util.h:104
long fract FRACT
Type used for "fractional" numbers.
Definition: maths-util.h:97
unsigned accum UREAL
Type used for "unsigned real" numbers.
Definition: maths-util.h:94
unsigned int Card
A Cardinal type.
Definition: maths-util.h:41
accum REAL
Type used for "real" numbers.
Definition: maths-util.h:91
unsigned long fract UFRACT
Type used for "unsigned fractional" numbers.
Definition: maths-util.h:100
static int32_t udivk(int32_t a, REAL b)
Divides an integer by an accum.
Definition: maths-util.h:250
static REAL kdivk(REAL a, REAL b)
Divides an accum by another accum.
Definition: maths-util.h:234
#define UREAL_CONST(x)
Define a constant of type UREAL.
Definition: maths-util.h:108
static UREAL ukdivuk(UREAL a, UREAL b)
Divides an unsigned accum by another unsigned accum.
Definition: maths-util.h:242
static REAL kdivui(REAL a, uint32_t b)
Divides an accum by an unsigned integer.
Definition: maths-util.h:258
static const uint32_t fract_powers_2[]
Definition: maths-util.h:265
static const uint32_t fract_powers_half[]
Definition: maths-util.h:274