Math function for base 2 conversion

I'm using Neo4j for genealogy projects. A simple pedigree generally represents a person's position using an ahnentafel number. I can create a bitstring of 0's and 1's to create ahnentafel in base2:

MATCH (n:Person{RN:1}) match p=(n)-[:father|mother*0..99]->(x) with x.fullname + ' [' + x.RN + '] (' + left(x.BD,4) + '-' + left(x.DD,4) + ')' as Name,length(p) as gen,reduce(srt2 ='', q IN nodes(p)| srt2 + replace(replace(q.sex,'M','A'),'F','B')) AS sortOrder,'1' + reduce(srt ='', q IN nodes(p)|srt + case when q.sex='M' then '0' else '1' end ) AS Anh with Name,gen,sortOrder,'1' + right(Anh,size(Anh)-2) as Ahnen return Name,gen,sortOrder,Ahnen order by gen,sortOrder

The anentafel output looks like this for the first three generations:
Ahnen

1
10
11
100
101
110
111
1000
1001
1010
1011
1100
1101
1110
1111

But most end users don't think in base2. So I'm now postprocessing this to transform it with code into base 10. It would be nice to have a function in Neo4j (APOC?) to do this conversion. It might even be more generic and allow other conversion (e.g., base 8 or base 16). The function would need to accept a bitstring and convert it to a number in the case of base2->10.

Here's a link for ahnentafel

Goodevening,
Have you looked at APOC? I remember there are some bitwise operatorfunctions available in APOC. Maybe these can be usefull.

Yours Kindly,
Omer

I did look at APOC and didn't see anything. It has conversions in format and some nice math functions, but not base2 to base10. APOC has roman (XLIX) to arabic (49) and vice versa. It would be nice to have 1101 to 13.

Instead of string appending '1' or '0' in your cypher you could use those bitwise operators to manipulate a single integer value.

OR

If you really want to convert a string of 0's an 1's to a base 10, then you could create your own user defined function.

https://neo4j.com/docs/java-reference/4.0/extending-neo4j/procedures-and-functions/functions/

It would be something like this:

package example;

import org.neo4j.procedure.Description;
import org.neo4j.procedure.Name;
import org.neo4j.procedure.UserFunction;

/**
 * This is an example of a simple user-defined function for Neo4j to perform a baseConvert
 */
public class BaseConvert {

    @UserFunction
    @Description("example.baseConvert('1101', 2) - Convert the provided base 2 string to a base 10 integer.")
    public Integer baseConvert(
            @Name("s") String s,
            @Name(value = "radix", defaultValue = 2) Integer radix) {
        if (s == null || radix == null) {
            return null;
        }
        return Integer.parseInt(s, radix);
    }
}
1 Like

Brant,

Thank you for this function. I'm just now getting back to this problem.

I would like to have a function rather than the bitwise operator. Ahnentafel is not a simple concatentation. I have these steps in my query to get to it:

  1. the path between to individiuals
    optional match path2=(pp:Person{RN:8})-[:father|mother*..99]->(m:Person{RN:MRCA_RN})
  1. create the initial concatenated bitstring
    '1' + reduce(srt ='', q IN nodes(path2)|srt + case when q.sex='M' then '0' else '1' end ) AS Anh
  1. refine this to create the ahnentafel in base 2
    '1' + right(Anh,size(Anh)-2) as Ahnentafel

How to I actually get the function you provided incorporated into my Neo4j queries? Does this get converted to a jar file and put in the plugin directory? How to reference it in the conf file?

I'd like to be able to put something like this in my query

  1. myfunctions.ahnentalbase2to10(Ahnentafel) as Base10Ahnentafel

Many thanks!

Dave