<commit_before>/**
 * @author <NAME> - <EMAIL>
 */

package library

import scala.collection.mutable.Map
import scala.collection.mutable.Stack
import scala.collection.mutable.MutableList

import play.api.libs.json._
import play.api.libs.concurrent.Execution.Implicits._

import com.signalcollect._
import com.signalcollect.configuration.ExecutionMode

import requests.EngineComputeRequest
import engine.UndirectedGraph
import engine.Resettable
import engine.Database
import http.OutReports

object BrandesStack extends Stack[BrandesVertex]

/**
 * Module that computes the Freeman's centrality 'Closeness' for
 * a single source vertex. It uses the Single Source Shortest Path 
 * algorithm for the sum of shortest paths.
 */
object BrandesBetweenness extends UndirectedGraph  {

  def vertex (id: Any) = new BrandesVertex(id)

  def edge (target: Any) = new BrandesEdge(target)

  def computeExecute (request: EngineComputeRequest, variables: Array[String]): Unit = {
    println(":P")
    graph.execute(ExecutionConfiguration.withExecutionMode(ExecutionMode.Synchronous))
    graph.shutdown
    // Brandes calculation.
    val reportNodes: MutableList[BrandesVertex] = MutableList()
    val n = vertices.size
    while (!BrandesStack.isEmpty) {
      val w = BrandesStack.pop
      for (v <- w.predecessors) v.delta = v.delta + (v.sigma.toDouble / w.sigma) * (1 + w.delta)
      if (w.id != variables(0) && w.delta > 0) {
        // Normalization.
        //w.delta = w.delta / ((n-2)*(n-1))
        reportNodes += w
      }
    }
    report(request, reportNodes.toList) 
    reportNodes.clear
  }

  private def report (request: EngineComputeRequest, ns: List[BrandesVertex]): Unit =
    Database.query(matchStatement(ns) + " " + setStatement(ns), { (error, response) => 
      if (error)
        OutReports.Error.unreachableNeo4j(request)
    })

  private def matchStatement (ns: List[BrandesVertex]): String = 
    addMatchStatement(ns, "MATCH ")

  private def addMatchStatement (ns: List[BrandesVertex], st: String): String =
    if (ns.isEmpty) st.dropRight(1)
    else addMatchStatement(ns.tail, st+"(a"+ns.head.id+" {id:'"+ns.head.id+"'}),")

  private def setStatement (ns: List[BrandesVertex]): String =
    addSetStatement(ns, "SET ")

  private def addSetStatement (ns: List[BrandesVertex], st: String): String =
    if (ns.isEmpty) st.dropRight(1)
    else addSetStatement(ns.tail, st+"a"+ns.head.id+".betweenness = a"+ns.head.id+".betweenness + "+ns.head.delta+",")

}

class BrandesEdge(t: Any) extends OptionalSignalEdge(t) with Resettable {
  def reset (varibles: Array[String]) = {}
  def signal = {
    source.state match {
      case None => None
      case Some(distance: Int) => Some((distance + weight.toInt, source))
    }
  }
}
<commit_msg>Issue #31: Work in progress.<commit_after>/**
 * @author <NAME> - <EMAIL>
 */

package library

import scala.collection.mutable.Map
import scala.collection.mutable.Stack
import scala.collection.mutable.MutableList

import play.api.libs.json._
import play.api.libs.concurrent.Execution.Implicits._

import com.signalcollect._
import com.signalcollect.configuration.ExecutionMode

import requests.EngineComputeRequest
import engine.UndirectedGraph
import engine.Resettable
import engine.Database
import http.OutReports

object BrandesStack extends Stack[BrandesVertex]

/**
 * Module that computes the Freeman's centrality 'Closeness' for
 * a single source vertex. It uses the Single Source Shortest Path 
 * algorithm for the sum of shortest paths.
 */
object BrandesBetweenness extends UndirectedGraph  {

  def vertex (id: Any) = new BrandesVertex(id)

  def edge (target: Any) = new BrandesEdge(target)

  def computeExecute (request: EngineComputeRequest, variables: Array[String]): Unit = {
    graph.execute(ExecutionConfiguration.withExecutionMode(ExecutionMode.Synchronous))
    graph.shutdown
    // Brandes calculation.
    val reportNodes: MutableList[BrandesVertex] = MutableList()
    val n = vertices.size
    while (!BrandesStack.isEmpty) {
      val w = BrandesStack.pop
      for (v <- w.predecessors) v.delta = v.delta + (v.sigma.toDouble / w.sigma) * (1 + w.delta)
      if (w.id != variables(0) && w.delta > 0) {
        // Normalization.
        //w.delta = w.delta / ((n-2)*(n-1))
        reportNodes += w
      }
    }
    report(request, reportNodes.toList) 
    reportNodes.clear
  }

  private def report (request: EngineComputeRequest, ns: List[BrandesVertex]): Unit =
    Database.query(matchStatement(ns) + " " + setStatement(ns), { (error, response) => 
      if (error)
        computeFinish(request, false)
      else
        computeFinish(request, true)
    })

  private def matchStatement (ns: List[BrandesVertex]): String = 
    addMatchStatement(ns, "MATCH ")

  private def addMatchStatement (ns: List[BrandesVertex], st: String): String =
    if (ns.isEmpty) st.dropRight(1)
    else addMatchStatement(ns.tail, st+"(a"+ns.head.id+" {id:'"+ns.head.id+"'}),")

  private def setStatement (ns: List[BrandesVertex]): String =
    addSetStatement(ns, "SET ")

  private def addSetStatement (ns: List[BrandesVertex], st: String): String =
    if (ns.isEmpty) st.dropRight(1)
    else addSetStatement(ns.tail, st+"a"+ns.head.id+".betweenness = a"+ns.head.id+".betweenness + "+ns.head.delta+",")

}

class BrandesEdge(t: Any) extends OptionalSignalEdge(t) with Resettable {
  def reset (varibles: Array[String]) = {}
  def signal = {
    source.state match {
      case None => None
      case Some(distance: Int) => Some((distance + weight.toInt, source))
    }
  }
}

{'fraction_non_alphanumeric': 0.1271551724137931, 'fraction_numerical': 0.00305316091954023, 'mean_word_length': 3.805004314063848, 'pattern_counts': {'":': 1, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4211105', 'n_tokens_mistral': 1776, 'n_tokens_neox': 1708, 'n_words': 425}