001/* 002 * $Id$ 003 */ 004 005package edu.jas.structure; 006 007 008 009/** 010 * Monoid element interface. Defines the multiplicative methods. 011 * @param <C> element type 012 * @author Heinz Kredel 013 */ 014 015public interface MonoidElem<C extends MonoidElem<C>> extends Element<C> { 016 017 018 /** 019 * Test if this is one. 020 * @return true if this is 1, else false. 021 */ 022 public boolean isONE(); 023 024 025 /** 026 * Test if this is a unit. I.e. there exists x with this.multiply(x).isONE() 027 * == true. 028 * @return true if this is a unit, else false. 029 */ 030 public boolean isUnit(); 031 032 033 /** 034 * Multiply this with S. 035 * @param S 036 * @return this * S. 037 */ 038 public C multiply(C S); 039 040 041 /** 042 * Divide this by S. 043 * @param S 044 * @return this / S. 045 */ 046 public C divide(C S); 047 048 049 /** 050 * Remainder after division of this by S. 051 * @param S 052 * @return this - (this / S) * S. 053 */ 054 public C remainder(C S); 055 056 057 /** 058 * Quotient and remainder by division of this by S. 059 * @param S 060 * @return [this/S, this - (this/S)*S]. 061 */ 062 @SuppressWarnings("unchecked") 063 default public C[] quotientRemainder(C S) { 064 return (C[]) new MonoidElem[] { divide(S), remainder(S) }; 065 } 066 067 068 /** 069 * Right division. 070 * Returns commutative divide if not overwritten. 071 * @param a element. 072 * @return right, with a * right = this 073 */ 074 default public C rightDivide(C a) { 075 if (((MonoidFactory<C>)factory()).isCommutative()) { 076 return divide(a); 077 } 078 throw new UnsupportedOperationException("operation not implemented"); 079 } 080 081 082 /** 083 * Left division. 084 * Returns commutative divide if not overwritten. 085 * @param a element. 086 * @return left, with left * a = this 087 */ 088 default public C leftDivide(C a) { 089 if (((MonoidFactory<C>)factory()).isCommutative()) { 090 return divide(a); 091 } 092 throw new UnsupportedOperationException("operation not implemented"); 093 } 094 095 096 /** 097 * Right remainder. 098 * Returns commutative remainder if not overwritten. 099 * @param a element. 100 * @return r = this - a * (1/right), where a * right = this. 101 */ 102 default public C rightRemainder(C a) { 103 if (((MonoidFactory<C>)factory()).isCommutative()) { 104 return remainder(a); 105 } 106 throw new UnsupportedOperationException("operation not implemented"); 107 } 108 109 110 /** 111 * Left remainder. 112 * Returns commutative remainder if not overwritten. 113 * @param a element. 114 * @return r = this - (1/left) * a, where left * a = this. 115 */ 116 default public C leftRemainder(C a) { 117 if (((MonoidFactory<C>)factory()).isCommutative()) { 118 return remainder(a); 119 } 120 throw new UnsupportedOperationException("operation not implemented"); 121 } 122 123 124 /** 125 * Two-sided division. 126 * Returns commutative divide if not overwritten. 127 * @param a element. 128 * @return [left,right], with left * a * right = this 129 */ 130 @SuppressWarnings("unchecked") 131 default public C[] twosidedDivide(C a) { 132 if (((MonoidFactory<C>)factory()).isCommutative()) { 133 C[] ret = (C[]) new MonoidElem[2]; 134 ret[0] = divide(a); 135 ret[1] = ((MonoidFactory<C>)factory()).getONE(); 136 return ret; 137 } 138 throw new UnsupportedOperationException("operation not implemented"); 139 } 140 141 142 /** 143 * Two-sided remainder. 144 * Returns commutative remainder if not overwritten. 145 * @param a element. 146 * @return r = this - (a/left) * a * (a/right), where left * a * right = this. 147 */ 148 default public C twosidedRemainder(C a){ 149 if (((MonoidFactory<C>)factory()).isCommutative()) { 150 return remainder(a); 151 } 152 throw new UnsupportedOperationException("operation not implemented"); 153 } 154 155 156 /** 157 * Inverse of this. Some implementing classes will throw 158 * NotInvertibleException if the element is not invertible. 159 * @return x with this * x = 1, if it exists. 160 */ 161 public C inverse(); /*throws NotInvertibleException*/ 162 163 164 /** 165 * Power of this to the n-th. 166 * @param n integer exponent. 167 * @return a**n, with a**0 = 1 and a**{-n} = {1/a}**n. 168 * Java 8 only 169 */ 170 @SuppressWarnings("unchecked") 171 default public C power(long n) { 172 //System.out.println("this = " + this + ", n = " + n); 173 return Power.<C>power((MonoidFactory<C>)factory(), (C)this, n); 174 } 175 176}