14 May 2012

Square Root Function: That Scales The Kernel

The sqrt function below uses the sqrt_kernel and findExponent functions from previous posts. Note that my actual implementation is placed in a namespace so the system sqrt will not be picked up or conflict.

#include <boost/assert.hpp>  

typedef double type_t;
const type_t epsilon = 1e-15;
const type_t ten = 10;

type_t
pow10(type_t value){
return pow( ten, value );
}

type_t
sqrt(type_t n, type_t eps = epsilon) {
BOOST_ASSERT(n >= 0);
if(n == 0) return 0.0;

type_t ScalingExponent = findExponent(n);
n *= pow10(-ScalingExponent);

type_t result = sqrt_kernel(n,eps);

type_t Exponent = findExponent(result);
return result * pow10( -Exponent + (ScalingExponent/2) );
}

04 May 2012

Finding The Exponent In Scientific Notation - Harder Than It Seems

Was needing a method to find the exponent of a number (which means that value's scientific notation exponent.) I found simpler ways for several special cases but in general this seems to work for my needs.

The farther below UnitTest++ test code uses Table I.

Table I: Used to see what the exponent is,

Debug : value = 0.0001 = 1e-4 : log10 = -4
Debug : value = 0.0005 = 5e-4 : log10 = -3.30103
Debug : value = 0.001 = 1e-3 : log10 = -3
Debug : value = 0.005 = 5e-3 : log10 = -2.30103
Debug : value = 0.01 = 1e-2 : log10 = -2
Debug : value = 0.05 = 5e-2 : log10 = -1.30103
Debug : value = 0.1 = 1e-1 : log10 = -1
Debug : value = 0.5 = 5e-1 : log10 = -0.30103
Debug : value = 1 = 1e+0 : log10 = 0
Debug : value = 2 = 2e+0 : log10 = 0.30103
Debug : value = 10 = 1e+1 : log10 = 1
Debug : value = 20 = 2e+1 : log10 = 1.30103
Debug : value = 100 = 1e+2 : log10 = 2
Debug : value = 200 = 2e+2 : log10 = 2.30103
Debug : value = 1000 = 1e+3 : log10 = 3
Debug : value = 2000 = 2e+3 : log10 = 3.30103
Debug : value = 10000 = 1e+4 : log10 = 4

The function being tested is at lines 10-13. If uses the boost modf(). Note there is some C++11 in here.
1:  #include <UnitTest++.h> 
2: #include <vector>
3: #include <boost/math/special_functions/modf.hpp>
4: namespace bm = boost::math;
5:
6: SUITE(FIND_EXPONENT) {
7: typedef double type_t;
8: const type_t epsilon = 1e-15;
9:
10: type_t findExponent(type_t value){
11: type_t intPart;
12: return ( bm::modf<type_t>( log10(fabs(value)) , &intPart ) < 0 ) ? --intPart : intPart;
13: }
14: TEST(Function_findExponent_withTableI) {
15: std::vector<type_t> values =
16: { 1e-4,5e-4, 1e-3,5e-3, 1e-2,5e-2, 1e-1,5e-1, 1e+0,2e+0, 1e+1,2e+1, 1e+2,2e+2, 1e+3,2e+3, 1e+4,2e+4 };
17: std::vector<type_t> exponents =
18: { -4,-4, -3,-3, -2,-2, -1,-1, 0,0, +1,+1, +2,+2, +3,+3, +4,+4 };
19: CHECK_EQUAL(exponents.size(), values.size());
20:
21: for(unsigned i=0; i<values.size(); ++i){
22: values.at(i) = findExponent(values.at(i));
23: }
24: CHECK_ARRAY_EQUAL(exponents,values,values.size());
25: }
26: }
27:

03 May 2012

Python For Lisp Programmers - "Interesting"

This page seems like a good reference for those interested in Python and/or Lisp. Here is a quote (the first paragraph) from the page:

'This is a brief introduction to Python for Lisp programmers. (Although it wasn't my intent, Python programmers have told me this page has helped them learn Lisp.) Basically, Python can be seen as a dialect of Lisp with "traditional" syntax (what Lisp people call "infix" or "m-lisp" syntax). One message on comp.lang.python said "I never understood why LISP was a good idea until I started playing with python." Python supports all of Lisp's essential features except macros, and you don't miss macros all that much because it does have eval, and operator overloading, and regular expression parsing, so some--but not all--of the use cases for macros are covered.'
Python For Lisp Programmers