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

example.BreakingLimits Maven / Gradle / Ivy

/*
 * Zorbage: an algebraic data hierarchy for use in numeric processing.
 *
 * Copyright (c) 2016-2021 Barry DeZonia All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list
 * of conditions and the following disclaimer.
 * 
 * Redistributions in binary form must reproduce the above copyright notice, this
 * list of conditions and the following disclaimer in the documentation and/or other
 * materials provided with the distribution.
 * 
 * Neither the name of the  nor the names of its contributors may
 * be used to endorse or promote products derived from this software without specific
 * prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */
package example;

import java.math.BigInteger;

import nom.bdezonia.zorbage.algebra.G;
import nom.bdezonia.zorbage.datasource.IndexedDataSource;
import nom.bdezonia.zorbage.procedure.Procedure1;
import nom.bdezonia.zorbage.procedure.Procedure2;
import nom.bdezonia.zorbage.storage.Storage;
import nom.bdezonia.zorbage.type.gaussian.int16.GaussianInt16Member;
import nom.bdezonia.zorbage.type.integer.int12.SignedInt12Member;
import nom.bdezonia.zorbage.type.integer.int128.SignedInt128Member;
import nom.bdezonia.zorbage.type.integer.int128.UnsignedInt128Member;
import nom.bdezonia.zorbage.type.integer.int32.SignedInt32Member;
import nom.bdezonia.zorbage.type.integer.int4.UnsignedInt4Member;
import nom.bdezonia.zorbage.type.integer.int64.SignedInt64Member;
import nom.bdezonia.zorbage.type.integer.int8.UnsignedInt8Member;
import nom.bdezonia.zorbage.type.integer.unbounded.UnboundedIntMember;
import nom.bdezonia.zorbage.type.rational.RationalMember;
import nom.bdezonia.zorbage.type.real.float128.Float128Member;
import nom.bdezonia.zorbage.type.real.float16.Float16Member;

/**
 * @author Barry DeZonia
 */
class BreakingLimits {
	
	// Zorbage breaks through a lot of limitations that Java normally imposes on its programs:
	
	/*
	 * Array/List lengths
	 *   Java imposes a 2^31 limit on list lengths. Arrays are indexed by 32-bit ints.
	 *   Zorbage allows a 2^63 limit on list lengths. Zorbage arrays are indexed by 64-bit ints.
	 *     In memory arrays can be glued together if needed to make huge in memory data structures.
	 *     Other list abstractions exist to provide ways of making huge lists of data.
	 */
	
	void example1() {

		SignedInt12Member value = G.INT12.construct();
		
		IndexedDataSource list = Storage.allocate(value, 17L * 1000 * 1000 * 1000);
		
		System.out.println(list.size()); // prints 17000000000
		
		for (long i = 0; i < list.size(); i++) {
			G.INT12.random().call(value);
			list.set(i, value);
		}
	}
	
	/*
	 * Unsigned numbers
	 *   Java does not support unsigned integers
	 *   Zorbage does support unsigned integers (from 1 bit to 128 bit)
	 */
	
	void example2() {
		
		UnsignedInt4Member u4 = G.UINT4.construct();  // stores values from 0 to 15
		
		u4.setV(14);
		
		System.out.println(u4.v()); // prints 14
		
		G.UINT4.succ().call(u4, u4); // increment

		System.out.println(u4.v()); // prints 15
		
		G.UINT4.succ().call(u4, u4); // increment

		System.out.println(u4.v());  // prints 0
		
	}
	
	/*
	 * Function pointers
	 *   Java does not support function pointers
	 *   Zorbage supports passing around 1st class type safe function and procedure pointers
	 */
	
	void example3() {
		
		// setup some temp variables
		
		SignedInt64Member value = G.INT64.construct();
		
		SignedInt64Member zero = G.INT64.construct();
		
		// get a pointer to the random value function for the 64-bit signed integer type
		
		Procedure1 randProc = G.INT64.random();
		
		// get a pointer to the absolute value function for the 64-bit signed integer type
		
		Procedure2 absProc = G.INT64.abs();
		
		// generate some results
		
		for (long i = 0; i < 45; i++) {
			
			// get a value
			randProc.call(value);
			
			// test it
			if (G.INT64.isLess().call(value, zero))
				System.out.println("Something is negative");
			
			// now make all values move into positive range
			absProc.call(value, value);
			
			// test it
			if (G.INT64.isLess().call(value, zero))
				System.out.println("Something went wrong");
		}
	}
	
	/*
	 * Many floating point types
	 *   Java supports 32 bit and 64 bit floating types
	 *   Zorbage supports 16 bit, 32 bit, 64 bit, 128 bit, and seemingly limitless precision floating
	 *   point numbers.
	 *   
	 *     One nice thing about floating point in Zorbage is that you can write one algorithm and by
	 *     passing it different parameters you can compute a result with 3 places precision or 7 places
	 *     precision or 16 places or even 4000. You can see this in the FloatingTypes example in this
	 *     directory.
	 */
	
	void example4() {
	
		Float16Member value16 = G.HLF.construct();
		
		value16.setV(13.1f);
		
		G.HLF.add().call(value16, value16, value16);
		
		System.out.println(value16.v()); // prints 26.2
		
		Float128Member value128 = G.QUAD.construct();
		
		value128.setFromLong(1234567890123456L);
		
		System.out.println(value128.v()); // prints 1234567890123456.0
	}
	
	/*
	 * Pass by reference of primitive types:
	 *   In Java you cannot write a method that changes the value of a primitive type
	 *   (int, float, etc.).
	 *   In Zorbage pass by reference even works with primitive types.
	 */
	
	void example5() {
		
		Procedure1 doubleIt =
				new Procedure1()
		{
			@Override
			public void call(SignedInt32Member value) {
				G.INT32.add().call(value, value, value);
			}
		};
		
		SignedInt32Member value = G.INT32.construct();
		
		// set the value to 1
		
		G.INT32.unity().call(value);
		
		// now double it
		
		doubleIt.call(value);

		// double it again
		
		doubleIt.call(value);
		
		// double it one more time
		
		doubleIt.call(value);
		
		// print result
		
		System.out.println(value.v()); // prints 8
	}
	
	/*
	 *   
	 * Non byte-aligned integers
	 *   In Java the integers are always byte aligned: 8 bit byte, 16 bit short, 32 bit int,
	 *     64 bit long.
	 *   In Zorbage all these types are present but also signed and unsiged integers of bit
	 *     depth 1, 2, 3, etc. all the way up to 16-bits are present.
	 */
	
	void example6() {

		// You've already seen some examples above

		// construct the integers that match Java's standard bit-depths
		
		G.INT8.construct();
		G.INT16.construct();
		G.INT32.construct();
		G.INT64.construct();

		// now construct some nonstandard signed integer types
		
		G.INT1.construct();
		G.INT2.construct();
		G.INT3.construct();
		G.INT4.construct();
		G.INT5.construct();
		G.INT6.construct();
		G.INT7.construct();
		G.INT9.construct();
		G.INT10.construct();
		G.INT11.construct();
		G.INT12.construct();
		G.INT13.construct();
		G.INT14.construct();
		G.INT15.construct();
		G.INT128.construct();
		
		// now construct unsigned integer types : all nonstandard according to Java
		
		G.UINT1.construct();
		G.UINT2.construct();
		G.UINT3.construct();
		G.UINT4.construct();
		G.UINT5.construct();
		G.UINT6.construct();
		G.UINT7.construct();
		G.UINT8.construct();
		G.UINT9.construct();
		G.UINT10.construct();
		G.UINT11.construct();
		G.UINT12.construct();
		G.UINT13.construct();
		G.UINT14.construct();
		G.UINT15.construct();
		G.UINT16.construct();
		G.UINT32.construct();
		G.UINT64.construct();
		G.UINT128.construct();
		
	}
	
	/*
	 * Specialized numeric types
	 *   Zorbage supports things Java does not:
	 *   - 128 bit signed integers (SignedInt128Member)
	 *   - 128 bit unsigned integers (UnsignedInt128Member)
	 *   - unbounded integers (UnboundedIntMember)
	 *   - rational numbers (RationalMember)
	 *       Rational numbers are great for safely scaling lists of integers while avoiding overflow and
	 *       underflow and double precision math and rounding.
	 *   - gaussian integers
	 */

	void example7() {
		
		// signed 128 bit ints
		
		SignedInt128Member value128s = G.INT128.construct();
		
		value128s.setV(BigInteger.ONE.add(BigInteger.ONE).pow(93)); // set to 2^93
		
		// unsigned 128 bit ints
		
		UnsignedInt128Member value128u = G.UINT128.construct();
		
		value128u.setV(BigInteger.ONE.add(BigInteger.ONE).pow(93)); // set to 2^93
		
		// unbounded ints
		
		UnboundedIntMember valueUB = G.UNBOUND.construct();
		
		valueUB.setV(BigInteger.ONE.add(BigInteger.ONE).pow(264)); // set to 2^264
		
		// rational numbers
		
		RationalMember rationalScale = new RationalMember(7,5);  // 7/5's : a little more than one
		
		UnsignedInt8Member value = G.UINT8.construct("128");
		
		G.UINT8.scaleByRational().call(rationalScale, value, value);
		
		System.out.println(value.v()); // prints 179
		
		// notice how the number did not overflow even though 128 * 7 / 5 does temporarily exceed 255
		
		// gaussian integers
		
		GaussianInt16Member g16 = G.GAUSS16.construct("{4,3}");
		
		G.GAUSS16.scaleByRational().call(rationalScale, g16, g16);
		
		System.out.println(g16);  // prints {5,4}
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy