OpenWareLaboratory
basicmaths.c
Go to the documentation of this file.
1 #include "basicmaths.h"
2 #include <stdint.h>
3 #include <string.h>
4 #include "fastpow.h"
5 #include "fastlog.h"
6 
7 #ifdef ARM_CORTEX
8 /* The realloc() function changes the size of the memory block pointed to */
9 /* by ptr to size bytes. The contents will be unchanged in the range from */
10 /* the start of the region up to the minimum of the old and new sizes. If */
11 /* the new size is larger than the old size, the added memory will not be */
12 /* initialized. If ptr is NULL, then the call is equivalent to mal‐ */
13 /* loc(size), for all values of size; if size is equal to zero, and ptr is */
14 /* not NULL, then the call is equivalent to free(ptr). Unless ptr is */
15 /* NULL, it must have been returned by an earlier call to malloc(), cal‐ */
16 /* loc(), or realloc(). If the area pointed to was moved, a free(ptr) is */
17 /* done. */
18 void* pvPortRealloc(void *ptr, size_t new_size) {
19  if(ptr == NULL)
20  return pvPortMalloc(new_size);
21  size_t old_size = vPortGetSizeBlock(ptr);
22  if(new_size == 0){
23  vPortFree(ptr);
24  return NULL;
25  }
26  if(new_size <= old_size)
27  return ptr;
28  void* p = pvPortMalloc(new_size);
29  if(p == NULL)
30  return p;
31  memcpy(p, ptr, old_size);
32  vPortFree(ptr);
33  return p;
34 }
35 
36 /* The calloc() function allocates memory for an array of nmemb elements */
37 /* of size bytes each and returns a pointer to the allocated memory. */
38 /* The memory is set to zero. */
39 void *pvPortCalloc(size_t nmemb, size_t size){
40  size_t xWantedSize = nmemb*size;
41  void* ptr = pvPortMalloc(xWantedSize);
42  if(ptr != NULL)
43  memset(ptr, 0, xWantedSize);
44  return ptr;
45 }
46 #endif
47 
48 // todo: see
49 // http://www.hxa.name/articles/content/fast-pow-adjustable_hxa7241_2007.html
50 // http://www.finesse.demon.co.uk/steven/sqrt.html
51 // http://www.keil.com/forum/7934/
52 // http://processors.wiki.ti.com/index.php/ARM_compiler_optimizations
53 
54  /* void *_sbrk(intptr_t increment){} */
55 
56 static uint32_t r32seed = 33641;
57 
58 void arm_srand32(uint32_t s){
59  r32seed = s;
60 }
61 
67 uint32_t arm_rand32(){
68  r32seed ^= r32seed << 13;
69  r32seed ^= r32seed >> 17;
70  r32seed ^= r32seed << 5;
71  return r32seed;
72 }
73 
74 float randf(){
75  return arm_rand32()*(1/4294967296.0f);
76 }
77 
78 float arm_sqrtf(float in){
79  float out;
80 #ifdef ARM_CORTEX
81  arm_sqrt_f32(in, &out);
82 #else
83  out=sqrtf(in);
84 #endif
85  return out;
86 }
87 
88 /* Fast arctan2
89  * from http://dspguru.com/dsp/tricks/fixed-point-atan2-with-self-normalization
90  */
91 float fast_atan2f(float y, float x){
92  const float coeff_1 = M_PI/4;
93  const float coeff_2 = 3*M_PI/4;
94  float abs_y = fabs(y)+1e-10; // kludge to prevent 0/0 condition
95  float r, angle;
96  if (x>=0){
97  r = (x - abs_y) / (x + abs_y);
98  angle = coeff_1 - coeff_1 * r;
99  }else{
100  r = (x + abs_y) / (abs_y - x);
101  angle = coeff_2 - coeff_1 * r;
102  }
103  if(y < 0)
104  return(-angle); // negate if in quad III or IV
105  else
106  return(angle);
107 }
108 
109 /* static const float* log_table = fast_log_table; */
110 /* static uint32_t log_precision = fast_log_precision; */
111 /* static const uint32_t* pow_table = fast_pow_table; */
112 /* static uint32_t pow_precision = fast_pow_precision; */
113 
114 static const float* log_table;
115 static uint32_t log_precision;
116 static const uint32_t* pow_table;
117 static uint32_t pow_precision;
118 
119 #define M_LOG210 3.32192809488736
120 
121 float fast_powf(float x, float y){
122  return powFastLookup(y, logf(x)*M_LOG2E, pow_table, pow_precision);
123 }
124 
125 float fast_expf(float x){
126  return powFastLookup(x, M_LOG2E, pow_table, pow_precision);
127 }
128 
129 float fast_exp2f(float x){
130  return powFastLookup(x, 1, pow_table, pow_precision);
131 }
132 
133 float fast_exp10f(float x){
135 }
136 
137 float fast_logf(float x){
138  return icsi_log(x, log_table, log_precision);
139 }
140 
141 float fast_log10f(float x){
142  /* log10 (x) equals log (x) / log (10). */
143  return icsi_log(x, log_table, log_precision) / M_LN10;
144 }
145 
146 float fast_log2f(float x){
147  /* log2 (x) equals log (x) / log (2). */
148  return icsi_log(x, log_table, log_precision) / M_LN2;
149 }
150 
151 void fast_pow_set_table(const uint32_t* table, int size){
152  pow_table = table;
153  pow_precision = fast_log2i(size);
154 }
155 
156 void fast_log_set_table(const float* table, int size){
157  log_table = table;
158  log_precision = fast_log2i(size);
159 }
160 
161 float fast_fmodf(float x, float y) {
162  float a = x/y;
163  return (a-(int)a)*y;
164 }
165 
166 uint32_t fast_log2i(uint32_t x){
167  return 31 - __builtin_clz (x); /* clz returns the number of leading 0's */
168 }
static uint32_t log_precision
Definition: basicmaths.c:115
static const float * log_table
Definition: basicmaths.c:114
float fast_powf(float x, float y)
Definition: basicmaths.c:121
uint32_t fast_log2i(uint32_t x)
Definition: basicmaths.c:166
float fast_expf(float x)
Definition: basicmaths.c:125
static const uint32_t * pow_table
Definition: basicmaths.c:116
float fast_fmodf(float x, float y)
Definition: basicmaths.c:161
void fast_log_set_table(const float *table, int size)
Definition: basicmaths.c:156
float randf()
generate a random number between 0 and 1
Definition: basicmaths.c:74
float fast_logf(float x)
Definition: basicmaths.c:137
static uint32_t r32seed
Definition: basicmaths.c:56
float fast_exp2f(float x)
Definition: basicmaths.c:129
uint32_t arm_rand32()
Generate an unsigned 32bit pseudo-random number using xorshifter algorithm.
Definition: basicmaths.c:67
void arm_srand32(uint32_t s)
Definition: basicmaths.c:58
float fast_exp10f(float x)
Definition: basicmaths.c:133
#define M_LOG210
Definition: basicmaths.c:119
float fast_log2f(float x)
Definition: basicmaths.c:146
void fast_pow_set_table(const uint32_t *table, int size)
Definition: basicmaths.c:151
float fast_atan2f(float y, float x)
Definition: basicmaths.c:91
float fast_log10f(float x)
Definition: basicmaths.c:141
static uint32_t pow_precision
Definition: basicmaths.c:117
float arm_sqrtf(float in)
Definition: basicmaths.c:78
#define M_PI
Definition: basicmaths.h:52
float icsi_log(float arg, const float *lookup_table, const uint32_t precision)
Definition: fastlog.c:44
float powFastLookup(const float val, const float ilog2, const uint32_t *pTable, const uint32_t precision)
Get pow (fast!).
Definition: fastpow.c:46