SPARQL counting triples in multiple graphs - count

I want to count triples in multiple graphs which are of a certain class and sum it up. I manage to count the triples of this class in each graph but I don't manage to calculate the total.
Initial query:
PREFIX locah: <http://data.archiveshub.ac.uk/def/>
PREFIX bs: <http://localhost:3030/alod/bs>
PREFIX ne: <http://localhost:3030/alod/ne>
SELECT (count(?sBS) as ?BScount) (count(?sNE) AS ?NEcount) WHERE {
{
GRAPH bs: {
?sBS a locah:ArchivalResource
}
} UNION {
GRAPH ne: {
?sNE a locah:ArchivalResource
}
}
}
My idea was to simply use the SUM() function as well so the SELECT would be like this:
SELECT (count(?sBS) as ?BScount) (count(?sNE) AS ?NEcount) (SUM(?NEcount ?BScount) AS ?total )WHERE {
But that doesn't seem to work.
And a related question: Why do I need the UNION? If I execute it without UNION it seems to come up with a very high triple count which doesn't make much sense and the count is twice the same.
You can try it on my SPARQL endpoint: http://data.alod.ch/sparql/

When you use an aggregate in the projection, you have to partition, or group, the solutions by distinct values of some of the variables. If you don't specify a group by clause, then the grouping is implicit. In this case, you have (at least) two options. One would be to use two subqueries, as in:
select ?acount ?bcount (?acount + ?bcount as ?totalCount) where {
{ select (count(*) as ?acount) where {
graph :a { ... } }
{ select (count(*) as ?bcount) where {
graph :b { ... } }
}
I think that's probably the simplest and most self-explanatory option. The other option, as you've noted, is to use a union:
select (count(?a) as ?acount)
(count(?b) as ?bcount)
(?acount + ?bcount as ?totalCount)
where {
{ graph :a { ?a ... } }
union
{ graph :b { ?b ... } }
}
The reason that something like
select (count(?a) as ?acount)
(count(?b) as ?bcount)
(?acount + ?bcount as ?totalCount)
where {
graph :a { ?a ... }
graph :b { ?b ... }
}
doesn't work is that you end up with the Cartesian product of ?a and ?b values. That is, suppose that there are two values for ?a and three values for ?b. Then you end up with six rows in the table:
a1, b1
a1, b2
a1, b3
a2, b1
a2, b2
a2, b3
Each of these rows is unique, so if you use the implicit group by, you'll have six a's and six b's, which isn't really what you want. You could still do this however, using distinct:
select (count(distinct ?a) as ?acount)
(count(distinct ?b) as ?bcount)
(?acount + ?bcount as ?totalCount)
where {
#-- ...
}
Types of Queries
Type 1: Subqueries
SELECT ?BScount ?NEcount (?BScount + ?NEcount as ?totalCount)
WHERE {
{ select (count(*) as ?BScount) WHERE {
GRAPH bs: { ?sBS a locah:ArchivalResource }
} }
{ select (count(*) as ?NEcount) WHERE {
GRAPH ne: { ?sNE a locah:ArchivalResource }
} }
}
Type 2: Union
SELECT (count(?sBS) as ?BScount)
(count(?sNE) AS ?NEcount)
(?BScount + ?NEcount as ?totalCount)
WHERE {
{ GRAPH bs: { ?sBS a locah:ArchivalResource } }
UNION
{ GRAPH ne: { ?sNE a locah:ArchivalResource } }
}
Type 3: Cartesian Product and Distinct
SELECT (count(distinct ?sBS) as ?BScount)
(count(distinct ?sNE) AS ?NEcount)
(?BScount + ?NEcount as ?totalCount)
WHERE {
{ GRAPH bs: { ?sBS a locah:ArchivalResource } }
{ GRAPH ne: { ?sNE a locah:ArchivalResource } }
}

Related

Recursion func w/o recursion

function findNum(a, b) {
if (!b) {
b = 0;
}
if (a < 2) {
throw new Error('wrong');
}
if (a === 2) {
return 1 / a + b;
}
return findNum(a - 1, b + 1 / (a * (a -1)));
}
Is there any way to write this func w/o recursion and without using while in it?

Constructing a Sparse Tropical Limit Function in Chapel

Given matrices A and B the tropical product is defined to be the usual matrix product with multiplication traded out for addition and addition traded out for minimum. That is, it returns a new matrix C such that,
C_ij = minimum(A_ij, B_ij, A_i1 + B_1j, A_i2 + B_12,..., A_im + B_mj)
Given the underlying adjacency matrix A_g of a graph g, the nth "power" with respect to the tropical product represents the connections between nodes reachable in at most n steps. That is, C_ij = (A**n)_ij has value m if nodes i and j are separated by m<=n edges.
In general, given some graph with N nodes. The diameter of the graph can only be at most N; and, given a graph with diameter k, A**n = A**k for all n>k and the matrix D_ij = A**k is called the "distance matrix" entries representing the distances between all nodes in the graph.
I have written a tropical product function in chapel and I want to write a function that takes an adjacency matrix and returns the resulting distance matrix. I have tried the following approaches to no avail. Guidance in getting past these errors would be greatly appreciated!
proc tropicLimit(A:[] real,B:[] real) {
var R = tropic(A,B);
if A == R {
return A;
} else {
tropicLimit(R,B);
}
}
which threw a domain mismatch error so I made the following edit:
proc tropicLimit(A:[] real,B:[] real) {
var R = tropic(A,B);
if A.domain == R.domain {
if && reduce (A == R) {
return R;
} else {
tropicLimit(R,B);
}
} else {
tropicLimit(R,B);
}
}
which throws
src/MatrixOps.chpl:602: error: control reaches end of function that returns a value
proc tropicLimit(A:[] real,B:[] real) {
var R = tropic(A,B);
if A.domain == R.domain {
if && reduce (A == R) { // Line 605 is this one
} else {
tropicLimit(R,B);
}
} else {
tropicLimit(R,B);
}
return R;
}
Brings me back to this error
src/MatrixOps.chpl:605: error: halt reached - Sparse arrays can't be zippered with anything other than their domains and sibling arrays (CS layout)
I also tried using a for loop with a break condition but that didn't work either
proc tropicLimit(B:[] real) {
var R = tropic(B,B);
for n in B.domain.dim(2) {
var S = tropic(R,B);
if S.domain != R.domain {
R = S; // Intended to just reassign the handle "R" to the contents of "S" i.o.w. destructive update of R
} else {
break;
}
}
return R;
}
Any suggestions?
src/MatrixOps.chpl:605: error: halt reached - Sparse arrays can't be zippered with anything other than their domains and sibling arrays (CS layout)
I believe you are encountering a limitation of zippering sparse arrays in the current implementation, documented in #6577.
Removing some unknowns from the equation, I believe this distilled code snippet demonstrates the issue you are encountering:
use LayoutCS;
var dom = {1..10, 1..10};
var Adom: sparse subdomain(dom) dmapped CS();
var Bdom: sparse subdomain(dom) dmapped CS();
var A: [Adom] real;
var B: [Bdom] real;
Adom += (1,1);
Bdom += (1,1);
A[1,1] = 1.0;
B[1,1] = 2.0;
writeln(A.domain == B.domain); // true
var willThisWork = && reduce (A == B);
// dang.chpl:19: error: halt reached - Sparse arrays can't be zippered with
// anything other than their domains and sibling arrays (CS layout)
As a work-around, I would suggest looping over the sparse indices after confirming the domains are equal and performing a && reduce. This is something you could wrap in a helper function, e.g.
proc main() {
var dom = {1..10, 1..10};
var Adom: sparse subdomain(dom) dmapped CS();
var Bdom: sparse subdomain(dom) dmapped CS();
var A: [Adom] real;
var B: [Bdom] real;
Adom += (1,1);
Bdom += (1,1);
A[1,1] = 1.0;
B[1,1] = 2.0;
if A.domain == B.domain {
writeln(equal(A, B));
}
}
/* Some day, this should be A.equals(B) ! */
proc equal(A: [], B: []) {
// You could also return 'false' if domains do not match
assert(A.domain == B.domain);
var s = true;
forall (i,j) in A.domain with (&& reduce s) {
s &&= (A[i,j] == B[i,j]);
}
return s;
}
src/MatrixOps.chpl:602: error: control reaches end of function that returns a value
This error is a result of not returning something in every condition. I believe you intended to do:
proc tropicLimit(A:[] real,B:[] real) {
var R = tropic(A,B);
if A.domain == R.domain {
if && reduce (A == R) {
return R;
} else {
return tropicLimit(R,B);
}
} else {
return tropicLimit(R,B);
}
}

How to reverse a Map in Kotlin?

I am trying to reverse a Map in Kotlin. So far, I have come up with:
mapOf("foo" to 42)
.toList()
.map { (k, v) -> v to k }
.toMap()
Is there any better way of doing this without using a middleman(middlelist)?
Since the Map consists of Entrys and it is not Iterable you can use Map#entries instead. It will be mapped to Map#entrySet to create a backed view of Set<Entry>, for example:
val reversed = map.entries.associateBy({ it.value }) { it.key }
OR use Iterable#associate, which will create additional Pairs.
val reversed = map.entries.associate{(k,v)-> v to k}
OR using Map#forEach:
val reversed = mutableMapOf<Int, String>().also {
// v-- use `forEach` here
map.forEach { (k, v) -> it.put(v, k) }
}.toMap()
// ^--- you can add `toMap()` to create an immutable Map.
Here is a simple extension function that reverse a map - without generating unneeded garbage (like pairs, intermediate data structures and unnecessary closures )
fun <K, V> Map<K, V>.reversed() = HashMap<V, K>().also { newMap ->
entries.forEach { newMap.put(it.value, it.key) }
}
note that apply is inlined, and entries.forEach is also inlined (which is not the same for Map::forEach)
In case your map is not a 1-1 mapping and you want the inversion to be a list of values:
mapOf(1 to "AAA", 2 to "BBB", 3 to "BBB").toList()
.groupBy { pair -> pair.second } // Pair<Int, String>
.mapValues { entry ->
entry.value.map { it.first } // Entry<String, List<Pair<Int, String>>
}
If you need to reverse a multimap like m: Map<K, List<V>> to a Map<V, List<K>> you can do
m
.flatMap { it.value.map { oneValue -> oneValue to it.key } }
.groupBy({ it.first }, { it.second })
.toMap()
In sequence,
mapOf('a' to listOf('b', 'c'), 'd' to listOf('b'))
gets flat mapped to a sequence like
listOf('b' to 'a', 'c' to 'a', 'b' to 'd') which gets grouped to
listOf('b' to listOf('a', 'd'), 'c' to listOf('a')) which then gets converted to a map.
This probably creates intermediate objects.
I'm still learning the ins and outs of Kotlin, but I had the same requirement and as of Kotlin 1.2 it appears that you can iterate over a Map and so map() it directly like this:
#Test
fun testThatReverseIsInverseOfMap() {
val intMap = mapOf(1 to "one", 2 to "two", 3 to "three")
val revMap = intMap.map{(k,v) -> v to k}.toMap()
assertTrue(intMap.keys.toTypedArray() contentEquals revMap.values.toTypedArray())
assertTrue(intMap.values.toTypedArray() contentEquals revMap.keys.toTypedArray())
}
This is my take on a 1:1 map
private fun <K, V> Map<K, V>.reverseOneToOneMap(): Map<V, K> {
val result = this.entries.associateBy({ it.value }) { it.key }
if (result.size != this.size) {
throw RuntimeException("Map must be 1:1")
}
return result
}

Optimize four nested for loops

I have four nested for loops. How can I optimize this ? I implement the following code but it takes too long.
p1=0.1
q1=0.3
p2=0.2
q2=0.4
n=10
r1=2
bincoeff=function(k,S1, R2, S2) {
return ( factorial(k+S1+R2+S2)/(factorial(k)*factorial(S1)*factorial(R2)*factorial(S2)) )
}
out=0
applyFormula= function(n, r1, p1, q1, p2, q2){
if (r1 < 0) {out <- 0}
else{
for (k in 0:r1) {
nmk= n-k
for (S1 in 0:nmk) {
for (R2 in 0:nmk) {
for (S2 in 0:nmk) {
if ( S1+R2+S2 == nmk ) {
out = out+ (bincoeff(k,S1,R2,S2)*(p1^k)*(q1^S1)*(p2^R2)*(q2^S2))
}
}
}
}
}
return (out)
}
}
I have after to apply this function to each row of my big data so it takes several minutes...
All the help you can offer me is appreciated. Thank you!

Longest, consequent, ascending subsequence of an array

I am stuck doing an assignment for university. The task is to find a recursive and then dynamic programming way to calculate the length of the longest,consequent,ascending subsequence of an array. If the array for example is: {4 , -5 , -3, -2, 5, -2, 0, 3 , 2} the maximal length would be 4 with the subsequence {-5, -3, -2, 5}. I have trouble finding a recursive way and without a recursive way it's impossible to find a dynamnic way for me.
I have tried programming something but I know it's wrong and I am not sure how to fix it:
public static int length(int[] arr,int j)
{
if(arr.length == 1)
{
return 1;
}
if(j == 1)
{
if(arr[j-1] < arr[j])
{
return 1;
}
else
{
return 0;
}
}
else
{
int c = length(arr,j-1);
if(arr[j-1] < arr[j])
{
return 1 + c;
}
else
{
return 0;
}
}
}
Try this :
int length(int index, int previous)
{
if(arr.length == (index+1))
return 0;
else
if(arr[index] > previous)
return 1+length(index+1,arr[index]);
else return length(index+1,previous)
}
Maybe you don't need to give the array as argument in each recursive call by making a static variable,
Previous is the latest element of the subsequence

Resources