Example #1
0
        /// <summary>
        /// Computes the dot product between this vector and another vector.
        /// </summary>
        /// <param name="other">
        /// The other vector to add.
        /// </param>
        /// <returns>s
        /// The result of the addition.
        /// </returns>
        protected override Complex DoDotProduct(Vector<Complex> other)
        {
            var result = Complex.Zero;

            if (ReferenceEquals(this, other))
            {
                for (var i = 0; i < NonZerosCount; i++)
                {
                    result += _nonZeroValues[i] * _nonZeroValues[i];
                }
            }
            else
            {
                for (var i = 0; i < NonZerosCount; i++)
                {
                    result += _nonZeroValues[i] * other.At(_nonZeroIndices[i]);
                }
            }

            return result;
        }
Example #2
0
 /// <summary>
 /// Pointwise multiplies this vector with another vector and stores the result into the result vector.
 /// </summary>
 /// <param name="other">The vector to pointwise multiply with this one.</param>
 /// <param name="result">The vector to store the result of the pointwise multiplication.</param>
 protected override void DoPointwiseDivide(Vector<Complex> other, Vector<Complex> result)
 {
     if (ReferenceEquals(this, other))
     {
         for (var i = 0; i < NonZerosCount; i++)
         {
             _nonZeroValues[i] /= _nonZeroValues[i];
         }
     }
     else
     {
         for (var i = 0; i < NonZerosCount; i++)
         {
             var index = _nonZeroIndices[i];
             result.At(index, _nonZeroValues[i] / other.At(index));
         }
     }
 }
Example #3
0
        /// <summary>
        /// Subtracts another vector to this vector and stores the result into the result vector.
        /// </summary>
        /// <param name="other">
        /// The vector to subtract from this one.
        /// </param>
        /// <param name="result">
        /// The vector to store the result of the subtraction.
        /// </param>
        protected override void DoSubtract(Vector<Complex> other, Vector<Complex> result)
        {
            if (ReferenceEquals(this, other))
            {
                result.Clear();
                return;
            }

            for (var index = 0; index < Count; index++)
            {
                result.At(index, At(index) - other.At(index));
            }
        }
Example #4
0
        /// <summary>
        /// Multiplies a scalar to each element of the vector and stores the result in the result vector.
        /// </summary>
        /// <param name="scalar">
        /// The scalar to multiply.
        /// </param>
        /// <param name="result">
        /// The vector to store the result of the multiplication.
        /// </param>
        protected override void DoMultiply(Complex scalar, Vector<Complex> result)
        {
            if (scalar == Complex.One)
            {
                if (!ReferenceEquals(this, result))
                {
                    CopyTo(result);
                }

                return;
            }

            if (scalar == Complex.Zero)
            {
                result.Clear();
                return;
            }

            var sparseResult = result as SparseVector;
            if (sparseResult == null)
            {
                result.Clear();
                for (var index = 0; index < NonZerosCount; index++)
                {
                    result.At(_nonZeroIndices[index], scalar * _nonZeroValues[index]);
                }
            }
            else
            {
                if (!ReferenceEquals(this, result))
                {
                    sparseResult.NonZerosCount = NonZerosCount;
                    sparseResult._nonZeroIndices = new int[NonZerosCount];
                    Buffer.BlockCopy(_nonZeroIndices, 0, sparseResult._nonZeroIndices, 0, _nonZeroIndices.Length * Constants.SizeOfInt);
                    sparseResult._nonZeroValues = new Complex[_nonZeroValues.Length];
                }
                
                Control.LinearAlgebraProvider.ScaleArray(scalar, _nonZeroValues, sparseResult._nonZeroValues);
            }
        }
Example #5
0
        /// <summary>
        /// Adds a scalar to each element of the vector and stores the result in the result vector.
        /// </summary>
        /// <param name="scalar">
        /// The scalar to add.
        /// </param>
        /// <param name="result">
        /// The vector to store the result of the addition.
        /// </param>
        protected override void DoAdd(Complex scalar, Vector<Complex> result)
        {
            if (scalar == Complex.Zero)
            {
                if (!ReferenceEquals(this, result))
                {
                    CopyTo(result);
                }

                return;
            }

            if (ReferenceEquals(this, result))
            {
                CommonParallel.For(
                    0,
                    NonZerosCount,
                    index => _nonZeroValues[index] += scalar);
            }
            else
            {
                for (var index = 0; index < Count; index++)
                {
                    result.At(index, At(index) + scalar);
                }
            }
        }
Example #6
0
 /// <summary>
 /// Adds another vector to this vector and stores the result into the result vector.
 /// </summary>
 /// <param name="other">
 /// The vector to add to this one.
 /// </param>
 /// <param name="result">
 /// The vector to store the result of the addition.
 /// </param>
 protected override void DoAdd(Vector<Complex> other, Vector<Complex> result)
 {
     if (ReferenceEquals(this, result))
     {
         CommonParallel.For(
             0,
             NonZerosCount,
             index => _nonZeroValues[index] += _nonZeroValues[index]);
     }
     else
     {
         for (var index = 0; index < Count; index++)
         {
             result.At(index, At(index) + other.At(index));
         }
     }
 }
Example #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SparseVector"/> class by
        /// copying the values from another.
        /// </summary>
        /// <param name="other">
        /// The vector to create the new vector from.
        /// </param>
        public SparseVector(Vector<Complex> other) : this(other.Count)
        {
            var vector = other as SparseVector;
            if (vector == null)
            {
                for (var i = 0; i < other.Count; i++)
                {
                    this[i] = other.At(i);
                }
            }
            else
            {
                _nonZeroValues = new Complex[vector.NonZerosCount];
                _nonZeroIndices = new int[vector.NonZerosCount];
                NonZerosCount = vector.NonZerosCount;

                // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value
                if (vector.NonZerosCount != 0)
                {
                    CommonParallel.For(0, vector.NonZerosCount, index => _nonZeroValues[index] = vector._nonZeroValues[index]);
                    Buffer.BlockCopy(vector._nonZeroIndices, 0, _nonZeroIndices, 0, vector.NonZerosCount * Constants.SizeOfInt);
                }
            }
        }
        /// <summary>
        /// Adds a scalar to each element of the vector and stores the result in the result vector.
        /// Warning, the new 'sparse vector' with a non-zero scalar added to it will be a 100% filled
        /// sparse vector and very inefficient. Would be better to work with a dense vector instead.
        /// </summary>
        /// <param name="scalar">
        /// The scalar to add.
        /// </param>
        /// <param name="result">
        /// The vector to store the result of the addition.
        /// </param>
        protected override void DoAdd(Complex scalar, Vector<Complex> result)
        {
            if (scalar == Complex.Zero)
            {
                if (!ReferenceEquals(this, result))
                {
                    CopyTo(result);
                }

                return;
            }

            if (ReferenceEquals(this, result))
            {
                //populate a new vector with the scalar
                var vnonZeroValues = new Complex[Count];
                var vnonZeroIndices = new int[Count];
                for (int index = 0; index < Count; index++)
                {
                    vnonZeroIndices[index] = index;
                    vnonZeroValues[index] = scalar;
                }

                //populate the non zero values from this
                var indices = _storage.Indices;
                var values = _storage.Values;
                for (int j = 0; j < _storage.ValueCount; j++)
                {
                    vnonZeroValues[indices[j]] = values[j] + scalar;
                }

                //assign this vectors arrary to the new arrays.
                _storage.Values = vnonZeroValues;
                _storage.Indices = vnonZeroIndices;
                _storage.ValueCount = Count;
            }
            else
            {
                for (var index = 0; index < Count; index++)
                {
                    result.At(index, At(index) + scalar);
                }
            }
        }
 /// <summary>
 /// Pointwise multiplies this vector with another vector and stores the result into the result vector.
 /// </summary>
 /// <param name="other">The vector to pointwise multiply with this one.</param>
 /// <param name="result">The vector to store the result of the pointwise multiplication.</param>
 protected override void DoPointwiseMultiply(Vector<Complex> other, Vector<Complex> result)
 {
     if (ReferenceEquals(this, other))
     {
         for (var i = 0; i < _storage.ValueCount; i++)
         {
             _storage.Values[i] *= _storage.Values[i];
         }
     }
     else
     {
         for (var i = 0; i < _storage.ValueCount; i++)
         {
             var index = _storage.Indices[i];
             result.At(index, other.At(index) * _storage.Values[i]);
         }
     }
 }
Example #10
0
        /// <summary>
        /// Subtracts another vector to this vector and stores the result into the result vector.
        /// </summary>
        /// <param name="other">
        /// The vector to subtract from this one.
        /// </param>
        /// <param name="result">
        /// The vector to store the result of the subtraction.
        /// </param>
        protected override void DoSubtract(Vector<Complex> other, Vector<Complex> result)
        {
            if (ReferenceEquals(this, other))
            {
                result.Clear();
                return;
            }

            var otherSparse = other as SparseVector;
            if (otherSparse == null)
            {
                base.DoSubtract(other, result);
                return;
            }

            var resultSparse = result as SparseVector;
            if (resultSparse == null)
            {
                base.DoSubtract(other, result);
                return;
            }

            // TODO (ruegg, 2011-10-11): Options to optimize?

            var otherStorage = otherSparse._storage;
            if (ReferenceEquals(this, resultSparse))
            {
                int i = 0, j = 0;
                while (j < otherStorage.ValueCount)
                {
                    if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
                    {
                        var otherValue = otherStorage.Values[j];
                        if (!Complex.Zero.Equals(otherValue))
                        {
                            _storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], -otherValue);
                        }
                        j++;
                    }
                    else if (_storage.Indices[i] == otherStorage.Indices[j])
                    {
                        // TODO: result can be zero, remove?
                        _storage.Values[i++] -= otherStorage.Values[j++];
                    }
                    else
                    {
                        i++;
                    }
                }
            }
            else
            {
                result.Clear();
                int i = 0, j = 0, last = -1;
                while (i < _storage.ValueCount || j < otherStorage.ValueCount)
                {
                    if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
                    {
                        var next = _storage.Indices[i];
                        if (next != last)
                        {
                            last = next;
                            result.At(next, _storage.Values[i] - otherSparse.At(next));
                        }
                        i++;
                    }
                    else
                    {
                        var next = otherStorage.Indices[j];
                        if (next != last)
                        {
                            last = next;
                            result.At(next, At(next) - otherStorage.Values[j]);
                        }
                        j++;
                    }
                }
            }
        }
Example #11
0
 /// <summary>
 /// Pointwise multiplies this vector with another vector and stores the result into the result vector.
 /// </summary>
 /// <param name="divisor">The vector to pointwise multiply with this one.</param>
 /// <param name="result">The vector to store the result of the pointwise multiplication.</param>
 protected override void DoPointwiseDivide(Vector<Complex> divisor, Vector<Complex> result)
 {
     if (ReferenceEquals(this, divisor))
     {
         for (var i = 0; i < _storage.ValueCount; i++)
         {
             _storage.Values[i] /= _storage.Values[i];
         }
     }
     else
     {
         for (var i = 0; i < _storage.ValueCount; i++)
         {
             var index = _storage.Indices[i];
             result.At(index, _storage.Values[i] / divisor.At(index));
         }
     }
 }
Example #12
0
        /// <summary>
        /// Negates vector and saves result to <paramref name="result"/>
        /// </summary>
        /// <param name="result">Target vector</param>
        protected override void DoNegate(Vector<Complex> result)
        {
            var sparseResult = result as SparseVector;
            if (sparseResult == null)
            {
                result.Clear();
                for (var index = 0; index < _storage.ValueCount; index++)
                {
                    result.At(_storage.Indices[index], -_storage.Values[index]);
                }
            }
            else
            {
                if (!ReferenceEquals(this, result))
                {
                    sparseResult._storage.ValueCount = _storage.ValueCount;
                    sparseResult._storage.Indices = new int[_storage.ValueCount];
                    Buffer.BlockCopy(_storage.Indices, 0, sparseResult._storage.Indices, 0, _storage.ValueCount * Constants.SizeOfInt);
                    sparseResult._storage.Values = new Complex[_storage.ValueCount];
                    Array.Copy(_storage.Values, sparseResult._storage.Values, _storage.ValueCount);
                }

                Control.LinearAlgebraProvider.ScaleArray(-Complex.One, sparseResult._storage.Values, sparseResult._storage.Values);
            }
        }
Example #13
0
 /// <summary>
 /// Computes the dot product between the conjugate of this vector and another vector.
 /// </summary>
 /// <param name="other">The other vector.</param>
 /// <returns>The sum of conj(a[i])*b[i] for all i.</returns>
 protected override Complex DoConjugateDotProduct(Vector<Complex> other)
 {
     var result = Complex.Zero;
     if (ReferenceEquals(this, other))
     {
         for (var i = 0; i < _storage.ValueCount; i++)
         {
             result += _storage.Values[i].Conjugate() * _storage.Values[i];
         }
     }
     else
     {
         for (var i = 0; i < _storage.ValueCount; i++)
         {
             result += _storage.Values[i].Conjugate() * other.At(_storage.Indices[i]);
         }
     }
     return result;
 }
        /// <summary>
        /// Multiplies the conjugate transpose of this matrix with a vector and places the results into the result vector.
        /// </summary>
        /// <param name="rightSide">The vector to multiply with.</param>
        /// <param name="result">The result of the multiplication.</param>
        protected override void DoConjugateTransposeThisAndMultiply(Vector<Complex> rightSide, Vector<Complex> result)
        {
            var d = Math.Min(ColumnCount, RowCount);
            if (d < ColumnCount)
            {
                result.ClearSubVector(RowCount, ColumnCount - RowCount);
            }

            if (d == RowCount)
            {
                var denseOther = rightSide.Storage as DenseVectorStorage<Complex>;
                var denseResult = result.Storage as DenseVectorStorage<Complex>;
                if (denseOther != null && denseResult != null)
                {
                    // TODO: merge/MulByConj
                    Control.LinearAlgebraProvider.ConjugateArray(_data, denseResult.Data);
                    Control.LinearAlgebraProvider.PointWiseMultiplyArrays(denseResult.Data, denseOther.Data, denseResult.Data);
                    return;
                }
            }

            for (var i = 0; i < d; i++)
            {
                result.At(i, _data[i].Conjugate()*rightSide.At(i));
            }
        }
Example #15
0
        /// <summary>
        /// Copies the values of this vector into the target vector.
        /// </summary>
        /// <param name="target">
        /// The vector to copy elements into.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="target"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// If <paramref name="target"/> is not the same size as this vector.
        /// </exception>
        public override void CopyTo(Vector<Complex> target)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }

            if (Count != target.Count)
            {
                throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target");
            }

            if (ReferenceEquals(this, target))
            {
                return;
            }

            var otherVector = target as SparseVector;
            if (otherVector == null)
            {
                target.Clear();

                for (var index = 0; index < NonZerosCount; index++)
                {
                    target.At(_nonZeroIndices[index], _nonZeroValues[index]);
                }
            }
            else
            {
                // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value
                otherVector._nonZeroValues = new Complex[NonZerosCount];
                otherVector._nonZeroIndices = new int[NonZerosCount];
                otherVector.NonZerosCount = NonZerosCount;

                if (NonZerosCount != 0)
                {
                    CommonParallel.For(0, NonZerosCount, index => otherVector._nonZeroValues[index] = _nonZeroValues[index]);
                    Buffer.BlockCopy(_nonZeroIndices, 0, otherVector._nonZeroIndices, 0, NonZerosCount * Constants.SizeOfInt);
                }
            }
        }
        /// <summary>
        /// Multiplies this matrix with a vector and places the results into the result vector.
        /// </summary>
        /// <param name="rightSide">The vector to multiply with.</param>
        /// <param name="result">The result of the multiplication.</param>
        protected override void DoMultiply(Vector<Complex> rightSide, Vector<Complex> result)
        {
            var d = Math.Min(ColumnCount, RowCount);
            if (d < RowCount)
            {
                result.ClearSubVector(ColumnCount, RowCount - ColumnCount);
            }

            if (d == ColumnCount)
            {
                var denseOther = rightSide.Storage as DenseVectorStorage<Complex>;
                var denseResult = result.Storage as DenseVectorStorage<Complex>;
                if (denseOther != null && denseResult != null)
                {
                    Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther.Data, denseResult.Data);
                    return;
                }
            }

            for (var i = 0; i < d; i++)
            {
                result.At(i, _data[i]*rightSide.At(i));
            }
        }
Example #17
0
        /// <summary>
        /// Subtracts another vector to this vector and stores the result into the result vector.
        /// </summary>
        /// <param name="other">
        /// The vector to subtract from this one.
        /// </param>
        /// <param name="result">
        /// The vector to store the result of the subtraction.
        /// </param>
        protected override void DoSubtract(Vector<Complex> other, Vector<Complex> result)
        {
            if (ReferenceEquals(this, other))
            {
                result.Clear();
                return;
            }

            var otherSparse = other as SparseVector;
            if (otherSparse == null)
            {
                base.DoSubtract(other, result);
                return;
            }

            var resultSparse = result as SparseVector;
            if (resultSparse == null)
            {
                base.DoSubtract(other, result);
                return;
            }

            // TODO (ruegg, 2011-10-11): Options to optimize?

            if (ReferenceEquals(this, resultSparse))
            {
                int i = 0, j = 0;
                while (i < NonZerosCount || j < otherSparse.NonZerosCount)
                {
                    if (i < NonZerosCount && j < otherSparse.NonZerosCount && _nonZeroIndices[i] == otherSparse._nonZeroIndices[j])
                    {
                        _nonZeroValues[i++] -= otherSparse._nonZeroValues[j++];
                    }
                    else if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] < otherSparse._nonZeroIndices[j])
                    {
                        i++;
                    }
                    else
                    {
                        var otherValue = otherSparse._nonZeroValues[j];
                        if (otherValue != Complex.Zero)
                        {
                            InsertAtUnchecked(i++, otherSparse._nonZeroIndices[j], -otherValue);
                        }
                        j++;
                    }
                }
            }
            else
            {
                result.Clear();
                int i = 0, j = 0, last = -1;
                while (i < NonZerosCount || j < otherSparse.NonZerosCount)
                {
                    if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] <= otherSparse._nonZeroIndices[j])
                    {
                        var next = _nonZeroIndices[i];
                        if (next != last)
                        {
                            last = next;
                            result.At(next, _nonZeroValues[i] - otherSparse.At(next));
                        }
                        i++;
                    }
                    else
                    {
                        var next = otherSparse._nonZeroIndices[j];
                        if (next != last)
                        {
                            last = next;
                            result.At(next, At(next) - otherSparse._nonZeroValues[j]);
                        }
                        j++;
                    }
                }
            }
        }