/* * File: LogMathTest.java * Authors: Justin Basilico * Company: Sandia National Laboratories * Project: Cognitive Foundry * * Copyright June 13, 2011, Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the U.S. Government. Export * of this program may require a license from the United States Government. * See CopyrightHistory.txt for complete details. * */ package gov.sandia.cognition.math; import java.util.Arrays; import java.util.LinkedList; import java.util.Random; import org.junit.Test; import static org.junit.Assert.*; /** * Unit tests for class LogMath. * * @author Justin Basilico * @since 3.3.0 */ public class LogMathTest { protected Random random = new Random(311); protected double epsilon = 1e-10; /** * Creates a new test. */ public LogMathTest() { } /** * Test of constants of class LogMath. */ @Test public void testConstants() { assertEquals(Math.log(0.0), LogMath.LOG_0, 0.0); assertEquals(Math.log(1.0), LogMath.LOG_1, 0.0); assertEquals(Math.log(2.0), LogMath.LOG_2, 0.0); assertEquals(Math.log(Math.E), LogMath.LOG_E, 0.0); assertEquals(Math.log(10.0), LogMath.LOG_10, 0.0); } /** * Test of toLog method, of class LogMath. */ @Test public void testToLog() { LinkedList<Double> values = new LinkedList<Double>(); values.addAll(Arrays.asList(0.0, 0.1, 0.5, 1.0, 2.0, 4.7, 10.0, 1e-50, 1e100)); for (int i = 0; i < 10; i++) { values.add(random.nextDouble() * 100000.0); } for (double x : values) { double logX = Math.log(x); assertEquals(logX, LogMath.toLog(x), 0.0); } // Make sure negative logs are NaNs. for (double x : values) { if (x != 0.0) { assertTrue(Double.isNaN(LogMath.toLog(-x))); } } } /** * Test of fromLog method, of class LogMath. */ @Test public void testFromLog() { LinkedList<Double> values = new LinkedList<Double>(); values.addAll(Arrays.asList(0.0, 0.1, 0.5, 1.0, 2.0, 4.7, 10.0, 1e-50, 1e100)); for (int i = 0; i < 10; i++) { values.add(random.nextDouble() * 100000.0); } for (double x : values) { double logX = Math.log(x); assertEquals(Math.exp(logX), LogMath.fromLog(LogMath.toLog(x)), 0.0); } // Make sure any number can be converted back. for (int i = 0; i < 10; i++) { double logX = (random.nextDouble() - 0.5) * 100.0; assertEquals(Math.exp(logX), LogMath.fromLog(logX), 0.0); } } /** * Test of add method, of class LogMath. */ @Test public void testAdd() { LinkedList<Double> values = new LinkedList<Double>(); values.addAll(Arrays.asList(0.0, 0.1, 0.5, 1.0, 2.0, 4.7, 10.0, 1e-50, 1e100, Double.POSITIVE_INFINITY)); for (int i = 0; i < 10; i++) { values.add(random.nextDouble() * 100000.0); } for (double x : values) { for (double y : values) { double expected = Math.log(x + y); double logX = LogMath.toLog(x); double logY = LogMath.toLog(y); double actual = LogMath.add(logX, logY); assertEquals(expected, actual, epsilon); } } } /** * Test of subtract method, of class LogMath. */ @Test public void testSubtract() { LinkedList<Double> values = new LinkedList<Double>(); values.addAll(Arrays.asList(0.0, 0.1, 0.5, 1.0, 2.0, 4.7, 10.0, 1e-200, 1e100, Double.POSITIVE_INFINITY)); for (int i = 0; i < 10; i++) { values.add(random.nextDouble() * 100000.0); } for (double x : values) { for (double y : values) { double expected = Math.log(x - y); double logX = LogMath.toLog(x); double logY = LogMath.toLog(y); double actual = LogMath.subtract(logX, logY); assertEquals(expected, actual, epsilon); if (x < y) { assertTrue(Double.isNaN(actual)); } } } } /** * Test of multiply method, of class LogMath. */ @Test public void testMultiply() { LinkedList<Double> values = new LinkedList<Double>(); values.addAll(Arrays.asList(0.0, 0.1, 0.5, 1.0, 2.0, 4.7, 10.0, 1e-50, 1e100)); for (int i = 0; i < 10; i++) { values.add(random.nextDouble() * 100000.0); } for (double x : values) { for (double y : values) { double expected = Math.log(x * y); double logX = LogMath.toLog(x); double logY = LogMath.toLog(y); double actual = LogMath.multiply(logX, logY); assertEquals(expected, actual, epsilon); assertEquals(logX + logY, actual, 0.0); } } } /** * Test of divide method, of class LogMath. */ @Test public void testDivide() { LinkedList<Double> values = new LinkedList<Double>(); values.addAll(Arrays.asList(0.0, 0.1, 0.5, 1.0, 2.0, 4.7, 10.0, 1e-50, 1e100)); for (int i = 0; i < 10; i++) { values.add(random.nextDouble() * 100000.0); } for (double x : values) { for (double y : values) { double expected = Math.log(x / y); double logX = LogMath.toLog(x); double logY = LogMath.toLog(y); double actual = LogMath.divide(logX, logY); assertEquals(expected, actual, epsilon); assertEquals(logX - logY, actual, 0.0); } } } /** * Test of inverse method, of class LogMath. */ @Test public void testInverse() { LinkedList<Double> values = new LinkedList<Double>(); values.addAll(Arrays.asList(0.0, 0.1, 0.5, 1.0, 2.0, 4.7, 10.0, 1e-50, 1e100)); for (int i = 0; i < 10; i++) { values.add(random.nextDouble() * 100000.0); } for (double x : values) { double logX = Math.log(x); double expected = Math.log(1.0 / x); double actual = LogMath.inverse(logX); assertEquals(expected, actual, epsilon); } } }