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