diff --git a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Addition.java b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Addition.java new file mode 100644 index 000000000..1e3197994 --- /dev/null +++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Addition.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.core; + +/** + * Addition. + * + * @param Type of elements. + */ +public interface Addition { + /** + * Binary addition. + * + * @param a Element. + * @return {@code this + a}. + */ + T add(T a); + + /** + * Identity element. + * + * @return the field element such that for all {@code a}, + * {@code zero().add(a).equals(a)} is {@code true}. + */ + T zero(); + + /** + * Additive inverse. + * + * @return {@code -this}. + */ + T negate(); +} diff --git a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Multiplication.java b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Multiplication.java new file mode 100644 index 000000000..e94ed860a --- /dev/null +++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Multiplication.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.core; + +/** + * Multiplication. + * + * @param Type of elements. + */ +public interface Multiplication { + /** + * Binary multiplication. + * + * @param a Element. + * @return {@code this * a}. + */ + T multiply(T a); + + /** + * Identity element. + * + * @return the field element such that for all {@code a}, + * {@code one().multiply(a).equals(a)} is {@code true}. + */ + T one(); + + /** + * Multiplicative inverse. + * + * @return this-1. + */ + T reciprocal(); +} diff --git a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/NativeOperators.java b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/NativeOperators.java new file mode 100644 index 000000000..483dba2a9 --- /dev/null +++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/NativeOperators.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.core; + +/** + * Operators that can be implemented in a more performant way + * using the language constructs. + * + * @param Type of elements. + */ +public interface NativeOperators + extends Addition, + Multiplication { + /** + * Binary subtraction. + * + * @param a Element. + * @return {@code this - a}. + */ + T subtract(T a); + + /** + * Binary division. + * + * @param a Element. + * @return {@code this / a}. + */ + T divide(T a); + + /** + * Repeated addition. + * + * @param n Number of times to add {@code this} to itself. + * @return {@code n * this}. + */ + T multiply(int n); + + /** + * Repeated multiplication. + * + * @param n Number of times to multiply {@code this} with itself. + * @return {@code this^n}. + */ + T pow(int n); +} diff --git a/commons-numbers-field/LICENSE.txt b/commons-numbers-field/LICENSE.txt new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/commons-numbers-field/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/commons-numbers-field/NOTICE.txt b/commons-numbers-field/NOTICE.txt new file mode 100644 index 000000000..9091baa67 --- /dev/null +++ b/commons-numbers-field/NOTICE.txt @@ -0,0 +1,6 @@ +Apache Commons Numbers +Copyright 2001-2017 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + diff --git a/commons-numbers-field/README.md b/commons-numbers-field/README.md new file mode 100644 index 000000000..aef0c98e7 --- /dev/null +++ b/commons-numbers-field/README.md @@ -0,0 +1,98 @@ + + +Apache Commons Numbers Field +=================== + +Utilities related to the concept of field. + +Documentation +------------- + +More information can be found on the [homepage](https://commons.apache.org/proper/commons-numbers). +The [JavaDoc](https://commons.apache.org/proper/commons-numbers/javadocs/api-release) can be browsed. +Questions related to the usage of Apache Commons Numbers Field should be posted to the [user mailing list][ml]. + +Where can I get the latest release? +----------------------------------- +You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-numbers/download_numbers.cgi). + +Alternatively you can pull it from the central Maven repositories: + +```xml + + org.apache.commons + commons-numbers-field + 1.0 + +``` + +Contributing +------------ + +We accept PRs via github. The [developer mailing list][ml] is the main channel of communication for contributors. +There are some guidelines which will make applying PRs easier for us: ++ No tabs! Please use spaces for indentation. ++ Respect the code style. ++ Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change. ++ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn clean test```. + +If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas). +You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md). + +License +------- +Code is under the [Apache Licence v2](https://www.apache.org/licenses/LICENSE-2.0.txt). + +Donations +--------- +You like Apache Commons Numbers Field? Then [donate back to the ASF](https://www.apache.org/foundation/contributing.html) to support the development. + +Additional Resources +-------------------- + ++ [Apache Commons Homepage](https://commons.apache.org/) ++ [Apache Bugtracker (JIRA)](https://issues.apache.org/jira/) ++ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons) ++ #apachecommons IRC channel on freenode.org + +[ml]:https://commons.apache.org/mail-lists.html diff --git a/commons-numbers-field/pom.xml b/commons-numbers-field/pom.xml new file mode 100644 index 000000000..5295443fd --- /dev/null +++ b/commons-numbers-field/pom.xml @@ -0,0 +1,63 @@ + + + + 4.0.0 + + + org.apache.commons + commons-numbers-parent + 1.0-SNAPSHOT + + + org.apache.commons + commons-numbers-field + 1.0-SNAPSHOT + Apache Commons Numbers Field + + Utilities related to the concept of field. + + + + org.apache.commons.numbers.field + + org.apache.commons.numbers.field + + ${basedir}/.. + + + + + org.apache.commons + commons-numbers-core + + + org.apache.commons + commons-numbers-fraction + + + + org.apache.commons + commons-numbers-core + test-jar + test + + + + diff --git a/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/AbstractField.java b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/AbstractField.java new file mode 100644 index 000000000..b5a4ad072 --- /dev/null +++ b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/AbstractField.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.field; + +import org.apache.commons.numbers.core.NativeOperators; + +/** + * Boiler-plate code for concrete implementations of {@link Field}. + * + * @param Type of the field elements. + */ +public abstract class AbstractField> + implements Field { + /** {@inheritDoc} */ + @Override + public T add(T a, T b) { + return a.add(b); + } + + /** {@inheritDoc} */ + @Override + public T subtract(T a, T b) { + return a.subtract(b); + } + + /** {@inheritDoc} */ + @Override + public T negate(T a) { + return a.negate(); + } + + /** {@inheritDoc} */ + @Override + public T multiply(int n, T a) { + return a.multiply(n); + } + + /** {@inheritDoc} */ + @Override + public T multiply(T a, T b) { + return a.multiply(b); + } + + /** {@inheritDoc} */ + @Override + public T divide(T a, T b) { + return a.divide(b); + } + + /** {@inheritDoc} */ + @Override + public T reciprocal(T a) { + return a.reciprocal(); + } +} diff --git a/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/FP64.java b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/FP64.java new file mode 100644 index 000000000..9bac221f4 --- /dev/null +++ b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/FP64.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.field; + +import org.apache.commons.numbers.core.NativeOperators; +import org.apache.commons.numbers.core.Precision; + +/** + * Wraps a {@code double} value in order to be used as a field + * element. + */ +public class FP64 extends Number + implements NativeOperators, + Comparable { + /** Additive neutral. */ + private static final FP64 ZERO = new FP64(0); + /** Multiplicative neutral. */ + private static final FP64 ONE = new FP64(1); + /** Value. */ + private final double value; + + /** + * @param value Value. + */ + public FP64(double value) { + this.value = value; + } + + /** {@inheritDoc} */ + @Override + public FP64 add(FP64 a) { + return new FP64(value + a.value); + } + + /** {@inheritDoc} */ + @Override + public FP64 negate() { + return new FP64(-value); + } + + /** {@inheritDoc} */ + @Override + public FP64 multiply(FP64 a) { + return new FP64(value * a.value); + } + + /** {@inheritDoc} */ + @Override + public FP64 reciprocal() { + return new FP64(1 / value); + } + + /** {@inheritDoc} */ + @Override + public FP64 subtract(FP64 a) { + return new FP64(value - a.value); + } + + /** {@inheritDoc} */ + @Override + public FP64 divide(FP64 a) { + return new FP64(value / a.value); + } + + /** {@inheritDoc} */ + @Override + public FP64 multiply(int n) { + return new FP64(value * n); + } + + /** {@inheritDoc} */ + @Override + public FP64 pow(int n) { + if (n == 0) { + return ONE; + } + + return new FP64(Math.pow(value, n)); + } + + /** {@inheritDoc} */ + @Override + public boolean equals(Object other) { + if (other instanceof FP64) { + final FP64 o = (FP64) other; + return Precision.equals(value, o.value, 1); + } + return false; + } + + /** {@inheritDoc} */ + @Override + public int hashCode() { + return Double.valueOf(value).hashCode(); + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return Double.toString(value); + } + + /** {@inheritDoc} */ + @Override + public double doubleValue() { + return value; + } + /** {@inheritDoc} */ + @Override + public float floatValue() { + return (float) value; + } + /** {@inheritDoc} */ + @Override + public int intValue() { + return (int) value; + } + /** {@inheritDoc} */ + @Override + public long longValue() { + return (long) value; + } + /** {@inheritDoc} */ + @Override + public byte byteValue() { + return (byte) value; + } + + /** {@inheritDoc} */ + @Override + public int compareTo(FP64 other) { + return Double.compare(value, other.value); + } + + /** {@inheritDoc} */ + @Override + public FP64 zero() { + return ZERO; + } + + /** {@inheritDoc} */ + @Override + public FP64 one() { + return ONE; + } +} diff --git a/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/FP64Field.java b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/FP64Field.java new file mode 100644 index 000000000..f63665cb2 --- /dev/null +++ b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/FP64Field.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.field; + +/** + * {@link Double} field. + */ +public class FP64Field extends AbstractField { + /** 0d */ + private static final FP64 ZERO = new FP64(Double.valueOf(0)); + /** 1d */ + private static final FP64 ONE = new FP64(Double.valueOf(1)); + + /** {@inheritDoc} */ + @Override + public FP64 one() { + return ONE; + } + + /** {@inheritDoc} */ + @Override + public FP64 zero() { + return ZERO; + } +} diff --git a/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/Field.java b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/Field.java new file mode 100644 index 000000000..6ddf0858b --- /dev/null +++ b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/Field.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.field; + +/** + * Interface representing a field. + * + * @param Type of the field elements. + */ +public interface Field { + /** + * @param a Field element. + * @param b Field element. + * @return {@code a + b}. + */ + T add(T a, T b); + + /** + * @param a Field element. + * @param b Field element. + * @return {@code a - b}. + */ + T subtract(T a, T b); + + /** + * @param a Field element. + * @return {@code -a}. + */ + T negate(T a); + + /** + * @param a Field element. + * @param n Number of times {@code a} must be added to itself. + * @return {@code n a}. + */ + T multiply(int n, T a); + + /** + * @param a Field element. + * @param b Field element. + * @return {@code a * b}. + */ + T multiply(T a, T b); + + /** + * @param a Field element. + * @param b Field element. + * @return a * b-1. + */ + T divide(T a, T b); + + /** + * @param a Field element. + * @return a-1. + */ + T reciprocal(T a); + + /** + * @return the field element {@code 1} such that for all {@code a}, + * {@code 1 * a == a}. + */ + T one(); + + /** + * @return the field element {@code 0} such that for all {@code a}, + * {@code 0 + a == a}. + */ + T zero(); +} diff --git a/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/FractionField.java b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/FractionField.java new file mode 100644 index 000000000..941225d13 --- /dev/null +++ b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/FractionField.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.field; + +import org.apache.commons.numbers.fraction.Fraction; + +/** + * {@link Fraction} field. + */ +public class FractionField extends AbstractField { + /** {@inheritDoc} */ + @Override + public Fraction one() { + return Fraction.ONE; + } + + /** {@inheritDoc} */ + @Override + public Fraction zero() { + return Fraction.ZERO; + } +} diff --git a/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/package-info.java b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/package-info.java new file mode 100644 index 000000000..e92331265 --- /dev/null +++ b/commons-numbers-field/src/main/java/org/apache/commons/numbers/field/package-info.java @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Field-related utilities. + */ +package org.apache.commons.numbers.field; diff --git a/commons-numbers-field/src/site/resources/profile.jacoco b/commons-numbers-field/src/site/resources/profile.jacoco new file mode 100644 index 000000000..a12755f3b --- /dev/null +++ b/commons-numbers-field/src/site/resources/profile.jacoco @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ----------------------------------------------------------------------------- +# +# Empty file used to automatically trigger JaCoCo profile from commons parent pom diff --git a/commons-numbers-field/src/site/site.xml b/commons-numbers-field/src/site/site.xml new file mode 100644 index 000000000..61fd005c9 --- /dev/null +++ b/commons-numbers-field/src/site/site.xml @@ -0,0 +1,35 @@ + + + + + Apache Commons Numbers + /images/commons_numbers.small.png + /index.html + + + + + + + + + + + diff --git a/commons-numbers-field/src/site/xdoc/index.xml b/commons-numbers-field/src/site/xdoc/index.xml new file mode 100644 index 000000000..74187e720 --- /dev/null +++ b/commons-numbers-field/src/site/xdoc/index.xml @@ -0,0 +1,39 @@ + + + + + + + Commons Numbers Field + + + + +
+

+ Commons Numbers provides utilities such as complex numbers and fractions. +

+ +

+ The "field" module contains utilities related to the concept of field. +

+
+ + + +
diff --git a/commons-numbers-field/src/test/java/org/apache/commons/numbers/field/FieldParametricTest.java b/commons-numbers-field/src/test/java/org/apache/commons/numbers/field/FieldParametricTest.java new file mode 100644 index 000000000..faea48cfb --- /dev/null +++ b/commons-numbers-field/src/test/java/org/apache/commons/numbers/field/FieldParametricTest.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.field; + +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * Tests for fields. + */ +@RunWith(value=Parameterized.class) +public class FieldParametricTest { + /** Field under test. */ + private final Field field; + private final Object a; + private final Object b; + private final Object c; + + /** + * Initializes data instance. + * + * @param data Field data to be tested. + */ + public FieldParametricTest(FieldTestData data) { + this.field = data.getField(); + this.a = data.getA(); + this.b = data.getB(); + this.c = data.getC(); + } + + @Parameters(name = "{index}: data={0}") + public static Iterable getList() { + return FieldsList.list(); + } + + @Test + public void testAdditionAssociativity() { + final Object r1 = field.add(field.add(a, b), c); + final Object r2 = field.add(a, field.add(b, c)); + assertEquals(r1, r2); + } + @Test + public void testAdditionCommutativity() { + final Object r1 = field.add(a, b); + final Object r2 = field.add(b, a); + assertEquals(r1, r2); + } + @Test + public void testAdditiveIdentity() { + final Object r1 = field.add(a, field.zero()); + final Object r2 = a; + assertEquals(r1, r2); + } + @Test + public void testAdditiveInverse() { + final Object r1 = field.add(a, field.negate(a)); + final Object r2 = field.zero(); + assertEquals(r1, r2); + } + + @Test + public void testMultiplicationAssociativity() { + final Object r1 = field.multiply(field.multiply(a, b), c); + final Object r2 = field.multiply(a, field.multiply(b, c)); + assertEquals(r1, r2); + } + @Test + public void testMultiplicationCommutativity() { + final Object r1 = field.multiply(a, b); + final Object r2 = field.multiply(b, a); + assertEquals(r1, r2); + } + @Test + public void testMultiplicativeIdentity() { + final Object r1 = field.multiply(a, field.one()); + final Object r2 = a; + assertEquals(r1, r2); + } + @Test + public void testMultiplicativeInverse() { + final Object r1 = field.multiply(a, field.reciprocal(a)); + final Object r2 = field.one(); + assertEquals(r1, r2); + } + + @Test + public void testDistributivity() { + final Object r1 = field.multiply(a, field.add(b, c)); + final Object r2 = field.add(field.multiply(a, b), field.multiply(a, c)); + assertEquals(r1, r2); + } + + /** + * @param a Instance. + * @param b Instance. + */ + private void assertEquals(Object a, + Object b) { + Assert.assertTrue(a + " != " + b, + a.equals(b)); + } +} diff --git a/commons-numbers-field/src/test/java/org/apache/commons/numbers/field/FieldTestData.java b/commons-numbers-field/src/test/java/org/apache/commons/numbers/field/FieldTestData.java new file mode 100644 index 000000000..82dc1a0c3 --- /dev/null +++ b/commons-numbers-field/src/test/java/org/apache/commons/numbers/field/FieldTestData.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.field; + +import java.util.Arrays; + +/** + * Data store for {@link FieldParametricTest}. + */ +class FieldTestData { + private final Field field; + private final Object a; + private final Object b; + private final Object c; + + public FieldTestData(Field field, + Object a, + Object b, + Object c) { + this.field = field; + this.a = a; + this.b = b; + this.c = c; + } + + public Field getField() { + return field; + } + + public Object getA() { + return a; + } + + public Object getB() { + return b; + } + + public Object getC() { + return c; + } + + @Override + public String toString() { + return field.toString() + " [a=" + a + ", b=" + b + ", c=" + c + "]"; + } +} diff --git a/commons-numbers-field/src/test/java/org/apache/commons/numbers/field/FieldsList.java b/commons-numbers-field/src/test/java/org/apache/commons/numbers/field/FieldsList.java new file mode 100644 index 000000000..0dc52ccba --- /dev/null +++ b/commons-numbers-field/src/test/java/org/apache/commons/numbers/field/FieldsList.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.numbers.field; + +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; + +import org.apache.commons.numbers.fraction.Fraction; + +/** + * List of fields. + */ +public class FieldsList { + /** List of all fields implemented in the library. */ + private static final List LIST = + new ArrayList(); + + static { + try { + // List of fields to test. + add(new FractionField(), + new Fraction(13, 4), + new Fraction(5, 29), + new Fraction(-279, 11)); + add(new FP64Field(), + new FP64(23.45678901), + new FP64(-543.2109876), + new FP64(-234.5678901)); + + } catch (Exception e) { + System.err.println("Unexpected exception while creating the list of fields: " + e); + e.printStackTrace(System.err); + throw new RuntimeException(e); + } + } + + /** + * @param field Field. + * @param a Field element. + * @param b Field element. + */ + private static void add(Field field, + T a, + T b, + T c) { + LIST.add(new FieldTestData[] { new FieldTestData(field, a, b, c) }); + } + + /** + * Subclasses that are "parametric" tests can forward the call to + * the "@Parameters"-annotated method to this method. + * + * @return the list of all fields. + */ + public static Iterable list() { + return Collections.unmodifiableList(LIST); + } +} diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java index 5639be1e5..308f93033 100644 --- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java +++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java @@ -19,15 +19,16 @@ import java.io.Serializable; import java.math.BigInteger; import org.apache.commons.numbers.core.ArithmeticUtils; +import org.apache.commons.numbers.core.NativeOperators; /** * Representation of a rational number. - * - * implements Serializable since 2.0 */ public class Fraction extends Number - implements Comparable, Serializable { + implements Comparable, + Serializable, + NativeOperators { /** A fraction representing "2 / 1". */ public static final Fraction TWO = new Fraction(2, 1); @@ -397,6 +398,18 @@ public long longValue() { return (long)doubleValue(); } + /** {@inheritDoc} */ + @Override + public Fraction zero() { + return ZERO; + } + + /** {@inheritDoc} */ + @Override + public Fraction one() { + return ONE; + } + /** * Return the additive inverse of this fraction. * @return the negation of this fraction. diff --git a/pom.xml b/pom.xml index 433ee4215..e39d75583 100644 --- a/pom.xml +++ b/pom.xml @@ -74,23 +74,28 @@ - - org.apache.commons - commons-numbers-core - ${project.version} - - - org.apache.commons - commons-numbers-complex - ${project.version} - - - org.apache.commons - commons-numbers-core - ${project.version} - test-jar - test - + + org.apache.commons + commons-numbers-core + ${project.version} + + + org.apache.commons + commons-numbers-complex + ${project.version} + + + org.apache.commons + commons-numbers-fraction + ${project.version} + + + org.apache.commons + commons-numbers-core + ${project.version} + test-jar + test + @@ -608,6 +613,7 @@ commons-numbers-gamma commons-numbers-combinatorics commons-numbers-arrays + commons-numbers-field