You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/Semantic/Helpers/SparceVector.cs

102 lines
2.8 KiB

5 years ago
using System;
using System.Collections.Generic;
using ZeroLevel.Services.Serialization;
namespace ZeroLevel.Services.Semantic.Helpers
{
public sealed class SparceVector
: IBinarySerializable
{
private readonly static int[] EmptyIndexes = new int[0];
private readonly static double[] EmptyValues = new double[0];
private int[] indexes;
private double[] values;
private double power;
public SparceVector()
{
indexes = EmptyIndexes;
values = EmptyValues;
power = 0;
}
public SparceVector(double[] vector)
{
var l = new List<int>();
for (int i = 0; i < vector.Length; i++)
{
if (Math.Abs(vector[i]) > double.Epsilon)
{
l.Add(i);
}
}
indexes = l.ToArray();
values = new double[l.Count];
power = 0;
for (int i = 0; i < l.Count; i++)
{
values[i] = vector[indexes[i]];
power += values[i] * values[i];
}
power = Math.Sqrt(power);
}
public SparceVector(double[] vector, int[] indicies)
{
indexes = indicies;
values = vector;
power = 0;
for (int i = 0; i < indexes.Length; i++)
{
power += values[i] * values[i];
}
power = Math.Sqrt(power);
}
public double Measure(SparceVector other)
{
double sum = 0.0d;
int li = 0, ri = 0;
int lv, rv;
while (li < this.indexes.Length &&
ri < other.indexes.Length)
{
lv = this.indexes[li];
rv = other.indexes[ri];
if (lv == rv)
{
// у обоих векторов совпадение по индексам
sum += this.values[li] * other.values[ri];
li++; ri++;
}
else if (lv < rv)
{
li++;
}
else
{
ri++;
}
}
return sum / (this.power * other.power);
}
public void Serialize(IBinaryWriter writer)
{
writer.WriteDouble(this.power);
writer.WriteCollection(indexes);
writer.WriteCollection(values);
}
public void Deserialize(IBinaryReader reader)
{
this.power = reader.ReadDouble();
this.indexes = reader.ReadInt32Collection().ToArray();
this.values = reader.ReadDoubleCollection().ToArray();
}
}
}

Powered by TurnKey Linux.