All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.github.evenjn.numeric.NumericUtils Maven / Gradle / Ivy

There is a newer version: 0.6.0
Show newest version
/**
 *
 * Copyright 2016 Marco Trevisan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package org.github.evenjn.numeric;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;
import java.util.function.Function;

import org.github.evenjn.knit.Bik;
import org.github.evenjn.knit.KnittingCursor;
import org.github.evenjn.yarn.Bi;
import org.github.evenjn.yarn.Cursor;
import org.github.evenjn.yarn.EndOfCursorException;

public class NumericUtils {

	public static double sumDoubles(Iterable numbers) {
		double r = 0;
		for (Double d: numbers) {
			r = r + d;
		}
		return r;
	}
	
	public static Summation summation(int buffer_size,  Function, Double> sum) {
		return new Summation( buffer_size, sum);
	}
	
	public static class Summation {

		private final int buffer_size;
		private Function, Double> sum;
		
		public Summation(int buffer_size, Function, Double> sum) {
			this.sum = sum;
			layers.add( new LinkedList<>( ) );
			this.buffer_size = buffer_size;
		}

		private Vector> layers = new Vector<>( );
		
		public void add(double value) {
			makeSureThereIsFreeSpace( 0 );
			layers.get( 0 ).add( value );
		}
		
		public double getSum() {
			LinkedList values = new LinkedList<>( );
			for (LinkedList list : layers) {
				for (Double d : list) {
					values.add( d );
				}	
			}
			return this.sum.apply( values );
		}
		private void makeSureThereIsFreeSpace( int level ) {
			if (level + 1 > layers.size( )) {
				layers.add( new LinkedList<>( ));
				return;
			}
			LinkedList list = layers.get( level );
			if (list.size( ) < buffer_size) {
				return;
			}
			makeSureThereIsFreeSpace( level + 1 );
			double sum = this.sum.apply( list );
			layers.get( level + 1 ).add( sum );
			list.clear( );
		}
	}

	
	public static int raiseInt( int base, int exponent ) {
		int result = 1;
		for ( int i = 0; i < exponent; i++ ) {
			result = result * base;
		}
		return result;
	}


	public static  Bi argmax( Function function, Cursor set ) {
		double max = 0d;
		I result = null;
		for ( I input : KnittingCursor.wrap( set ).once( ) ) {
			if ( result == null ) {
				result = input;
				max = function.apply( input );
				continue;
			}
			double tmp = function.apply( input );
			if ( tmp > max ) {
				max = tmp;
				result = input;
			}
		}
		return Bik.nu( result, max );
	}

	public static  I argmax( Iterable set, Function function ) {
		boolean found = false;
		double max = 0d;
		I result = null;
		for ( I input : set ) {
			double tmp = function.apply( input );
			if ( !found || tmp > max ) {
				found = true;
				result = input;
				max = tmp;
			}
		}
		return result;
	}

	public static  I argmax( Cursor set, Function function ) {
		boolean found = false;
		double max = 0d;
		I result = null;
		for ( I input : KnittingCursor.wrap( set ).once( ) ) {
			double tmp = function.apply( input );
			if ( !found || tmp > max ) {
				found = true;
				result = input;
				max = tmp;
			}
		}
		return result;
	}

	public static  Double sum( Function function, Cursor set ) {
		double result = 0d;
		for ( I input : KnittingCursor.wrap( set ).once( ) ) {
			result += function.apply( input );
		}
		return result;
	}

	public static  Double sum( Cursor set, Function function ) {
		double result = 0d;
		for ( I input : KnittingCursor.wrap( set ).once( ) ) {
			result += function.apply( input );
		}
		return result;
	}

	public static > I max( Cursor set ) {
		I result = null;
		for ( I input : KnittingCursor.wrap( set ).once( ) ) {
			if ( result == null || result.compareTo( input ) < 0 ) {
				result = input;
			}
		}
		return result;
	}

	public static > I min( Cursor set ) {
		I result = null;
		for ( I input : KnittingCursor.wrap( set ).once( ) ) {
			if ( result == null || result.compareTo( input ) > 0 ) {
				result = input;
			}
		}
		return result;
	}


	public static  Double sum( Iterable set, Function function ) {
		double result = 0d;
		for ( I input : set ) {
			result += function.apply( input );
		}
		return result;
	}

	public static  Double product( Iterable set,
			Function function ) {
		double result = 1d;
		for ( I input : set ) {
			result *= function.apply( input );
		}
		return result;
	}
	
	private static  Iterator asIterator(Cursor cursor) {
		return KnittingCursor.wrap(cursor).once().iterator();
	}
	
	/**
	 * Returns all pairs [ 0 0 ] [ 0 1 ] [ 0 2 ] .. [ 0 ( max - 1 ) ] [ 1 0 ] [ 1
	 * 1 ] [ 1 2 ] .. [ 1 ( max - 1 ) ] [ ( max - 1 ) 0 ] [ ( max - 1 ) 1 ] [ (
	 * max - 1 ) 2 ] .. [ ( max - 1 ) ( max - 1 ) ]
	 * 
	 * 
	 */
	public static Iterable> birange( final int max ) {
		return new Iterable>( ) {

			@Override
			public Iterator> iterator( ) {
				final Bik bi = Bik.nu( 0, -1 );
				return asIterator( new Cursor>( ) {

					@Override
					public Bi next( )
							throws EndOfCursorException {
						int first = bi.front( );
						int second = bi.back( );
						if ( second + 1 == max ) {
							if ( first + 1 == max )
								throw EndOfCursorException.neo();
							first = first + 1;
							second = 0;
						}
						else {
							second = second + 1;
						}
						bi.set( first, second );
						return bi;
					}

				} );

			}
		};

	}
  

	/*
	 * Range generators
	 */

	public static Iterable range( final int to ) {
		return range( 0, to );
	}

	public static Iterable range( final int from, final int to ) {
		return new Iterable( ) {

			@Override
			public Iterator iterator( ) {
				return asIterator(new Cursor( ) {

					private int current = from;

					@Override
					public Integer next( )
							throws EndOfCursorException {
						if ( current >= to )
							throw EndOfCursorException.neo();
						return current++;
					}
				} );
			}
		};
	}

	public static Iterable range( final long to ) {
		return range( 0, to );
	}

	public static Iterable range( final long from, final long to ) {
		return new Iterable( ) {

			@Override
			public Iterator iterator( ) {
				return asIterator( new Cursor( ) {

					private long current = from;

					@Override
					public Long next( )
							throws EndOfCursorException {
						if ( current >= to )
							throw EndOfCursorException.neo();
						return current++;
					}
				} );
			}
		};
	}
}