OpenCores
URL https://opencores.org/ocsvn/fp_log/fp_log/trunk

Subversion Repositories fp_log

[/] [fp_log/] [trunk/] [DP-ICSILog/] [DP-ICSILog.c] - Rev 2

Compare with Previous | Blame | View Log

/*******************************************************************************************
 *
 * Double-Precision ICSILog algorithm implementation 
 * written by Nikolaos Alchiotis and Alexandros Stamatakis
 *       
 * The Exelixis Lab
 * Bioinformatics Unit (I12)
 * Department of Computer Science
 * Technical University of Munich
 *
 * Emails: alachiot@cs.tum.edu, stamatak@cs.tum.edu
 * WWW:   http://wwwkramer.in.tum.de/exelixis/
 *
 * This code is made available under GNU GPL
 *
 *
*******************************************************************************************/
 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
/********************************************/
// Union to Access the bits
 
typedef union
{
  double value;
 
  struct
  {
    unsigned int rght_p;
    unsigned int lft_p;
  } 
    parts;
} 
  ieee_double_shape_type;
 
 
/********************************************/
 
//Constant Value
double con_val;
 
// Variables used for error checking
double value_minus_inf,
       value_nan,
       value_inf,
       value_inf_inf;
 
// Prec shows how many MSBs of the mantissa field will be used to index the mantissa LUT
unsigned int prec = 12;
 
// Lut_entries is the number of entries of the mantissa LUT
int lut_entries;//=pow(2,prec);
 
//ShiftBits is used by the main function to perform the shifting operation
int shiftBits;//= 12 + 20 - prec;
 
 
/********************************************/
 
// Function to initialize the mantissa LUT . It is the same one that the official ICSILog uses.
 
static void DP_ICSILog_INIT(const unsigned precision, double* const pTable)
{
  /* 
     step along table elements and x-axis positions
     (start with extra half increment, so the steps intersect at their midpoints.) 
  */
 
  con_val = log(2);
  value_minus_inf = -1.0 / 0.0;
  value_nan = 0.0 / 0.0;
  value_inf = pow(10, 308);
  value_inf_inf = value_inf + value_inf;
 
 
  double oneToTwo = 1.0f + (1.0f / (double)( 1 << (precision + 1)));
  int i;
 
  for(i = 0;  i < (1 << precision);  ++i )
    {
      // make y-axis value for table element
      pTable[i] = logf(oneToTwo);
 
      oneToTwo += 1.0f / (double)(1 << precision);
    }
}
 
/********************************************/
// The DP_myICSILog main function.
 
static inline double DP_myICSILog(const double input , const int num_of_bits, register double * const t)
{  
  register double result;
 
  if(input < 0.0)    
    result = value_nan;
  else
    {
      if(input == 0.0)
	result = value_minus_inf;	
      else
	{
	  if(input > value_inf)	    
	    result = value_inf_inf;	
	  else
	    {	 
	      ieee_double_shape_type model_input;
	      model_input.value = input;
 
	      register unsigned int left = model_input.parts.lft_p;
 
	      register double m1 = ((left << 1) >> 21) - 1023.0;
	      register int index = (left << 12) >> num_of_bits;
 
	      result = (con_val * m1  + t[index]);				 
	    }
	}
    }
  return result;
}
 
 
int main()
{
 
  double 
    value = 123456789,
    *DP_myICSILog_LUT,
    result;
 
  /*********************************************************************/
  // How to Initialize the function
  prec = 12; 
 
  lut_entries = pow(2,prec);
 
  shiftBits = 12 + 20 - prec;
 
  DP_myICSILog_LUT = (double*)malloc(sizeof(double) * lut_entries);
 
  DP_ICSILog_INIT(prec, DP_myICSILog_LUT);
 
  /********************************************************************/
 
 
  /********************************************************************/
 
  // How to Call the function
  result = DP_myICSILog(value, shiftBits, DP_myICSILog_LUT);
 
  printf("\n\nDP_myICSILog(%f) = %f \n",value, result);
  printf("\nLog(%f) = %f \n\n\n", value, log(value));
  return 0;
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.