• Main Page
  • Related Pages
  • Data Structures
  • Files
  • File List
  • Globals

src/libsphinxbase/fe/fixlog.c

00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
00002 /* ====================================================================
00003  * Copyright (c) 2005 Carnegie Mellon University.  All rights 
00004  * reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer. 
00012  *
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in
00015  *    the documentation and/or other materials provided with the
00016  *    distribution.
00017  *
00018  * This work was supported in part by funding from the Defense Advanced 
00019  * Research Projects Agency and the National Science Foundation of the 
00020  * United States of America, and the CMU Sphinx Speech Consortium.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
00023  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
00024  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00025  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
00026  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00027  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00028  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
00029  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
00030  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00031  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00032  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * ====================================================================
00035  *
00036  * File: fixlog.c
00037  *
00038  * Description: Fast approximate fixed-point logarithms
00039  *
00040  * Author: David Huggins-Daines <dhuggins@cs.cmu.edu>
00041  *
00042  */
00043 
00044 #ifdef HAVE_CONFIG_H
00045 #include <config.h>
00046 #endif
00047 
00048 #include "prim_type.h"
00049 #include "fe_internal.h"
00050 #include "fixpoint.h"
00051 
00052 /* Table of log2(x/64)*(1<<DEFAULT_RADIX) */
00053 /* perl -e 'for (0..63) {my $x = 1 + $_/64; print "\t(uint32)(", log($x)/log(2), "*(1<<DEFAULT_RADIX)),\n"}' */
00054 static uint32 logtable[] = {
00055     (uint32) (0 * (1 << DEFAULT_RADIX)),
00056     (uint32) (0.0223678130284545 * (1 << DEFAULT_RADIX)),
00057     (uint32) (0.0443941193584534 * (1 << DEFAULT_RADIX)),
00058     (uint32) (0.0660891904577724 * (1 << DEFAULT_RADIX)),
00059     (uint32) (0.0874628412503394 * (1 << DEFAULT_RADIX)),
00060     (uint32) (0.108524456778169 * (1 << DEFAULT_RADIX)),
00061     (uint32) (0.129283016944966 * (1 << DEFAULT_RADIX)),
00062     (uint32) (0.149747119504682 * (1 << DEFAULT_RADIX)),
00063     (uint32) (0.169925001442312 * (1 << DEFAULT_RADIX)),
00064     (uint32) (0.189824558880017 * (1 << DEFAULT_RADIX)),
00065     (uint32) (0.20945336562895 * (1 << DEFAULT_RADIX)),
00066     (uint32) (0.228818690495881 * (1 << DEFAULT_RADIX)),
00067     (uint32) (0.247927513443586 * (1 << DEFAULT_RADIX)),
00068     (uint32) (0.266786540694901 * (1 << DEFAULT_RADIX)),
00069     (uint32) (0.285402218862248 * (1 << DEFAULT_RADIX)),
00070     (uint32) (0.303780748177103 * (1 << DEFAULT_RADIX)),
00071     (uint32) (0.321928094887362 * (1 << DEFAULT_RADIX)),
00072     (uint32) (0.339850002884625 * (1 << DEFAULT_RADIX)),
00073     (uint32) (0.357552004618084 * (1 << DEFAULT_RADIX)),
00074     (uint32) (0.375039431346925 * (1 << DEFAULT_RADIX)),
00075     (uint32) (0.39231742277876 * (1 << DEFAULT_RADIX)),
00076     (uint32) (0.409390936137702 * (1 << DEFAULT_RADIX)),
00077     (uint32) (0.426264754702098 * (1 << DEFAULT_RADIX)),
00078     (uint32) (0.442943495848728 * (1 << DEFAULT_RADIX)),
00079     (uint32) (0.459431618637297 * (1 << DEFAULT_RADIX)),
00080     (uint32) (0.475733430966398 * (1 << DEFAULT_RADIX)),
00081     (uint32) (0.491853096329675 * (1 << DEFAULT_RADIX)),
00082     (uint32) (0.507794640198696 * (1 << DEFAULT_RADIX)),
00083     (uint32) (0.523561956057013 * (1 << DEFAULT_RADIX)),
00084     (uint32) (0.539158811108031 * (1 << DEFAULT_RADIX)),
00085     (uint32) (0.554588851677637 * (1 << DEFAULT_RADIX)),
00086     (uint32) (0.569855608330948 * (1 << DEFAULT_RADIX)),
00087     (uint32) (0.584962500721156 * (1 << DEFAULT_RADIX)),
00088     (uint32) (0.599912842187128 * (1 << DEFAULT_RADIX)),
00089     (uint32) (0.614709844115208 * (1 << DEFAULT_RADIX)),
00090     (uint32) (0.62935662007961 * (1 << DEFAULT_RADIX)),
00091     (uint32) (0.643856189774725 * (1 << DEFAULT_RADIX)),
00092     (uint32) (0.658211482751795 * (1 << DEFAULT_RADIX)),
00093     (uint32) (0.672425341971496 * (1 << DEFAULT_RADIX)),
00094     (uint32) (0.686500527183218 * (1 << DEFAULT_RADIX)),
00095     (uint32) (0.700439718141092 * (1 << DEFAULT_RADIX)),
00096     (uint32) (0.714245517666123 * (1 << DEFAULT_RADIX)),
00097     (uint32) (0.727920454563199 * (1 << DEFAULT_RADIX)),
00098     (uint32) (0.741466986401147 * (1 << DEFAULT_RADIX)),
00099     (uint32) (0.754887502163469 * (1 << DEFAULT_RADIX)),
00100     (uint32) (0.768184324776926 * (1 << DEFAULT_RADIX)),
00101     (uint32) (0.78135971352466 * (1 << DEFAULT_RADIX)),
00102     (uint32) (0.794415866350106 * (1 << DEFAULT_RADIX)),
00103     (uint32) (0.807354922057604 * (1 << DEFAULT_RADIX)),
00104     (uint32) (0.820178962415188 * (1 << DEFAULT_RADIX)),
00105     (uint32) (0.832890014164742 * (1 << DEFAULT_RADIX)),
00106     (uint32) (0.845490050944375 * (1 << DEFAULT_RADIX)),
00107     (uint32) (0.857980995127572 * (1 << DEFAULT_RADIX)),
00108     (uint32) (0.870364719583405 * (1 << DEFAULT_RADIX)),
00109     (uint32) (0.882643049361841 * (1 << DEFAULT_RADIX)),
00110     (uint32) (0.894817763307944 * (1 << DEFAULT_RADIX)),
00111     (uint32) (0.906890595608518 * (1 << DEFAULT_RADIX)),
00112     (uint32) (0.918863237274595 * (1 << DEFAULT_RADIX)),
00113     (uint32) (0.930737337562886 * (1 << DEFAULT_RADIX)),
00114     (uint32) (0.94251450533924 * (1 << DEFAULT_RADIX)),
00115     (uint32) (0.954196310386875 * (1 << DEFAULT_RADIX)),
00116     (uint32) (0.965784284662087 * (1 << DEFAULT_RADIX)),
00117     (uint32) (0.977279923499917 * (1 << DEFAULT_RADIX)),
00118     (uint32) (0.988684686772166 * (1 << DEFAULT_RADIX)),
00119 };
00120 
00121 int32
00122 fixlog2(uint32 x)
00123 {
00124     uint32 y;
00125 
00126     if (x == 0)
00127         return MIN_FIXLOG2;
00128 
00129     /* Get the exponent. */
00130 #if defined(__GNUC__) && defined(__i386__) 
00131   __asm__("bsrl %1, %0\n": "=r"(y): "g"(x):"cc");
00132     x <<= (31 - y);
00133 #elif defined(__ppc__)
00134   __asm__("cntlzw %0, %1\n": "=r"(y):"r"(x));
00135     x <<= y;
00136     y = 31 - y;
00137 #elif defined __ARM_ARCH_5__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__
00138   __asm__("clz %0, %1\n": "=r"(y):"r"(x));
00139     x <<= y;
00140     y = 31 - y;
00141 #else
00142     for (y = 31; y >= 0; --y) {
00143         if (x & 0x80000000)
00144             break;
00145         x <<= 1;
00146     }
00147 #endif
00148     y <<= DEFAULT_RADIX;
00149     /* Do a table lookup for the MSB of the mantissa. */
00150     x = (x >> 25) & 0x3f;
00151     return y + logtable[x];
00152 }
00153 
00154 int
00155 fixlog(uint32 x)
00156 {
00157     int32 y;
00158 
00159     if (x == 0)
00160         return MIN_FIXLOG;
00161 
00162     y = fixlog2(x);
00163     return FIXMUL(y, FIXLN_2);
00164 }

Generated on Tue Aug 17 2010 for SphinxBase by  doxygen 1.7.1