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);

Reply via email to