sPyNNaker neural_modelling 7.3.1
Loading...
Searching...
No Matches
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
41typedef 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
52typedef double REAL;
53typedef double UREAL;
54typedef double FRACT;
55typedef 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
61static 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
91typedef accum REAL;
92
94typedef unsigned accum UREAL;
95
97typedef long fract FRACT;
98
100typedef 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
228extern uint64_t udiv64(uint64_t, uint64_t);
229
234static inline REAL kdivk(REAL a, REAL b) {
235 return kbits((uint32_t) udiv64(((uint64_t) bitsk(a) << 15), (uint64_t) bitsk(b)));
236}
237
242static inline UREAL ukdivuk(UREAL a, UREAL b) {
243 return ukbits((uint32_t) udiv64(((uint64_t) bitsuk(a) << 16), (uint64_t) bitsuk(b)));
244}
245
250static inline int32_t udivk(int32_t a, REAL b) {
251 return __LI(udiv64(__U64(a) << 15, __U64(bitsk(b))));
252}
253
258static inline REAL kdivui(REAL a, uint32_t b) {
259 return kbits((uint32_t) __LI(udiv64(__U64(bitsk(a)), __U64(b))));
260}
261
265static 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
274static 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
283static 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
#define __U64(x)
#define __LI(x)