/*
 * Zorbage: an algebraic data hierarchy for use in numeric processing.
 *
 * Copyright (C) 2016-2019 Barry DeZonia
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. 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.
 * 
 * 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 THE COPYRIGHT HOLDERS OR CONTRIBUTORS 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 nom.bdezonia.zorbage.algorithm;

import nom.bdezonia.zorbage.type.algebra.Algebra;
import nom.bdezonia.zorbage.type.algebra.Multiplication;
import nom.bdezonia.zorbage.type.algebra.Unity;

/**
 * 
 * @author Barry DeZonia
 *
 */
public class PowerNonNegative {

	private PowerNonNegative() {}
	
	/**
	 * 
	 * @param algebra
	 * @param power
	 * @param a
	 * @param b
	 */
	public static <T extends Algebra<T,U> & Multiplication<U> & Unity<U>, U>
		void compute(T algebra, int power, U a, U b)
	{
		if (power < 0)
			throw new IllegalArgumentException("Cannot get negative powers from integers");
		if (power == 0) {
			if (algebra.isZero().call(a))
				throw new IllegalArgumentException("0^0 is not a number");
		}
		pow(algebra, power, a, b);
	}
	
	// this algorithm adapted from boost
	
	private static <T extends Algebra<T,U> & Multiplication<U> & Unity<U>, U>
		void pow(T algebra, int pow, U a, U b)
	{
		if (pow == 0) {
			algebra.unity().call(b);
		}
		else if (pow == 1) {
			algebra.assign().call(a, b);
		}
		else {
			U tmp = algebra.construct();
			int halfPow = pow >>> 1;
			pow(algebra, halfPow, a, tmp);
			algebra.multiply().call(tmp, tmp, tmp);
			if (pow != (halfPow << 1))
				algebra.multiply().call(tmp, a, tmp);
			algebra.assign().call(tmp, b);
		}
	}

	/*
	Boost Software License - Version 1.0 - August 17th, 2003

	Permission is hereby granted, free of charge, to any person or organization
	obtaining a copy of the software and accompanying documentation covered by
	this license (the "Software") to use, reproduce, display, distribute,
	execute, and transmit the Software, and to prepare derivative works of the
	Software, and to permit third-parties to whom the Software is furnished to
	do so, all subject to the following:

	The copyright notices in the Software and this entire statement, including
	the above license grant, this restriction and the following disclaimer,
	must be included in all copies of the Software, in whole or in part, and
	all derivative works of the Software, unless such copies or derivative
	works are solely in the form of machine-executable object code generated by
	a source language processor.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
	SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
	FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
	ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
	DEALINGS IN THE SOFTWARE.
	*/

}

@@ -2186,48 +2186,8 @@
 %7D%0A%09%0A
-%09// this algorithm adapted from boost%0A%09%0A
 %09pri
@@ -2674,1373 +2674,6 @@
 %09%7D%0A%0A
-%09/*%0A%09Boost Software License - Version 1.0 - August 17th, 2003%0A%0A%09Permission is hereby granted, free of charge, to any person or organization%0A%09obtaining a copy of the software and accompanying documentation covered by%0A%09this license (the %22Software%22) to use, reproduce, display, distribute,%0A%09execute, and transmit the Software, and to prepare derivative works of the%0A%09Software, and to permit third-parties to whom the Software is furnished to%0A%09do so, all subject to the following:%0A%0A%09The copyright notices in the Software and this entire statement, including%0A%09the above license grant, this restriction and the following disclaimer,%0A%09must be included in all copies of the Software, in whole or in part, and%0A%09all derivative works of the Software, unless such copies or derivative%0A%09works are solely in the form of machine-executable object code generated by%0A%09a source language processor.%0A%0A%09THE SOFTWARE IS PROVIDED %22AS IS%22, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR%0A%09IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,%0A%09FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT%0A%09SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE%0A%09FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,%0A%09ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER%0A%09DEALINGS IN THE SOFTWARE.%0A%09*/%0A%0A
 %7D%0A

Remove incorrect attribution