Changeset 15207 for trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/Distances/CosineDistance.cs
- Timestamp:
- 07/12/17 15:17:41 (7 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/Distances/CosineDistance.cs
r15206 r15207 34 34 /// </summary> 35 35 [StorableClass] 36 [Item(" InnerProductDistance", "The angluar distance as defined as a normalized distance measure dependent on the angle between two vectors.\nIt is designed for vectors with all positive coordinates")]37 public class InnerProductDistance : DistanceBase<IEnumerable<double>> {36 [Item("CosineDistance", "The angluar distance as defined as a normalized distance measure dependent on the angle between two vectors.\nIt is designed for vectors with all positive coordinates")] 37 public class CosineDistance : DistanceBase<IEnumerable<double>> { 38 38 39 #region HLConstructors 39 #region HLConstructors & Cloning 40 40 [StorableConstructor] 41 protected InnerProductDistance(bool deserializing) : base(deserializing) { }42 protected InnerProductDistance(InnerProductDistance original, Cloner cloner)41 protected CosineDistance(bool deserializing) : base(deserializing) { } 42 protected CosineDistance(CosineDistance original, Cloner cloner) 43 43 : base(original, cloner) { } 44 public InnerProductDistance() { }44 public CosineDistance() { } 45 45 public override IDeepCloneable Clone(Cloner cloner) { 46 return new InnerProductDistance(this, cloner);46 return new CosineDistance(this, cloner); 47 47 } 48 48 #endregion 49 49 50 50 #region statics 51 public static double GetDistance(IEnumerable<double> point1, IEnumerable<double> point2) { 52 var xs = point1.GetEnumerator(); 53 var ys = point2.GetEnumerator(); 54 var sum = 0.0; 55 while(xs.MoveNext() & ys.MoveNext()) { 56 if(xs.Current < 0 || ys.Current < 0) throw new ArgumentException("Inner product distance is only defined for vectors with non-negative elements"); 57 sum += xs.Current * ys.Current; 51 public static double GetDistance(IReadOnlyList<double> point1, IReadOnlyList<double> point2) { 52 if (point1.Count != point2.Count) throw new ArgumentException("Cosine distance not defined on vectors of different length"); 53 var innerprod = 0.0; 54 var length1 = 0.0; 55 var length2 = 0.0; 56 57 for (var i = 0; i < point1.Count; i++) { 58 double d1 = point1[i], d2 = point2[i]; 59 innerprod += d1 * d2; 60 length1 += d1 * d1; 61 length2 += d2 * d2; 58 62 } 59 if(xs.MoveNext() || ys.MoveNext()) throw new ArgumentException("Enumerables contain a different number of elements"); 60 return sum; 63 var l = Math.Sqrt(length1 * length2); 64 if (l.IsAlmost(0)) throw new ArgumentException("Cosine distance is not defined on vectors of length 0"); 65 return 1 - innerprod / l; 61 66 } 62 67 #endregion 63 68 public override double Get(IEnumerable<double> a, IEnumerable<double> b) { 64 return GetDistance(a , b);69 return GetDistance(a.ToArray(), b.ToArray()); 65 70 } 66 71 }
Note: See TracChangeset
for help on using the changeset viewer.