Additions to GREL:
* Factorial function allowing variable steps * GreatestCommonDenominator function * LeastCommonMultiple function * Multinomial function * Quotient function git-svn-id: http://google-refine.googlecode.com/svn/trunk@1910 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
43d0de2d8a
commit
09fa36198c
@ -60,9 +60,9 @@ public class Combin implements Function {
|
||||
throw new IllegalArgumentException ("the number of elements, n, should be larger than the number of combinations, k");
|
||||
if (n < 1)
|
||||
throw new IllegalArgumentException ("the number of elements, n, cannot be less than 1");
|
||||
int nFact = Fact.factorial(n);
|
||||
int rFact = Fact.factorial(k);
|
||||
int nminusrFact = Fact.factorial(n - k);
|
||||
int nFact = FactN.factorial(n, 1);
|
||||
int rFact = FactN.factorial(k, 1);
|
||||
int nminusrFact = FactN.factorial(n - k, 1);
|
||||
return nFact / (rFact * nminusrFact);
|
||||
}
|
||||
|
||||
|
@ -46,22 +46,11 @@ public class Fact implements Function {
|
||||
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
if (args.length == 1 && args[0] != null && args[0] instanceof Number) {
|
||||
return Fact.factorial(((Number) args[0]).intValue());
|
||||
return FactN.factorial(((Number) args[0]).intValue(), 1);
|
||||
}
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects a number");
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the factorial of an integer, i.
|
||||
* Returns 1 for zero and negative integers.
|
||||
*/
|
||||
public static int factorial(int i){
|
||||
if(i <= 1)
|
||||
return 1;
|
||||
else
|
||||
return i * Fact.factorial(i - 1);
|
||||
}
|
||||
|
||||
public void write(JSONWriter writer, Properties options)
|
||||
throws JSONException {
|
||||
|
||||
|
80
main/src/com/google/refine/expr/functions/math/FactN.java
Normal file
80
main/src/com/google/refine/expr/functions/math/FactN.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
|
||||
Copyright 2010, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
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
|
||||
OWNER 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 com.google.refine.expr.functions.math;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
import com.google.refine.expr.EvalError;
|
||||
import com.google.refine.grel.ControlFunctionRegistry;
|
||||
import com.google.refine.grel.Function;
|
||||
|
||||
public class FactN implements Function {
|
||||
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
if (args.length != 2)
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects two numbers");
|
||||
if(args[0] == null || !(args[0] instanceof Number))
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects the first parameter to be a number");
|
||||
if(args[1] == null && !(args[1] instanceof Number))
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects the second parameter to be a number");
|
||||
|
||||
return FactN.factorial(((Number) args[0]).intValue(), ((Number) args[1]).intValue());
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the factorial of an integer, i, for a decreasing step of n.
|
||||
* e.g. A double factorial would have a step of 2.
|
||||
* Returns 1 for zero and negative integers.
|
||||
*/
|
||||
public static int factorial(int i, int step){
|
||||
if(i <= 1)
|
||||
return 1;
|
||||
else
|
||||
return i * FactN.factorial(i - step, step);
|
||||
}
|
||||
|
||||
public void write(JSONWriter writer, Properties options)
|
||||
throws JSONException {
|
||||
|
||||
writer.object();
|
||||
writer.key("description"); writer.value("Returns the factorial of a number");
|
||||
writer.key("params"); writer.value("number i");
|
||||
writer.key("returns"); writer.value("number");
|
||||
writer.endObject();
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
|
||||
Copyright 2010, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
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
|
||||
OWNER 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 com.google.refine.expr.functions.math;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
import com.google.refine.expr.EvalError;
|
||||
import com.google.refine.grel.ControlFunctionRegistry;
|
||||
import com.google.refine.grel.Function;
|
||||
|
||||
public class GreatestCommonDenominator implements Function {
|
||||
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
if (args.length == 2 && args[0] != null && args[0] instanceof Number
|
||||
&& args[1] != null && args[1] instanceof Number) {
|
||||
return GreatestCommonDenominator.GCD(((Number) args[0]).doubleValue(), ((Number) args[1]).doubleValue());
|
||||
}
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects two numbers");
|
||||
}
|
||||
|
||||
public static double GCD(double a, double b){
|
||||
return b == 0 ? a : GCD(b, a % b);
|
||||
}
|
||||
|
||||
public void write(JSONWriter writer, Properties options)
|
||||
throws JSONException {
|
||||
|
||||
writer.object();
|
||||
writer.key("description"); writer.value("Returns the greatest common denominator of the two numbers");
|
||||
writer.key("params"); writer.value("number d, number e");
|
||||
writer.key("returns"); writer.value("number");
|
||||
writer.endObject();
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
|
||||
Copyright 2010, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
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
|
||||
OWNER 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 com.google.refine.expr.functions.math;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
import com.google.refine.expr.EvalError;
|
||||
import com.google.refine.grel.ControlFunctionRegistry;
|
||||
import com.google.refine.grel.Function;
|
||||
|
||||
public class LeastCommonMultiple implements Function {
|
||||
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
if (args.length == 2
|
||||
&& args[0] != null && args[0] instanceof Number
|
||||
&& args[1] != null && args[1] instanceof Number) {
|
||||
return LeastCommonMultiple.LCM(((Number) args[0]).doubleValue(), ((Number) args[1]).doubleValue());
|
||||
}
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects two numbers");
|
||||
}
|
||||
|
||||
public static double LCM(double a, double b){
|
||||
double largerValue = a;
|
||||
double smallerValue = b;
|
||||
if(b > a){
|
||||
largerValue = b;
|
||||
smallerValue = a;
|
||||
}
|
||||
for(int i = 1; i <= largerValue; i++){
|
||||
if((largerValue*i) % smallerValue == 0)
|
||||
return largerValue * i;
|
||||
}
|
||||
return largerValue * smallerValue;
|
||||
}
|
||||
|
||||
public void write(JSONWriter writer, Properties options)
|
||||
throws JSONException {
|
||||
|
||||
writer.object();
|
||||
writer.key("description"); writer.value("Returns the greatest common denominator of the two numbers");
|
||||
writer.key("params"); writer.value("number d, number e");
|
||||
writer.key("returns"); writer.value("number");
|
||||
writer.endObject();
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
|
||||
Copyright 2010, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
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
|
||||
OWNER 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 com.google.refine.expr.functions.math;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
import com.google.refine.expr.EvalError;
|
||||
import com.google.refine.grel.ControlFunctionRegistry;
|
||||
import com.google.refine.grel.Function;
|
||||
|
||||
public class Multinomial implements Function {
|
||||
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
if (args.length < 1)
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects one or more numbers");
|
||||
int sum = 0;
|
||||
int product = 1;
|
||||
for(int i = 0; i < args.length; i++){
|
||||
if(args[i] == null && !(args[i] instanceof Number))
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects parameter " + (i + 1) + " to be a number");
|
||||
int num = ((Number) args[i]).intValue();
|
||||
sum += num;
|
||||
product *= FactN.factorial(num, 1);
|
||||
}
|
||||
return FactN.factorial(sum, 1) / product;
|
||||
}
|
||||
|
||||
public void write(JSONWriter writer, Properties options)
|
||||
throws JSONException {
|
||||
|
||||
writer.object();
|
||||
writer.key("description"); writer.value("Calculates the multinomial of a series of numbers");
|
||||
writer.key("params"); writer.value("one or more numbers");
|
||||
writer.key("returns"); writer.value("number");
|
||||
writer.endObject();
|
||||
}
|
||||
}
|
64
main/src/com/google/refine/expr/functions/math/Quotient.java
Normal file
64
main/src/com/google/refine/expr/functions/math/Quotient.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
|
||||
Copyright 2010, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
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
|
||||
OWNER 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 com.google.refine.expr.functions.math;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
import com.google.refine.expr.EvalError;
|
||||
import com.google.refine.grel.ControlFunctionRegistry;
|
||||
import com.google.refine.grel.Function;
|
||||
|
||||
public class Quotient implements Function {
|
||||
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
if (args.length == 2 && args[0] != null && args[0] instanceof Number
|
||||
&& args[1] != null && args[1] instanceof Number) {
|
||||
return Math.floor((((Number) args[0]).doubleValue() / ((Number) args[1]).doubleValue()));
|
||||
}
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects two numbers");
|
||||
}
|
||||
|
||||
public void write(JSONWriter writer, Properties options)
|
||||
throws JSONException {
|
||||
|
||||
writer.object();
|
||||
writer.key("description"); writer.value("Returns the integer portion of a division");
|
||||
writer.key("params"); writer.value("number numerator, number denominator");
|
||||
writer.key("returns"); writer.value("number");
|
||||
writer.endObject();
|
||||
}
|
||||
}
|
@ -72,14 +72,19 @@ import com.google.refine.expr.functions.math.Degrees;
|
||||
import com.google.refine.expr.functions.math.Even;
|
||||
import com.google.refine.expr.functions.math.Exp;
|
||||
import com.google.refine.expr.functions.math.Fact;
|
||||
import com.google.refine.expr.functions.math.FactN;
|
||||
import com.google.refine.expr.functions.math.Floor;
|
||||
import com.google.refine.expr.functions.math.GreatestCommonDenominator;
|
||||
import com.google.refine.expr.functions.math.LeastCommonMultiple;
|
||||
import com.google.refine.expr.functions.math.Ln;
|
||||
import com.google.refine.expr.functions.math.Log;
|
||||
import com.google.refine.expr.functions.math.Max;
|
||||
import com.google.refine.expr.functions.math.Min;
|
||||
import com.google.refine.expr.functions.math.Mod;
|
||||
import com.google.refine.expr.functions.math.Multinomial;
|
||||
import com.google.refine.expr.functions.math.Odd;
|
||||
import com.google.refine.expr.functions.math.Pow;
|
||||
import com.google.refine.expr.functions.math.Quotient;
|
||||
import com.google.refine.expr.functions.math.Radians;
|
||||
import com.google.refine.expr.functions.math.Round;
|
||||
import com.google.refine.expr.functions.math.Sin;
|
||||
@ -253,9 +258,14 @@ public class ControlFunctionRegistry {
|
||||
registerFunction("exp", new Exp());
|
||||
registerFunction("sum", new Sum());
|
||||
registerFunction("fact", new Fact());
|
||||
registerFunction("factn", new FactN());
|
||||
registerFunction("combin", new Combin());
|
||||
registerFunction("degrees", new Degrees());
|
||||
registerFunction("radians", new Radians());
|
||||
registerFunction("gcd", new GreatestCommonDenominator());
|
||||
registerFunction("lcm", new LeastCommonMultiple());
|
||||
registerFunction("multinomial", new Multinomial());
|
||||
registerFunction("quotient", new Quotient());
|
||||
|
||||
registerFunction("and", new And());
|
||||
registerFunction("or", new Or());
|
||||
|
Loading…
Reference in New Issue
Block a user