55 float64 log10_of_base;
56 float64 inv_log_of_base;
57 float64 inv_log10_of_base;
71 E_ERROR(
"Base must be greater than 1.0\n");
79 lmath->log_of_base = log(base);
80 lmath->log10_of_base = log10(base);
81 lmath->inv_log_of_base = 1.0/lmath->log_of_base;
82 lmath->inv_log10_of_base = 1.0/lmath->log10_of_base;
83 lmath->t.
shift = shift;
85 lmath->zero = MAX_NEG_INT32 >> (shift + 2);
91 maxyx = (uint32) (log(2.0) / log(base) + 0.5) >> shift;
93 if (maxyx < 256) width = 1;
94 else if (maxyx < 65536) width = 2;
97 lmath->t.
width = width;
101 float64 lobyx = log(1.0 + byx) * lmath->inv_log_of_base;
102 int32 k = (int32) (lobyx + 0.5 * (1<<shift)) >> shift;
116 if (i < 255) i = 255;
123 float64 lobyx = log(1.0 + byx) * lmath->inv_log_of_base;
124 int32 k = (int32) (lobyx + 0.5 * (1<<shift)) >> shift;
131 prev = ((uint8 *)lmath->t.
table)[i >> shift];
134 prev = ((uint16 *)lmath->t.
table)[i >> shift];
137 prev = ((uint32 *)lmath->t.
table)[i >> shift];
143 ((uint8 *)lmath->t.
table)[i >> shift] = (uint8) k;
146 ((uint16 *)lmath->t.
table)[i >> shift] = (uint16) k;
149 ((uint32 *)lmath->t.
table)[i >> shift] = (uint32) k;
167 char **argname, **argval;
169 int chksum_present, do_mmap;
174 E_INFO(
"Reading log table file '%s'\n", file_name);
175 if ((fp = fopen(file_name,
"rb")) == NULL) {
176 E_ERROR_SYSTEM(
"Failed to open log table file '%s' for reading", file_name);
181 if (
bio_readhdr(fp, &argname, &argval, &byteswap) < 0) {
182 E_ERROR(
"Failed to read the header from the file '%s'\n", file_name);
191 lmath->base = 1.0001;
195 for (i = 0; argname[i]; i++) {
196 if (strcmp(argname[i],
"version") == 0) {
198 else if (strcmp(argname[i],
"chksum0") == 0) {
199 if (strcmp(argval[i],
"yes") == 0)
202 else if (strcmp(argname[i],
"width") == 0) {
203 lmath->t.
width = atoi(argval[i]);
205 else if (strcmp(argname[i],
"shift") == 0) {
206 lmath->t.
shift = atoi(argval[i]);
208 else if (strcmp(argname[i],
"logbase") == 0) {
209 lmath->base =
atof_c(argval[i]);
216 lmath->log_of_base = log(lmath->base);
217 lmath->log10_of_base = log10(lmath->base);
218 lmath->inv_log_of_base = 1.0/lmath->log_of_base;
219 lmath->inv_log10_of_base = 1.0/lmath->log10_of_base;
221 lmath->zero = MAX_NEG_INT32 >> (lmath->t.
shift + 2);
225 E_ERROR(
"Failed to read values from the file '%s'", file_name);
232 if (pos & ((
long)lmath->t.
width - 1)) {
233 E_WARN(
"%s: Data start %ld is not aligned on %d-byte boundary, will not memory map\n",
234 file_name, pos, lmath->t.
width);
239 E_WARN(
"%s: Data is wrong-endian, will not memory map\n", file_name);
250 fp, byteswap, &chksum) != lmath->t.
table_size) {
251 E_ERROR(
"Failed to read data (%d x %d bytes) from the file '%s' failed",
258 if (fread(&i, 1, 1, fp) == 1) {
259 E_ERROR(
"%s: More data than expected\n", file_name);
278 if (lmath->t.
table == NULL) {
279 E_ERROR(
"No log table to write!\n");
283 E_INFO(
"Writing log table file '%s'\n", file_name);
284 if ((fp = fopen(file_name,
"wb")) == NULL) {
285 E_ERROR_SYSTEM(
"Failed to open logtable file '%s' for writing", file_name);
291 fprintf(fp,
"s3\nversion 1.0\nchksum0 yes\n");
292 fprintf(fp,
"width %d\n", lmath->t.
width);
293 fprintf(fp,
"shift %d\n", lmath->t.
shift);
294 fprintf(fp,
"logbase %f\n", lmath->base);
296 pos = ftell(fp) + strlen(
"endhdr\n");
297 if (pos & ((
long)lmath->t.
width - 1)) {
298 size_t align = lmath->t.
width - (pos & ((long)lmath->t.
width - 1));
299 assert(lmath->t.
width <= 8);
300 fwrite(
" " , 1, align, fp);
302 fprintf(fp,
"endhdr\n");
305 chksum = (uint32)BYTE_ORDER_MAGIC;
306 fwrite(&chksum,
sizeof(uint32), 1, fp);
310 1, fp, 0, &chksum) != 1) {
311 E_ERROR(
"Failed to write data to a file '%s'", file_name);
317 E_ERROR(
"Failed to write data (%d x %d bytes) to the file '%s'",
321 if (
bio_fwrite(&chksum,
sizeof(uint32), 1, fp, 0, NULL) != 1) {
322 E_ERROR(
"Failed to write checksum to the file '%s'", file_name);
346 if (--lmath->refcount > 0)
347 return lmath->refcount;
358 uint32 *out_width, uint32 *out_shift)
360 if (out_size) *out_size = lmath->t.
table_size;
361 if (out_width) *out_width = lmath->t.
width;
362 if (out_shift) *out_shift = lmath->t.
shift;
382 return lmath->t.
width;
388 return lmath->t.
shift;
398 if (logb_x <= lmath->zero)
400 if (logb_y <= lmath->zero)
403 if (t->
table == NULL)
407 if (logb_x > logb_y) {
408 d = (logb_x - logb_y);
412 d = (logb_y - logb_x);
429 return r + (((uint8 *)t->
table)[d]);
431 return r + (((uint16 *)t->
table)[d]);
433 return r + (((uint32 *)t->
table)[d]);
452 return (
int)(log(p) * lmath->inv_log_of_base) >> lmath->t.
shift;
458 return pow(lmath->base, (float64)(logb_p << lmath->t.
shift));
464 return (
int)(log_p * lmath->inv_log_of_base) >> lmath->t.
shift;
470 return (float64)(logb_p << lmath->t.
shift) * lmath->log_of_base;
476 return (
int)(log_p * lmath->inv_log10_of_base) >> lmath->t.
shift;
483 float res = (float)(log_p * lmath->inv_log10_of_base);
484 for (i = 0; i < lmath->t.
shift; i++)
492 return (float64)(logb_p << lmath->t.
shift) * lmath->log10_of_base;
499 for (i = 0; i < lmath->t.
shift; i++) {
502 return log_p * lmath->log10_of_base;
Cross platform binary IO to process files in sphinx3 format.
SPHINXBASE_EXPORT int32 bio_fwrite(const void *buf, int32 el_sz, int32 n_el, FILE *fp, int32 swap, uint32 *chksum)
Like fwrite but perform byteswapping and accumulate checksum (the 2 extra arguments).
SPHINXBASE_EXPORT int32 bio_fread(void *buf, int32 el_sz, int32 n_el, FILE *fp, int32 swap, uint32 *chksum)
Like fread but perform byteswapping and accumulate checksum (the 2 extra arguments).
SPHINXBASE_EXPORT int32 bio_readhdr(FILE *fp, char ***name, char ***val, int32 *swap)
Read binary file format header: has the following format.
SPHINXBASE_EXPORT void bio_verify_chksum(FILE *fp, int32 byteswap, uint32 chksum)
Read and verify checksum at the end of binary file.
SPHINXBASE_EXPORT void bio_hdrarg_free(char **name, char **val)
Free name and value strings previously allocated and returned by bio_readhdr.
Sphinx's memory allocation/deallocation routines.
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
Implementation of logging routines.
#define E_ERROR(...)
Print error message to error log.
#define E_INFO(...)
Print logging information to standard error stream.
#define E_ERROR_SYSTEM(...)
Print error text; Call perror("");.
#define E_WARN(...)
Print warning message to error log.
Fast integer logarithmic addition operations.
SPHINXBASE_EXPORT int logmath_get_width(logmath_t *lmath)
Get the width of the values in a log table.
SPHINXBASE_EXPORT int logmath_get_zero(logmath_t *lmath)
Get the smallest possible value represented in this base.
SPHINXBASE_EXPORT float logmath_log10_to_log_float(logmath_t *lmath, float64 log_p)
Convert base 10 log (in floating point) to float log in base B.
SPHINXBASE_EXPORT float64 logmath_log_float_to_log10(logmath_t *lmath, float log_p)
Convert float log in base B to base 10 log.
SPHINXBASE_EXPORT int32 logmath_get_table_shape(logmath_t *lmath, uint32 *out_size, uint32 *out_width, uint32 *out_shift)
Get the log table size and dimensions.
SPHINXBASE_EXPORT int logmath_ln_to_log(logmath_t *lmath, float64 log_p)
Convert natural log (in floating point) to integer log in base B.
SPHINXBASE_EXPORT logmath_t * logmath_read(const char *filename)
Memory-map (or read) a log table from a file.
SPHINXBASE_EXPORT int logmath_add(logmath_t *lmath, int logb_p, int logb_q)
Add two values in log space (i.e.
SPHINXBASE_EXPORT float64 logmath_get_base(logmath_t *lmath)
Get the log base.
SPHINXBASE_EXPORT int logmath_add_exact(logmath_t *lmath, int logb_p, int logb_q)
Add two values in log space exactly and slowly (without using add table).
SPHINXBASE_EXPORT int32 logmath_write(logmath_t *lmath, const char *filename)
Write a log table to a file.
SPHINXBASE_EXPORT float64 logmath_log_to_log10(logmath_t *lmath, int logb_p)
Convert integer log in base B to base 10 log (in floating point).
SPHINXBASE_EXPORT float64 logmath_log_to_ln(logmath_t *lmath, int logb_p)
Convert integer log in base B to natural log (in floating point).
SPHINXBASE_EXPORT int logmath_free(logmath_t *lmath)
Free a log table.
SPHINXBASE_EXPORT int logmath_log10_to_log(logmath_t *lmath, float64 log_p)
Convert base 10 log (in floating point) to integer log in base B.
SPHINXBASE_EXPORT logmath_t * logmath_init(float64 base, int shift, int use_table)
Initialize a log math computation table.
SPHINXBASE_EXPORT logmath_t * logmath_retain(logmath_t *lmath)
Retain ownership of a log table.
#define LOGMATH_TABLE(lm)
Obtain the log-add table from a logmath_t *.
SPHINXBASE_EXPORT float64 logmath_exp(logmath_t *lmath, int logb_p)
Convert integer log in base B to linear floating point.
SPHINXBASE_EXPORT int logmath_log(logmath_t *lmath, float64 p)
Convert linear floating point number to integer log in base B.
SPHINXBASE_EXPORT int logmath_get_shift(logmath_t *lmath)
Get the shift of the values in a log table.
Memory-mapped I/O wrappers for files.
SPHINXBASE_EXPORT void mmio_file_unmap(mmio_file_t *mf)
Unmap a file, releasing memory associated with it.
SPHINXBASE_EXPORT mmio_file_t * mmio_file_read(const char *filename)
Memory-map a file for reading.
SPHINXBASE_EXPORT void * mmio_file_ptr(mmio_file_t *mf)
Get a pointer to the memory mapped for a file.
Miscellaneous useful string functions.
SPHINXBASE_EXPORT double atof_c(char const *str)
Locale independent version of atof().
void * table
Table, in unsigned integers of (width) bytes.
int8 shift
Right shift applied to elements in (table).
uint32 table_size
Number of elements in (table).
uint8 width
Width of elements of (table).