/// <summary> /// Combines vectors into their product vector. /// for example: [ v1, v2 ] => v3: {Value:v1 * v2, Index:[v1.Index, v2.Index] /// </summary> /// <param name="vectors">vectors to combine</param> /// <param name="vectorSize">the size of the passed vectors</param> /// <returns>combined vector</returns> public static IndexedVector Combine(IEnumerable <IndexedVector> vectors, int vectorSize) { var result = new IndexedVector { Index = Enumerable.Empty <int>().ToHashSet(), Value = Vector.One(vectorSize) }; foreach (var vector in vectors) { result.Value = result.Value.Multiply(vector.Value); result.Index.UnionWith(vector.Index); } return(result); }
/// <summary> /// Gets the 'characteristic' vectors for a given matrix row(IndexedVector). /// </summary> /// <param name="vector">row to get the vectors for</param> /// <returns>characteristic vectors</returns> public IList <Vector> GetCharacteristicVectorsFor(IndexedVector vector) { var contains = _characteristicVectors.TryGetValue(vector.Index, out var result); if (contains) { return(result); } var indices = vector.GetCharacteristicVectorIndices(M); var indicesWithInverse = indices //get index and the 'inverse' of the index .SelectMany(index => new[] { -index, index }) .ToList(); var combinations = indicesWithInverse //get all combinations of the indices in indices.Count means. .GetCombinations(indices.Count) //convert to hashset .Select(index => index.ToHashSet()) //skip indexes like {...,x, ..., -x, ...} .Where(index => index.All(part => !index.Contains(-part))) .ToList(); var characteristics = new List <Vector>(combinations.Count); foreach (var combination in combinations) { var characteristicVector = Vector.One(VectorSize); foreach (var index in combination) { //Get either the inverse of the vector (complement), or the vector itself bool isInverse = index < 0; var row = this[new HashSet <int> { Math.Abs(index) }].Value; var toMultiply = isInverse ? row.Complement() : row; characteristicVector = characteristicVector.Multiply(toMultiply); } characteristics.Add(characteristicVector); } _characteristicVectors.Add(vector.Index, characteristics); return(characteristics); }
/// <summary> /// Generates the matrix rows using R and M parameters. /// Stores the result in _rows; /// </summary> private void Generate() { var baseVectors = GetBaseVectors().ToList(); // if R <= 1, then there is no need to generate the products from vector combinations if (R <= 1) { Rows = baseVectors; return; } //get all possible combinations from the base vectors in collections of size 2 - R. //skip the first 'base' vector, as it's equivalent to 1, and when multiplying by it later, the resulting vector is simply itself. var combinations = baseVectors.Skip(1).GetCombinations(2, R); var indexedCombinedVectors = combinations .Select(combination => IndexedVector.Combine(combination, VectorSize)); Rows = baseVectors .Concat(indexedCombinedVectors) .ToList(); }