We’re smarter together. Learn from this collection of community knowledge and add your expertise.

Building Log & Antilog Functions with Proc FCMP

by Super Contributor 3 weeks ago - edited 3 weeks ago (955 Views)

Introduction

 

I was recently working on a new piece of code which required me to use the logarithm of a number to base 0.5 (don’t ask – that may form the basis of a future article :-)). My immediate reaction was “no problem - there’s a function for that”. However, upon checking I realised that there isn’t an inbuilt SAS function you can use to give you a logarithm to just any base; the log function itself returns the natural (base e) logarithm, the log1px function returns the log of 1 plus the argument, log10 gives you the logarithm to base 10 and log2 the logarithm to base 2. I knew that if I was working with Excel the log function there allows me to specify a base so I decided to use Proc FCMP to write my own user defined function to add to my growing library. In addition, once I’d completed that I decided it would be useful to have another function to convert a logarithm back to its source value and so the antilog function was born!

 

The Logn Function

 

The formula for calculating the logarithm of a number to any given base is quite simple. You take the natural logarithm of the number and divide it by the natural logarithm of the base. This means we can create a nice short function like this (note that if the number is less than or equal to 0 we are returning a missing value – this is consistent with the inbuilt log functions).

 

 

/* Define the location of the UDF library */

libname udflib '/folders/myshortcuts/Dropbox/SAS/UDFLib';
options cmplib=udflib.funcs;

/************************************************************************************
 Title: Logn

 Purpose: Calculates the logarithm of a number to a supplied base

 Restriction: None

 Syntax: Logn(value, base)

 Required Arguments: Two positive numeric constants, variables or expressions

 Details: The logn function returns the logarithm of the first argument to the base 
          of the second argument. If either argument is <= 0 then the function
          returns a missing value

 Examples: logn(32,0.5) - returns -5

************************************************************************************/

proc fcmp outlib=udflib.funcs.math;
	function logn(val,base);
		if (val <= 0) or (base <= 0) then return(.);
		else return(log(val)/log(base));
	endsub;
run;

 

The Antilog Function

 

The formula to convert a logarithm back to its source number is also very simple – you just raise the base to the power of the logarithm and you have your original number like so

 

 

/* Define the location of the UDF library */

libname udflib '/folders/myshortcuts/Dropbox/SAS/UDFLib';
options cmplib=udflib.funcs;

/************************************************************************************
 Title: Antilog

 Purpose: Given a logarithm and it's base calculates the original number from which
          it was derived

 Restriction: None

 Syntax: Antilog(value, base)

 Required Arguments: Two numeric constants, variables or expressions

 Details: The antilog function returns the orginal number from a logarithm given the
          logarithm and it's base. If the base is <= 0 then the function returns a
          missing value

 Examples: antilog(-5,0.5) returns 32

************************************************************************************/

proc fcmp outlib=udflib.funcs.math;
	function antilog(val,base);
		if base <=0 then return(.);
		else return(base**val);
	endsub;
run;

 

Testing the Functions

 

Here is the log of a run creating a logarithm of a number to base 0.5 using logn and then converting it back with antilog. You can check the results with one of many online calculators

 

 

1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 61         
 62         libname udflib '/folders/myshortcuts/Dropbox/SAS/UDFLib';
 NOTE: Libref UDFLIB was successfully assigned as follows: 
       Engine:        V9 
       Physical Name: /folders/myshortcuts/Dropbox/SAS/UDFLib
 63         options cmplib=udflib.funcs;
 64         
 65         data _null_;
 66         
 67         logval = logn(32,0.5);
 68         
 69         put logval=;
 70         
 71         antilogval=antilog(logval,0.5);
 72         
 73         put antilogval=;
 74         run;
 
 logval=-5
 antilogval=32
 NOTE: DATA statement used (Total process time):
       real time           0.18 seconds
       cpu time            0.02 seconds

 

Conclusion

 

Whilst in the vast majority of cases one of the inbuilt logarithm functions will be perfectly satisfactory you will, very occasionally, have the need for a different base and we now have a function sitting in our library waiting for just such an occurrence. As a bonus, we also have a means of converting any logarithm back to its original number.

 

If you think you can see an improvement to these functions or if there are any other functions you would like to see created please leave a comment below.

Contributors
Your turn
Sign In!

Want to write an article? Sign in with your profile.