1

I have a cloud of roughly 200 points in the plane. I would like to use Mathematica to draw the barcode corresponding to the corresponding persistent homology.

There is a resource function PersistentHomology that does the trick (in theory):

https://resources.wolframcloud.com/FunctionRepository/resources/PersistentHomology/

But this seems to be working for smaller data only. The package JavaPlex

http://appliedtopology.github.io/javaplex/

seems to be linkable to Mathematica; as far as I understand, it works well with Matlab. If it manages the job, I'd like to see some example. Otherwise I would appreciate any reference to other available tools.

Preem
  • 205
  • 5
  • 1
    "But this seems to be working for smaller data only" - what happens when you try it? Errors? Long computation times? Can you share a sample dataset? – MarcoB Jul 04 '23 at 11:24
  • One can get the results for like 20 points in reasonable time. The website says the computations explode with the size of the data, and the 200 point sample seems to be going forever. My data could be just random: Table[{Random[],Random[]},{i,1,200}] – Preem Jul 04 '23 at 12:32
  • 1
    Maybe try 16 points, then 18, then 20 then 22 then 24 and do each of those several times and plot log time versus number of points, if the plot isn't roughly a straight line then try log log time versus points, and see if you can fairly confidently predict how many decades 200 points might take to finish. Google Wiki Persistent homology shows 15 recent software packages for this. Maybe one of those would be tuned for a problem of your size. – Bill Jul 04 '23 at 15:06
  • 1
    It seems that the first bottleneck in PersistentHomology is computing simpweights, the max entry of the distance matrices of each simplex. This is with 200 random points as input, and there are 1333500 simpexes! – Adam Jul 04 '23 at 16:36
  • See https://reference.wolfram.com/language/JLink/tutorial/CallingJavaFromTheWolframLanguage.html for Java call details. – Adam Jul 16 '23 at 22:11

1 Answers1

3

Here's an example of Mathematica calling javaplex. See https://reference.wolfram.com/language/JLink/tutorial/CallingJavaFromTheWolframLanguage.html for syntax and other details.

From https://github.com/appliedtopology/javaplex/releases/ I downloaded the jar to ~/Desktop/javaplex/library/javaplex.jar. Now let's follow their hello world from https://github.com/appliedtopology/javaplex/wiki/Tutorial.

loading geometry

Needs@"JLink`"
Remove[stream, intervals]
ReinstallJava[ClassPath -> AbsoluteFileName@"~/Desktop/javaplex/library/javaplex.jar"];
LoadJavaClass@"edu.stanford.math.plex4.api.Plex4"

(make triangle) stream = Plex4`createExplicitSimplexStream[]; stream@addVertex@# & /@ Range[0, 2]; stream@addElement@# & /@ {{0, 1}, {0, 2}, {1, 2}}; stream@finalizeStream[]; stream@getSize[]

intervals = Plex4`getModularSimplicialAlgorithm[3, 2]@computeIntervals@stream intervals@toString[] (* Dimension: 0 [0.0, infinity) Dimension: 1 [0.0, infinity) *)

barcode image

We can call drawBarcode from the class BarcodeVisualizer. The result is a java BufferedImage, which can be converted as per How to convert a Java BufferedImage to a Mathematica Image?.

LoadJavaClass[#,StaticsVisible->True]&/@
  {"edu.stanford.math.plex4.visualization.BarcodeVisualizer",
   "javax.imageio.ImageIO"}
importBufferedImage[bi_]:=(ImageIO`write[bi,"png",#];ImportByteArray[ByteArray@Mod[#@toByteArray[],2^8],"PNG"])&@JavaNew@"java.io.ByteArrayOutputStream"

stream = Plex4createExplicitSimplexStream[]; stream@addVertex[#, 0] & /@ Range@4; stream@addVertex[5, 1]; stream@addElement[{#, 1 + Mod[#, 4]}, 0] & /@ Range@4; stream@addElement[{3, 5}, 2]; stream@addElement[{4, 5}, 3]; stream@addElement[{3, 4, 5}, 7]; stream@finalizeStream[]; intervals = (Plex4getModularSimplicialAlgorithm[3, 2])@computeIntervals@stream;

importBufferedImage@BarcodeVisualizer`drawBarcode[ intervals@getIntervalsAtDimension@#, "barcode", 8]&/@{0,1}

dim 0 house dim 1 house

Adam
  • 3,937
  • 6
  • 22
  • Thanks! This looks good and seems to be working with larger data as well. Is there any way I could get the result as a list of intervals or something similar that would allow for further manipulations? – Preem Jul 16 '23 at 07:57
  • I'm not sure how to do that in javaplex – Adam Jul 16 '23 at 16:37
  • The hello world link in the answer gives a way of doing this in Matlab: intervals_dim0 = edu.stanford.math.plex4.homology.barcodes.BarcodeUtility.getEndpoints(intervals, 0, 0) Is there an obvious way of translating this to Mathematica? I have tried replacing dots with @ and brackets with square brackets, but I must be missing something else, as this doesn't work. – Preem Jul 16 '23 at 18:06
  • 1
    An example of calling a static method is as follows: LoadJavaClass["java.lang.System",StaticsVisible->True]; System`currentTimeMillis[]. – Adam Jul 17 '23 at 01:34