5 // Created by pete on 1/17/17.
6 // Copyright © 2017 Kiva Design. All rights reserved.
8 // edited or touched Nov 6 2018
15 #include "utilities.h"
18 static char * title
= "kiva utility functions 1.0v6 [June 10 2019]";
22 - added btName() to give names to the types of blocks and queues
24 - added isqrt() [validated elsewhere]
29 - by default utilityReport now set to 0
31 - added char * utGetNameFromPath(char * p)
38 // ---------------- utilityTitleAndVersion ------------------
40 char * utilityTitleAndVersion(void) {
44 // -------------- findent -----------------
46 void findent(FILE * f
, int depth
) {
47 // outputs 'indent' tabs after a newline
55 // ---------------- timenow ------------------
57 uint64
timenow(void) {
58 // returns the current time in microseconds
62 gettimeofday(&tv
, &tz
);
63 thetime
= ((uint64
)tv
.tv_sec
* 1000000) + (uint64
)tv
.tv_usec
;
68 // -------------------- utGetNameFromPath ------------------
70 char * utGetNameFromPath(char * p
) {
71 char * path
= strdup(p
);
72 // extract the last slice of the path to give the name
73 uint32 len
= (uint32
)strlen(path
);
74 char * ptr
= &path
[len
];
76 // walk backwards till we find a '/'
77 while (*ptr
!= '/') ptr
--;
78 char * name
= strdup(ptr
+ 1);
83 // ---------------- comments on rn creation ----------------
87 https://fr.mathworks.com/matlabcentral/fileexchange/8054-triangular-distributed-random-variable-generator?requestedDomain=true
89 %Script by Dr.Mongkut Piantanakulchai
90 %To simulate the triangular distribution
91 %Return a vector of random variable
92 %The range of the value is between (a,b)
93 %The mode is c (most probable value)
94 %n is to total number of values generated
96 %X = trirnd(1,5,10,100000);
97 % this will generate 100000 random numbers between 1 and 10 (where most probable
99 % To visualize the result use the command
102 function X=trirnd(a,c,b,n)
107 if sqrt(z*(b-a)*(c-a))+a<c
108 X(i)=sqrt(z*(b-a)*(c-a))+a;
110 X(i)=b-sqrt((1-z)*(b-a)*(b-c));
113 %hist(X,50); Remove this comment % to look at histogram of X
118 // ----------------------- random numbers --------------------
120 #define rvM ((1L << 31) - 1L)
122 #define rvquotient (rvM / rvd)
123 #define rvremainder (rvM % rvd)
125 #define maxUniformStream (8)
128 //*********** NOTE: a stream must never get the value 0, or it won't ever change *******
130 static uint32 RandomStreams
[maxUniformStream
+ 1];
132 // ----------------------------- uniform ---------------
134 uint32
uniform(uint32 stream
, uint32 base
, uint32 limit
) {
136 /* returns a uniformly distributed rv in base..limit
137 the smallest number returned is base
138 the largest number returned is base + (limit - 1)
139 base, limit MUST both be >= 0
141 these are NOT checked in the runtime
144 // ********* NOTE: warnings about integer overflow in expressions in this function should be ignored.
146 result
= RandomStreams
[stream
];
147 result
= (rvd
* (result
% rvquotient
)) -
148 (rvremainder
* (result
/ rvquotient
));
150 // kill any zero values
154 RandomStreams
[stream
] = result
;
156 //printf("\n\t\tRAW rv= %d 0x%08lx", result, result);
158 // reduce the range of the value to base..limit
159 result
%= (limit
- base
);
160 return (base
+ result
);
163 // ----------------- isqrt -----------------------
165 uint32
isqrt(uint32 n
) {
169 // validated with simple tests
170 for (i
= 0; i
< 16; i
++) {
186 // ----------------- triangular -------------------
188 uint32
triangular(uint32 stream
, uint32 base
, uint32 limit
, uint32 mode
) {
189 // creates a triangularly-distributed RN in the range base, limit with peak at mode
190 // only works for values in 0..1 as fractions...
192 uint32 z
= uniform(stream
, base
, limit
);
193 uint32 s
= isqrt(z
*(limit
- base
)*(mode
- base
)) + base
;
199 return limit
-isqrt((1-z
)*(limit
-base
)*(limit
-mode
));
203 /* ---------------------- initUniform --------------------------------- */
205 void initUniform(void) {
206 // initialise the seeds - must call before calling uniform
209 for (i
= 0; i
< maxUniformStream
; i
++) {
210 RandomStreams
[i
] = i
+ 1;
214 // ------------- sext ---------------------
216 int64
sext(uint32 n
, uint64 v
) {
217 // sign extends v assuming it has n bits of data
219 // printf("\nsign extend '%lld' which comprises %d bits", v, n);
221 uint64 bit
= (1LL << (n
- 1));
222 // printf("\n\tbit = %lld", bit);
224 // need to sign extend
226 // printf("\n\tmask = 0x%08llx", mask);
228 // printf("\n\tr = 0x%08llx %lld", r, r);