sPyNNaker neural_modelling 7.1.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 EXP(x) exp(x)
71#define LN(x) log(x)
72#define ABS(x) fabs(x)
73
74//#define INV(x) ONE/(x)
75
76#define MAX(x, y) MAX_HR((x), (y))
77#define SIGN(x, y) ((macro_arg_1=(y)) >= ZERO ? ABS(x) : -ABS(x))
78
79#define ACS_DBL_TINY 1.0e-300
80
81#else /* using fixed point types and functions */
82
83#include <stdfix.h>
84#include <stdfix-full-iso.h>
85#include <stdfix-exp.h>
86#include <sqrt.h>
87
89typedef accum REAL;
90
92typedef unsigned accum UREAL;
93
95typedef long fract FRACT;
96
98typedef unsigned long fract UFRACT;
99
102#define REAL_CONST(x) x##k // accum -> k
103
106#define UREAL_CONST(x) x##uk // unsigned accum -> uk
107
110#define FRACT_CONST(x) x##lr
111
114#define UFRACT_CONST(x) x##ulr
115
117#define ONE REAL_CONST(1.0000)
119#define HALF REAL_CONST(0.5000)
121#define ZERO REAL_CONST(0.0000)
123#define ACS_DBL_TINY REAL_CONST(0.000001)
124
128#define SQRT(x) sqrtk(x)
129
133#define EXP(x) expk(x)
134
135#if 0
139#define LN(x) lnfx(x)
140
145#define POW(x, p) powfx(x, p) // strictly positive x only
146#endif
147
151#define ABS(x) absfx(x)
152
153//#define INV(x)
154
155//#define MAX(x, y) maxfx(x, y)
156
162#define SIGN(x, y) ((macro_arg_1=(y)) >= ZERO ? ABS(x) : -ABS(x))
163
164#endif // FLOATING_POINT
165
166// some common operations that could be usefully speeded up
167#ifdef FLOATING_POINT
168
169#define REAL_COMPARE(x, op, y) ((x) op (y))
170#define REAL_TWICE(x) ((x) * 2.00000)
171#define REAL_HALF(x) ((x) * 0.50000)
172
173#else // !FLOATING_POINT
174
180#define REAL_COMPARE(x, op, y) (bitsk((x)) op bitsk((y)))
181
185#define REAL_TWICE(x) ((x) * 2.000000k)
186
190#define REAL_HALF(x) ((x) * 0.500000k)
191
192#endif // FLOATING_POINT
193
195#define MIN_HR(a, b) ({\
196 __type_of__(a) _a = (a); \
197 __type_of__(b) _b = (b); \
198 _a <= _b? _a : _b;})
199
201#define MAX_HR(a, b) ({\
202 __type_of__(a) _a = (a); \
203 __type_of__(b) _b = (b); \
204 _a > _b? _a : _b;})
205
207#define SQR(a) ({\
208 __type_of__(a) _a = (a); \
209 _a == ZERO? ZERO: _a * _a;})
210
212#define CUBE(a) ({\
213 __type_of__(a) _a = (a); \
214 _a == ZERO? ZERO: _a * _a * _a;})
215
216extern uint64_t udiv64(uint64_t, uint64_t);
217
222static inline REAL kdivk(REAL a, REAL b) {
223 return kbits((uint32_t) udiv64(((uint64_t) bitsk(a) << 15), (uint64_t) bitsk(b)));
224}
225
230static inline UREAL ukdivuk(UREAL a, UREAL b) {
231 return ukbits((uint32_t) udiv64(((uint64_t) bitsuk(a) << 16), (uint64_t) bitsuk(b)));
232}
233
238static inline int32_t udivk(int32_t a, REAL b) {
239 return __LI(udiv64(__U64(a) << 15, __U64(bitsk(b))));
240}
241
246static inline REAL kdivui(REAL a, uint32_t b) {
247 return kbits((uint32_t) __LI(udiv64(__U64(bitsk(a)), __U64(b))));
248}
249
253static const uint32_t fract_powers_2[] = {
254 0x16a09, 0x1306f, 0x1172b, 0x10b55, 0x1059b, 0x102c9, 0x10163, 0x100b1,
255 0x10058, 0x1002c, 0x10016, 0x1000b, 0x10005, 0x10002, 0x10001
256};
257
258
262static const uint32_t fract_powers_half[] = {
263 0xb504, 0xd744, 0xeac0, 0xf525, 0xfa83, 0xfd3e, 0xfe9e, 0xff4e, 0xffa7,
264 0xffd3, 0xffe9, 0xfff4, 0xfffa, 0xfffd, 0xfffe
265};
266
271static inline UREAL pow_of_2(REAL p) {
272
273 // The variable that will hold the return value
274 uint32_t accumulator;
275
276 // The fractional bits from the input
277 uint32_t fract_bits;
278
279 // The powers to use in the calculation
280 const uint32_t *powers;
281
282 if (p >= 0) {
283 if (p >= 16) {
284 return kbits(0xFFFFFFFF);
285 }
286 accumulator = bitsuk(UREAL_CONST(1)) << (bitsk(p) >> 15);
287 fract_bits = bitsk(p) & 0x7FFF;
288 powers = fract_powers_2;
289 } else {
290 if (p <= -16) {
291 return kbits(0);
292 }
293 REAL val = p * REAL_CONST(-1);
294 accumulator = bitsuk(UREAL_CONST(1)) >> (bitsk(val) >> 15);
295 fract_bits = bitsk(val) & 0x7FFF;
296 powers = fract_powers_half;
297 }
298
299 // Multiply in fractional powers for each non-zero fractional bits
300 for (uint32_t i = 0; i < 15; i++) {
301 uint32_t bit = (fract_bits >> (14 - i)) & 0x1;
302 if (bit) {
303 uint32_t f = bit * powers[i];
304 accumulator = __stdfix_smul_uk(accumulator, f);
305 }
306 }
307
308 return ukbits(accumulator);
309}
310
311#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:271
#define REAL_CONST(x)
Define a constant of type REAL.
Definition maths-util.h:102
long fract FRACT
Type used for "fractional" numbers.
Definition maths-util.h:95
unsigned accum UREAL
Type used for "unsigned real" numbers.
Definition maths-util.h:92
unsigned int Card
A Cardinal type.
Definition maths-util.h:41
accum REAL
Type used for "real" numbers.
Definition maths-util.h:89
unsigned long fract UFRACT
Type used for "unsigned fractional" numbers.
Definition maths-util.h:98
static int32_t udivk(int32_t a, REAL b)
Divides an integer by an accum.
Definition maths-util.h:238
static REAL kdivk(REAL a, REAL b)
Divides an accum by another accum.
Definition maths-util.h:222
#define UREAL_CONST(x)
Define a constant of type UREAL.
Definition maths-util.h:106
static UREAL ukdivuk(UREAL a, UREAL b)
Divides an unsigned accum by another unsigned accum.
Definition maths-util.h:230
static REAL kdivui(REAL a, uint32_t b)
Divides an accum by an unsigned integer.
Definition maths-util.h:246
static const uint32_t fract_powers_2[]
Definition maths-util.h:253
static const uint32_t fract_powers_half[]
Definition maths-util.h:262
#define __U64(x)
#define __LI(x)