<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://ejml.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Example_Masked_Triangle_Count</id>
	<title>Example Masked Triangle Count - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://ejml.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Example_Masked_Triangle_Count"/>
	<link rel="alternate" type="text/html" href="https://ejml.org/wiki/index.php?title=Example_Masked_Triangle_Count&amp;action=history"/>
	<updated>2026-04-21T22:21:51Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.11</generator>
	<entry>
		<id>https://ejml.org/wiki/index.php?title=Example_Masked_Triangle_Count&amp;diff=316&amp;oldid=prev</id>
		<title>Peter: Created page with &quot;Many Graph operations can be performed using linear algebra and this connection is the subject of much recent research. EJML now has basic &quot;Graph BLAS&quot; capabilities as this ex...&quot;</title>
		<link rel="alternate" type="text/html" href="https://ejml.org/wiki/index.php?title=Example_Masked_Triangle_Count&amp;diff=316&amp;oldid=prev"/>
		<updated>2021-07-07T15:23:21Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;Many Graph operations can be performed using linear algebra and this connection is the subject of much recent research. EJML now has basic &amp;quot;Graph BLAS&amp;quot; capabilities as this ex...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Many Graph operations can be performed using linear algebra and this connection is the subject of much recent research. EJML now has basic &amp;quot;Graph BLAS&amp;quot; capabilities as this example shows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
External Resources:&lt;br /&gt;
* [https://github.com/lessthanoptimal/ejml/blob/v0.41/examples/src/org/ejml/example/ExampleMaskedTriangleCount.java ExampleMaskedTriangleCount.java]&lt;br /&gt;
&lt;br /&gt;
== Example Code ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Example using masked matrix multiplication to count the triangles in a graph.&lt;br /&gt;
 * Triangle counting is used to detect communities in graphs and often used to analyse social graphs.&lt;br /&gt;
 *&lt;br /&gt;
 * More about the connection between graphs and linear algebra can be found at:&lt;br /&gt;
 * https://github.com/GraphBLAS/GraphBLAS-Pointers.&lt;br /&gt;
 *&lt;br /&gt;
 * @author Florentin Doerre&lt;br /&gt;
 */&lt;br /&gt;
public class ExampleMaskedTriangleCount {&lt;br /&gt;
    public static void main( String[] args ) {&lt;br /&gt;
        // For the example we will be using the following graph:&lt;br /&gt;
        // (0)--(1)--(2)--(0), (2)--(3)--(4)--(2), (5)&lt;br /&gt;
        var adjacencyMatrix = new DMatrixSparseCSC(6, 6, 24);&lt;br /&gt;
        adjacencyMatrix.set(0, 1, 1);&lt;br /&gt;
        adjacencyMatrix.set(0, 2, 1);&lt;br /&gt;
        adjacencyMatrix.set(1, 2, 1);&lt;br /&gt;
        adjacencyMatrix.set(2, 3, 1);&lt;br /&gt;
        adjacencyMatrix.set(2, 4, 1);&lt;br /&gt;
        adjacencyMatrix.set(3, 4, 1);&lt;br /&gt;
&lt;br /&gt;
        // Triangle Count is defined over undirected graphs, therefore we make matrix symmetric (i.e. undirected)&lt;br /&gt;
        adjacencyMatrix.copy().createCoordinateIterator().forEachRemaining(v -&amp;gt; adjacencyMatrix.set(v.col, v.row, v.value));&lt;br /&gt;
&lt;br /&gt;
        // In a graph context mxm computes all path of length 2 (a-&amp;gt;b-&amp;gt;c).&lt;br /&gt;
        // But, for triangles we are only interested in the &amp;quot;closed&amp;quot; path which form a triangle (a-&amp;gt;b-&amp;gt;c-&amp;gt;a).&lt;br /&gt;
        // To avoid computing irrelevant paths, we can use the adjacency matrix as the mask, which assures (a-&amp;gt;c) exists.&lt;br /&gt;
        var mask = DMaskFactory.builder(adjacencyMatrix, true).build();&lt;br /&gt;
        var triangleMatrix = CommonOpsWithSemiRing_DSCC.mult(adjacencyMatrix, adjacencyMatrix, null, DSemiRings.PLUS_TIMES, mask, null, null);&lt;br /&gt;
&lt;br /&gt;
        // To compute the triangles per vertex we calculate the sum per each row.&lt;br /&gt;
        // For the correct count, we need to divide the count by 2 as each triangle was counted twice (a--b--c, and a--c--b)&lt;br /&gt;
        var trianglesPerVertex = CommonOps_DSCC.reduceRowWise(triangleMatrix, 0, Double::sum, null);&lt;br /&gt;
        CommonOps_DDRM.apply(trianglesPerVertex, v -&amp;gt; v/2);&lt;br /&gt;
&lt;br /&gt;
        System.out.println(&amp;quot;Triangles including vertex 0 &amp;quot; + trianglesPerVertex.get(0));&lt;br /&gt;
        System.out.println(&amp;quot;Triangles including vertex 2 &amp;quot; + trianglesPerVertex.get(2));&lt;br /&gt;
        System.out.println(&amp;quot;Triangles including vertex 5 &amp;quot; + trianglesPerVertex.get(5));&lt;br /&gt;
&lt;br /&gt;
        // Note: To avoid counting each triangle twice, the lower triangle over the adjacency matrix can be used TRI&amp;lt;A&amp;gt; = A * L&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Peter</name></author>
	</entry>
</feed>