Add Leviathan ln(), reciprocal() and rnd() functions (JENA-507) - ln() is natural logarithm - reciprocal() is reciprocal i.e. 1/arg - rnd() is similar to RAND() but optionally accepts min and max values to get a random number in a specific range
Project: http://git-wip-us.apache.org/repos/asf/jena/repo Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/4a42ee2a Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/4a42ee2a Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/4a42ee2a Branch: refs/heads/JENA-507 Commit: 4a42ee2a1edfaf8c02f51143e879d7e67f00aad9 Parents: 33a8f8d Author: Rob Vesse <[email protected]> Authored: Thu Oct 9 12:19:23 2014 +0100 Committer: Rob Vesse <[email protected]> Committed: Thu Oct 9 12:19:23 2014 +0100 ---------------------------------------------------------------------- .../sparql/function/library/leviathan/ln.java | 18 +++++++ .../function/library/leviathan/reciprocal.java | 18 +++++++ .../sparql/function/library/leviathan/rnd.java | 52 ++++++++++++++++++++ .../sparql/expr/TestLeviathanFunctions.java | 15 ++++++ 4 files changed, 103 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jena/blob/4a42ee2a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/ln.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/ln.java b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/ln.java new file mode 100644 index 0000000..5377e57 --- /dev/null +++ b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/ln.java @@ -0,0 +1,18 @@ +package com.hp.hpl.jena.sparql.function.library.leviathan; + +import com.hp.hpl.jena.sparql.expr.NodeValue; +import com.hp.hpl.jena.sparql.expr.nodevalue.XSDFuncOp; +import com.hp.hpl.jena.sparql.function.FunctionBase1; + +public class ln extends FunctionBase1 { + + @Override + public NodeValue exec(NodeValue v) { + // Don't care about the return value, will just error if the thing isn't + // a numeric + XSDFuncOp.classifyNumeric("ln", v); + + return NodeValue.makeDouble(Math.log(v.getDouble())); + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/4a42ee2a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/reciprocal.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/reciprocal.java b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/reciprocal.java new file mode 100644 index 0000000..147c422 --- /dev/null +++ b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/reciprocal.java @@ -0,0 +1,18 @@ +package com.hp.hpl.jena.sparql.function.library.leviathan; + +import com.hp.hpl.jena.sparql.expr.NodeValue; +import com.hp.hpl.jena.sparql.expr.nodevalue.XSDFuncOp; +import com.hp.hpl.jena.sparql.function.FunctionBase1; + +public class reciprocal extends FunctionBase1 { + + @Override + public NodeValue exec(NodeValue v) { + // Don't care about the return value, will just error if the thing isn't + // a numeric + XSDFuncOp.classifyNumeric("reciprocal", v); + + return NodeValue.makeDouble(1d / v.getDouble()); + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/4a42ee2a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/rnd.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/rnd.java b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/rnd.java new file mode 100644 index 0000000..c078010 --- /dev/null +++ b/jena-arq/src/main/java/com/hp/hpl/jena/sparql/function/library/leviathan/rnd.java @@ -0,0 +1,52 @@ +package com.hp.hpl.jena.sparql.function.library.leviathan; + +import java.util.List; + +import org.apache.jena.atlas.lib.RandomLib; + +import com.hp.hpl.jena.query.QueryBuildException; +import com.hp.hpl.jena.sparql.expr.ExprEvalException; +import com.hp.hpl.jena.sparql.expr.ExprList; +import com.hp.hpl.jena.sparql.expr.NodeValue; +import com.hp.hpl.jena.sparql.function.FunctionBase; +import com.hp.hpl.jena.sparql.util.Utils; + +public class rnd extends FunctionBase { + + @Override + public NodeValue exec(List<NodeValue> args) { + if (args.size() > 2) + throw new ExprEvalException("Too many arguments"); + + switch (args.size()) { + case 0: + return NodeValue.makeDouble(RandomLib.random.nextDouble()); + case 1: { + double max = args.get(0).getDouble(); + if (max <= 0d) + throw new ExprEvalException("Max must be > 0"); + return NodeValue.makeDouble(RandomLib.random.nextDouble() * max); + } + case 2: { + double min = args.get(0).getDouble(); + double max = args.get(1).getDouble(); + if (min > max) + throw new ExprEvalException("Min cannot be greater than the max"); + + double range = max - min; + double value = min + (RandomLib.random.nextDouble() * range); + return NodeValue.makeDouble(value); + } + default: + throw new ExprEvalException("Too many arguments"); + } + } + + @Override + public void checkBuild(String uri, ExprList args) { + if (args.size() > 2) + throw new QueryBuildException("Function '" + Utils.className(this) + + "' takes between 0, 1 or 2 argument(s)"); + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/4a42ee2a/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestLeviathanFunctions.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestLeviathanFunctions.java b/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestLeviathanFunctions.java index ba5c53c..f3100b7 100644 --- a/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestLeviathanFunctions.java +++ b/jena-arq/src/test/java/com/hp/hpl/jena/sparql/expr/TestLeviathanFunctions.java @@ -160,6 +160,21 @@ public class TestLeviathanFunctions extends BaseTest { public void log_06() { test("lfn:log(16, 4)", "2"); } + + @Test + public void reciprocal_01() { + test("lfn:reciprocal(1)", "1"); + } + + @Test + public void reciprocal_02() { + test("lfn:reciprocal(2)", "0.5"); + } + + @Test + public void reciprocal_03() { + test("lfn:reciprocal(lfn:reciprocal(2))", "2"); + } private static void test(String exprString, String result) { Node r = NodeFactoryExtra.parseNode(result);
