package aalg.algebra;

import java.math.BigInteger;

/**
 * Base implementation of monoid.
 * @author Ing. Petr Ležák
 *
 * @param <T> type of element
 */
public abstract class MonoidImpl<T extends IElement> implements IMonoid<T> {

	/**
	 * Applies operation to repeatCount bases.
	 * Transforms repeatCount to binary representation and uses exponentiation-by-squaring algorithm.
	 * @param base base element
	 * @param repeatCount number of bases
	 * @return base * base * ... * base, base is used repeatCount times.
	 */
	@Override
	public T repeatOperation (final T base, final BigInteger repeatCount) {
		T result = getIdentity();
		
		for (int i = repeatCount.bitLength() - 1; i >= 0; i--) {
			if (repeatCount.testBit(i))
				result = operation(result, base);
			
			if (i > 0)
				result = operation(result, result);
		}
		
		return result;
	}

}
