# A Distributed Execution Pipeline for Clustering Trajectories Based on a Fuzzy Similarity Relation
## 4 Materials and Methods
### The Project's Class Diagrams
```
begin Function_def apply(RDD[Similarity])(alpha:Double, t_norm:String, alg:String):SiMatrix= (t_norm,alg) match { case (\"max-delta\", \"smart\")=> new SiMatrix(flatten(similarities))(alpha) with HandleWithFilter with MaxDeltaNorm with Smart case (\"max-min\", \"smart\")=> new SiMatrix(flatten(similarities))(alpha) with HandleWithoutFilter with MaxProductNorm with Smart }
```  
**Algorithm 2**The _SiMatrix_ companion object _apply_ method. The _apply_ method of the _SiMatrix_ object leverages the _flatten_ function to create a reverse duplicate of the entries and return an iterator of the couple which will be flattened by Spark's _flatMap_ operation. Now, for computing the closure, we specified two traits _Seminaire_ and _Smart_ related respectively to the semi-naive and smart algorithm. The difference between the two is that at each iteration the first considers the initial relation when computing the composition, while the second considers the same relation related to the current iteration. This led us to define a curried function for each trait with default parameters. In the _Seminaire_ trait Algorithm 3, we specify that Rx equals the predefined Rx in the _AbstractMatrix_, which gets overridden in the _SiMatrix_ class. The last function in the closure curried form computes the composition of the past specified parameters Ri and Rx. This reflects the high potential of Scala's higher order function into simplifying highly complex computations. At the heart of the _closure_ function, we check if the current Rj equals the past iteration Ri. If the preposition holds, we return Ri; otherwise, we call the closure again in a recursive manner with Ri as Rj and the other parameters as default ones. As for the _Smart_ trait Algorithm 4; we change Rx into a KeyEntry  
Figure 2: The implementation of the _AbstractMatrix_ class. value returned by calling the _reverse_ function on the first parameter Ri. Note that to compute the transitive closure, we consider the type _KeyEntry_ which reflects the _RDD[(Long,(Long, double))]_ type. The first relation gets its columns extracted and joined with the rows of the second relation which are extracted by the _ireverse_ function. The composition is overridden in the _SiMatrix_ class (please see the Algorithm 5). In particular, the composition calls the handle function which in the same manner calls the norm function. Hence, the order of the mixins is very important. ```
begin  trait SemiNaive extends AbstractMatrix {  import AbstractMatrix._ Function override abstract def closure(Ri:RDD[Similarity]) (Rx:KeyEntry=Rx) (Rj:RDD[Similarity]=composition(Ri)(Rx)) :RDD[Similarity]=  if(Rj:subtract(Ri).isEmpty()) Ri  else closure(Rj)/0 }
```  
**Algorithm 3**The _SemiNaive_ trait. ```
begin  trait Smart extends AbstractMatrix {  import AbstractMatrix._ Function override abstract def closure(Ri:RDD[Similarity]) (Rx:KeyEntry=ireverse(Ri)) (Rj:RDD[Similarity]=composition(Ri)(Rx)) :RDD[Similarity]=  if(Rj:subtract(Ri).isEmpty()) Ri  else closure(Rj)/0 }
```  
**Algorithm 4**The _Smart_ trait. ```
begin  trait Smart extends AbstractMatrix {  import AbstractMatrix._ Function override abstract def closure(Ri:RDD[Similarity]) (Rx:KeyEntry=ireverse(Ri)) (Rj:RDD[Similarity]=composition(Ri)(Rx)) :RDD[Similarity]=  if(Rj:subtract(Ri).isEmpty()) Ri  else closure(Rj)/0 }
```  
**Algorithm 5**The overridden _composition_ method in the _SiMatrix_ class. To compute the similarities of the trajectories, we defined a trait _GeoEntry_ that gets extended by the _PointEntry_ and _TrajectoryEntry_ case classes. Case classes in scala are serialized by default, their constructor parameters become accessible variables and functions like equals and hashCode are overridden. They are related to the Value Object Pattern. The _TrajectoryEntry_ class is composed by objects of the _PointEntry_ class. The similarities of the points gets computed by the _getSimilarity_ function which call the recursive function _lcs_s both defined in the _TrajectoryEntry_ class.