Browse Source

sparse: fixed stylecop errors

la-knuth
Marcus Cuda 17 years ago
parent
commit
9b45a251eb
  1. 375
      src/Numerics/LinearAlgebra/Double/SparseVector.cs

375
src/Numerics/LinearAlgebra/Double/SparseVector.cs

@ -3,9 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -14,10 +12,8 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -38,19 +34,28 @@ namespace MathNet.Numerics.LinearAlgebra.Double
using Properties; using Properties;
using Threading; using Threading;
/// <summary>
/// A vector with sparse storage.
/// </summary>
public class SparseVector : Vector public class SparseVector : Vector
{ {
/// <summary>
/// Lock ojbect for the indexer.
/// </summary>
private readonly object lockObject = new object();
/// <summary> /// <summary>
/// Gets the vector's internal data. The array containing the actual values; only the non-zero values are stored. /// Gets the vector's internal data. The array containing the actual values; only the non-zero values are stored.
/// </summary> /// </summary>
private double[] NonZeroValues = new double[0]; private double[] _nonZeroValues = new double[0];
/// <summary> /// <summary>
/// The indices of the non-zero entries. /// The indices of the non-zero entries.
/// </summary> /// </summary>
private int[] NonZeroIndices = new int[0]; private int[] _nonZeroIndices = new int[0];
/// <summary> /// <summary>
/// Returns the number of non zero elements in the vector. /// Gets the number of non zero elements in the vector.
/// </summary> /// </summary>
/// <value>The number of non zero elements.</value> /// <value>The number of non zero elements.</value>
public int NonZerosCount public int NonZerosCount
@ -60,6 +65,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
#region Constructors #region Constructors
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SparseVector"/> class with a given size. /// Initializes a new instance of the <see cref="SparseVector"/> class with a given size.
/// </summary> /// </summary>
@ -69,7 +75,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If <paramref name="size"/> is less than one. /// If <paramref name="size"/> is less than one.
/// </exception> /// </exception>
public SparseVector(int size) : base(size) { } public SparseVector(int size) : base(size)
{
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SparseVector"/> class with a given size /// Initializes a new instance of the <see cref="SparseVector"/> class with a given size
@ -86,22 +94,25 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </exception> /// </exception>
public SparseVector(int size, double value) : this(size) public SparseVector(int size, double value) : this(size)
{ {
if (value == 0.0) //Skip adding values if (value == 0.0)
{
// Skip adding values
return; return;
}
// We already know that this vector is "full", let's allocate all needed memory // We already know that this vector is "full", let's allocate all needed memory
NonZeroValues = new double[size]; this._nonZeroValues = new double[size];
NonZeroIndices = new int[size]; this._nonZeroIndices = new int[size];
NonZerosCount = size; this.NonZerosCount = size;
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => index =>
{ {
NonZeroValues[index] = value; this._nonZeroValues[index] = value;
NonZeroIndices[index] = index; this._nonZeroIndices[index] = index;
}); });
} }
/// <summary> /// <summary>
@ -116,18 +127,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var vector = other as SparseVector; var vector = other as SparseVector;
if (vector == null) if (vector == null)
{ {
for (int i = 0; i < other.Count; i++ ) for (var i = 0; i < other.Count; i++)
this[i] = other[i]; {
this[i] = other[i];
}
} }
else else
{ {
NonZeroValues = new double[vector.NonZerosCount]; this._nonZeroValues = new double[vector.NonZerosCount];
NonZeroIndices = new int[vector.NonZerosCount]; this._nonZeroIndices = new int[vector.NonZerosCount];
NonZerosCount = vector.NonZerosCount; this.NonZerosCount = vector.NonZerosCount;
// Lets copy only needed data. Portion of needed data is determined by NonZerosCount value // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value
Buffer.BlockCopy(vector.NonZeroValues, 0, this.NonZeroValues, 0, vector.NonZerosCount * Constants.SizeOfDouble); Buffer.BlockCopy(vector._nonZeroValues, 0, this._nonZeroValues, 0, vector.NonZerosCount * Constants.SizeOfDouble);
Buffer.BlockCopy(vector.NonZeroIndices, 0, this.NonZeroIndices, 0, vector.NonZerosCount * Constants.SizeOfInt); Buffer.BlockCopy(vector._nonZeroIndices, 0, this._nonZeroIndices, 0, vector.NonZerosCount * Constants.SizeOfInt);
} }
} }
@ -141,12 +154,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public SparseVector(SparseVector other) : this(other.Count) public SparseVector(SparseVector other) : this(other.Count)
{ {
// Lets copy only needed data. Portion of needed data is determined by NonZerosCount value // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value
NonZeroValues = new double[other.NonZerosCount]; this._nonZeroValues = new double[other.NonZerosCount];
NonZeroIndices = new int[other.NonZerosCount]; this._nonZeroIndices = new int[other.NonZerosCount];
NonZerosCount = other.NonZerosCount; this.NonZerosCount = other.NonZerosCount;
Buffer.BlockCopy(other.NonZeroValues, 0, this.NonZeroValues, 0, other.NonZerosCount * Constants.SizeOfDouble); Buffer.BlockCopy(other._nonZeroValues, 0, this._nonZeroValues, 0, other.NonZerosCount * Constants.SizeOfDouble);
Buffer.BlockCopy(other.NonZeroIndices, 0, this.NonZeroIndices, 0, other.NonZerosCount * Constants.SizeOfInt); Buffer.BlockCopy(other._nonZeroIndices, 0, this._nonZeroIndices, 0, other.NonZerosCount * Constants.SizeOfInt);
} }
/// <summary> /// <summary>
@ -156,9 +169,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <remarks>The vector copy the array. Any changes to the vector will NOT change the array.</remarks> /// <remarks>The vector copy the array. Any changes to the vector will NOT change the array.</remarks>
public SparseVector(double[] array) : this(array.Length) public SparseVector(double[] array) : this(array.Length)
{ {
for (int i = 0; i < array.Length; i++ ) for (var i = 0; i < array.Length; i++)
this[i] = array[i]; {
this[i] = array[i];
}
} }
#endregion #endregion
/// <summary> /// <summary>
@ -168,12 +184,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override Matrix ToColumnMatrix() public override Matrix ToColumnMatrix()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
//var matrix = new SparseMatrix(this.Count, 1);
//CommonParallel.For( // var matrix = new SparseMatrix(this.Count, 1);
// 0, // CommonParallel.For(
// this.Count, // 0,
// index => matrix[i, 0] = vector[index]); // this.Count,
//return matrix; // index => matrix[i, 0] = vector[index]);
// return matrix;
} }
/// <summary> /// <summary>
@ -183,15 +200,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override Matrix ToRowMatrix() public override Matrix ToRowMatrix()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
//var matrix = new SparseMatrix(1, this.Count);
//CommonParallel.For( // var matrix = new SparseMatrix(1, this.Count);
// 0, // CommonParallel.For(
// this.Count, // 0,
// index => matrix[0, i] = vector[index]); // this.Count,
//return matrix; // index => matrix[0, i] = vector[index]);
// return matrix;
} }
private readonly object lockObject = new object();
/// <summary>Gets or sets the value at the given <paramref name="index"/>.</summary> /// <summary>Gets or sets the value at the given <paramref name="index"/>.</summary>
/// <param name="index">The index of the value to get or set.</param> /// <param name="index">The index of the value to get or set.</param>
/// <returns>The value of the vector at the given <paramref name="index"/>.</returns> /// <returns>The value of the vector at the given <paramref name="index"/>.</returns>
@ -202,31 +219,35 @@ namespace MathNet.Numerics.LinearAlgebra.Double
get get
{ {
// If index is out of bounds // If index is out of bounds
if ((index < 0) || (index >= Count)) if ((index < 0) || (index >= this.Count))
{ {
throw new IndexOutOfRangeException(); throw new IndexOutOfRangeException();
} }
lock (lockObject) lock (this.lockObject)
{ {
// Search if item idex exists in NonZeroIndices array in range "0 - real nonzero values count" // Search if item idex exists in NonZeroIndices array in range "0 - real nonzero values count"
int itemIndex = Array.BinarySearch(NonZeroIndices, 0, NonZerosCount, index); var itemIndex = Array.BinarySearch(this._nonZeroIndices, 0, this.NonZerosCount, index);
if (itemIndex >= 0) if (itemIndex >= 0)
return NonZeroValues[itemIndex]; {
return this._nonZeroValues[itemIndex];
}
} }
return 0.0; return 0.0;
} }
set set
{ {
// If index is out of bounds // If index is out of bounds
if ((index < 0) || (index >= Count)) if ((index < 0) || (index >= this.Count))
{ {
throw new IndexOutOfRangeException(); throw new IndexOutOfRangeException();
} }
lock (lockObject) lock (this.lockObject)
{ {
SetValue(index, value); this.SetValue(index, value);
} }
} }
} }
@ -247,7 +268,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override Matrix CreateMatrix(int rows, int columns) public override Matrix CreateMatrix(int rows, int columns)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
//return new SparseMatrix(rows, columns);
// return new SparseMatrix(rows, columns);
} }
/// <summary> /// <summary>
@ -265,9 +287,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return new SparseVector(size); return new SparseVector(size);
} }
/// <summary>
/// Clears this instance.
/// </summary>
public void Clear() public void Clear()
{ {
NonZerosCount = 0; this.NonZerosCount = 0;
} }
/// <summary> /// <summary>
@ -303,24 +328,24 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (otherVector == null) if (otherVector == null)
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
this.Count, this.Count,
index => target[index] = this[index]); index => target[index] = this[index]);
} }
else else
{ {
// Lets copy only needed data. Portion of needed data is determined by NonZerosCount value // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value
otherVector.NonZeroValues = new double[this.NonZerosCount]; otherVector._nonZeroValues = new double[this.NonZerosCount];
otherVector.NonZeroIndices = new int[this.NonZerosCount]; otherVector._nonZeroIndices = new int[this.NonZerosCount];
otherVector.NonZerosCount = this.NonZerosCount; otherVector.NonZerosCount = this.NonZerosCount;
Buffer.BlockCopy(this.NonZeroValues, 0, otherVector.NonZeroValues, 0, this.NonZerosCount * Constants.SizeOfDouble); Buffer.BlockCopy(this._nonZeroValues, 0, otherVector._nonZeroValues, 0, this.NonZerosCount * Constants.SizeOfDouble);
Buffer.BlockCopy(this.NonZeroIndices, 0, otherVector.NonZeroIndices, 0, this.NonZerosCount * Constants.SizeOfInt); Buffer.BlockCopy(this._nonZeroIndices, 0, otherVector._nonZeroIndices, 0, this.NonZerosCount * Constants.SizeOfInt);
} }
} }
#region Operators and supplementary functions #region Operators and supplementary functions
// NOTE: There are no operators as: // NOTE: There are no operators as:
// public static implicit operator SparseVector(double[] array) // public static implicit operator SparseVector(double[] array)
// and // and
@ -341,8 +366,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
return; return;
} }
for (int i = 0; i < this.Count; i++ )
for (var i = 0; i < this.Count; i++)
{
this[i] += scalar; this[i] += scalar;
}
} }
/// <summary> /// <summary>
@ -398,6 +426,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
} }
/// <summary>
/// Adds the scaled sparce vector.
/// </summary>
/// <param name="alpha">The alpha.</param>
/// <param name="other">The other.</param>
private void AddScaledSparceVector(double alpha, SparseVector other) private void AddScaledSparceVector(double alpha, SparseVector other)
{ {
if (other == null) if (other == null)
@ -424,21 +457,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// To avoid such problem lets change values in internal storage of "this" // To avoid such problem lets change values in internal storage of "this"
if (alpha == 1.0) if (alpha == 1.0)
{ {
for (int i = 0; i < this.NonZerosCount; i++) for (var i = 0; i < this.NonZerosCount; i++)
{ {
this.NonZeroValues[i] += this.NonZeroValues[i]; this._nonZeroValues[i] += this._nonZeroValues[i];
} }
} }
else if (alpha == -1.0) else if (alpha == -1.0)
{ {
Clear(); // Vector is subtracted from itself this.Clear(); // Vector is subtracted from itself
return; return;
} }
else else
{ {
for (int i = 0; i < this.NonZerosCount; i++) for (var i = 0; i < this.NonZerosCount; i++)
{ {
this.NonZeroValues[i] += alpha * this.NonZeroValues[i]; this._nonZeroValues[i] += alpha * this._nonZeroValues[i];
} }
} }
} }
@ -447,20 +480,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// "this" and "other" are different objects, so by modifying "this" the "other" object will not be changed // "this" and "other" are different objects, so by modifying "this" the "other" object will not be changed
if (alpha == 1.0) if (alpha == 1.0)
{ {
for (int i = 0; i < other.NonZerosCount; i++) for (var i = 0; i < other.NonZerosCount; i++)
{ {
this[other.NonZeroIndices[i]] += other.NonZeroValues[i]; this[other._nonZeroIndices[i]] += other._nonZeroValues[i];
} }
} }
else else
{ {
for (int i = 0; i < other.NonZerosCount; i++) for (var i = 0; i < other.NonZerosCount; i++)
{ {
this[other.NonZeroIndices[i]] += alpha * other.NonZeroValues[i]; this[other._nonZeroIndices[i]] += alpha * other._nonZeroValues[i];
} }
} }
} }
} }
/// <summary> /// <summary>
/// Adds another vector to this vector and stores the result into the result vector. /// Adds another vector to this vector and stores the result into the result vector.
/// </summary> /// </summary>
@ -546,6 +580,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
ret.Add(rightSide); ret.Add(rightSide);
return ret; return ret;
} }
/// <summary> /// <summary>
/// Subtracts a scalar from each element of the vector. /// Subtracts a scalar from each element of the vector.
/// </summary> /// </summary>
@ -556,8 +591,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
return; return;
} }
for (int i = 0; i < this.Count; i++)
for (var i = 0; i < this.Count; i++)
{
this[i] -= scalar; this[i] -= scalar;
}
} }
/// <summary> /// <summary>
@ -707,17 +745,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
var result = new SparseVector(this.Count) var result = new SparseVector(this.Count)
{ {
NonZeroValues = new double[this.NonZerosCount], _nonZeroValues = new double[this.NonZerosCount],
NonZeroIndices = new int[this.NonZerosCount], _nonZeroIndices = new int[this.NonZerosCount],
NonZerosCount = this.NonZerosCount NonZerosCount = this.NonZerosCount
}; };
Buffer.BlockCopy(this.NonZeroIndices, 0, result.NonZeroIndices, 0, this.NonZerosCount * Constants.SizeOfInt); Buffer.BlockCopy(this._nonZeroIndices, 0, result._nonZeroIndices, 0, this.NonZerosCount * Constants.SizeOfInt);
CommonParallel.For( CommonParallel.For(
0, 0,
this.NonZerosCount, this.NonZerosCount,
index => result.NonZeroValues[index] = -this.NonZeroValues[index]); index => result._nonZeroValues[index] = -this._nonZeroValues[index]);
return result; return result;
} }
@ -732,12 +770,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
return; return;
} }
if (scalar == 0) if (scalar == 0)
{ {
Clear(); // Set array empty this.Clear(); // Set array empty
return; return;
} }
Control.LinearAlgebraProvider.ScaleArray(scalar, this.NonZeroValues);
Control.LinearAlgebraProvider.ScaleArray(scalar, this._nonZeroValues);
} }
/// <summary> /// <summary>
@ -764,10 +804,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// base implementation iterates though all elements, but we need only take non-zeros // base implementation iterates though all elements, but we need only take non-zeros
for (var i = 0; i < this.NonZerosCount; i++) for (var i = 0; i < this.NonZerosCount; i++)
{ {
result += this.NonZeroValues[i] * other[this.NonZeroIndices[i]]; result += this._nonZeroValues[i] * other[this._nonZeroIndices[i]];
} }
return result; return result;
} }
/// <summary> /// <summary>
/// Multiplies a vector with a scalar. /// Multiplies a vector with a scalar.
/// </summary> /// </summary>
@ -830,7 +872,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rightSide"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rightSide");
} }
return leftSide.DotProduct(rightSide); return leftSide.DotProduct(rightSide);
} }
@ -847,6 +889,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
var ret = (SparseVector)leftSide.Clone(); var ret = (SparseVector)leftSide.Clone();
ret.Multiply(1.0 / rightSide); ret.Multiply(1.0 / rightSide);
return ret; return ret;
@ -858,14 +901,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The index of absolute minimum element.</returns> /// <returns>The index of absolute minimum element.</returns>
public override int AbsoluteMinimumIndex() public override int AbsoluteMinimumIndex()
{ {
if (this.NonZerosCount == 0) // No non-zero elements. Return 0 if (this.NonZerosCount == 0)
{
// No non-zero elements. Return 0
return 0; return 0;
}
var index = 0; var index = 0;
var min = Math.Abs(this.NonZeroValues[index]); var min = Math.Abs(this._nonZeroValues[index]);
for (var i = 1; i < this.NonZerosCount; i++) for (var i = 1; i < this.NonZerosCount; i++)
{ {
var test = Math.Abs(this.NonZeroValues[i]); var test = Math.Abs(this._nonZeroValues[i]);
if (test < min) if (test < min)
{ {
index = i; index = i;
@ -873,7 +919,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
} }
return this.NonZeroIndices[index]; return this._nonZeroIndices[index];
} }
/// <summary> /// <summary>
@ -905,8 +951,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
var result = new SparseVector(length); var result = new SparseVector(length);
for (int i = index; i < index + length; i++) for (var i = index; i < index + length; i++)
{
result[i - index] = this[i]; result[i - index] = this[i];
}
return result; return result;
} }
@ -929,9 +977,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "values"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "values");
} }
for (int i = 0; i < values.Length; i++ ) for (var i = 0; i < values.Length; i++)
{
this[i] = values[i]; this[i] = values[i];
}
} }
/// <summary> /// <summary>
/// Returns the index of the absolute maximum element. /// Returns the index of the absolute maximum element.
/// </summary> /// </summary>
@ -939,21 +990,24 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override int MaximumIndex() public override int MaximumIndex()
{ {
if (this.NonZerosCount == 0) if (this.NonZerosCount == 0)
{
return 0; return 0;
}
var index = 0; var index = 0;
var max = this.NonZeroValues[0]; var max = this._nonZeroValues[0];
for (var i = 1; i < this.NonZerosCount; i++) for (var i = 1; i < this.NonZerosCount; i++)
{ {
if (max < this.NonZeroValues[i]) if (max < this._nonZeroValues[i])
{ {
index = i; index = i;
max = this.NonZeroValues[i]; max = this._nonZeroValues[i];
} }
} }
return this.NonZeroIndices[index]; return this._nonZeroIndices[index];
} }
/// <summary> /// <summary>
/// Returns the index of the minimum element. /// Returns the index of the minimum element.
/// </summary> /// </summary>
@ -961,20 +1015,22 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override int MinimumIndex() public override int MinimumIndex()
{ {
if (this.NonZerosCount == 0) if (this.NonZerosCount == 0)
{
return 0; return 0;
}
var index = 0; var index = 0;
var min = this.NonZeroValues[0]; var min = this._nonZeroValues[0];
for (var i = 1; i < this.NonZerosCount; i++) for (var i = 1; i < this.NonZerosCount; i++)
{ {
if (min > this.NonZeroValues[i]) if (min > this._nonZeroValues[i])
{ {
index = i; index = i;
min = this.NonZeroValues[i]; min = this._nonZeroValues[i];
} }
} }
return this.NonZeroIndices[index]; return this._nonZeroIndices[index];
} }
/// <summary> /// <summary>
@ -986,7 +1042,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
double result = 0; double result = 0;
for (var i = 0; i < this.NonZerosCount; i++) for (var i = 0; i < this.NonZerosCount; i++)
{ {
result += this.NonZeroValues[i]; result += this._nonZeroValues[i];
} }
return result; return result;
@ -1001,11 +1057,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
double result = 0; double result = 0;
for (var i = 0; i < this.NonZerosCount; i++) for (var i = 0; i < this.NonZerosCount; i++)
{ {
result += Math.Abs(this.NonZeroValues[i]); result += Math.Abs(this._nonZeroValues[i]);
} }
return result; return result;
} }
/// <summary> /// <summary>
/// Pointwise multiplies this vector with another vector. /// Pointwise multiplies this vector with another vector.
/// </summary> /// </summary>
@ -1096,7 +1153,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// base implementation iterates though all elements, but we need only take non-zeros // base implementation iterates though all elements, but we need only take non-zeros
for (var i = 0; i < this.NonZerosCount; i++) for (var i = 0; i < this.NonZerosCount; i++)
{ {
this[this.NonZeroIndices[i]] /= other[this.NonZeroIndices[i]]; this[this._nonZeroIndices[i]] /= other[this._nonZeroIndices[i]];
} }
} }
@ -1165,18 +1222,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
throw new NotImplementedException(); throw new NotImplementedException();
//var matrix = new DenseMatrix(u.Count, v.Count);
//CommonParallel.For( // var matrix = new DenseMatrix(u.Count, v.Count);
// 0, // CommonParallel.For(
// u.Count, // 0,
// i => // u.Count,
// { // i =>
// for (int j = 0; j < v.Count; j++) // {
// { // for (int j = 0; j < v.Count; j++)
// matrix.At(i, j, u.Data[i] * v.Data[j]); // {
// } // matrix.At(i, j, u.Data[i] * v.Data[j]);
// }); // }
//return matrix; // });
// return matrix;
} }
/// <summary> /// <summary>
@ -1204,6 +1262,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return v; return v;
} }
/// <summary> /// <summary>
/// Generates a vector with random elements /// Generates a vector with random elements
/// </summary> /// </summary>
@ -1242,9 +1301,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
return OuterProduct(this, v); return OuterProduct(this, v);
} }
#endregion #endregion
#region Vector Norms #region Vector Norms
/// <summary> /// <summary>
/// Computes the p-Norm. /// Computes the p-Norm.
/// </summary> /// </summary>
@ -1258,9 +1319,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
var sum = CommonParallel.Aggregate( var sum = CommonParallel.Aggregate(
0, 0,
this.NonZerosCount, this.NonZerosCount,
index => Math.Pow(Math.Abs(this.NonZeroValues[index]), p)); index => Math.Pow(Math.Abs(this._nonZeroValues[index]), p));
return Math.Pow(sum, 1.0 / p); return Math.Pow(sum, 1.0 / p);
} }
@ -1271,11 +1332,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>Scalar ret = max(abs(this[i]))</returns> /// <returns>Scalar ret = max(abs(this[i]))</returns>
public override double NormInfinity() public override double NormInfinity()
{ {
return CommonParallel.Select( return CommonParallel.Select(0, this.NonZerosCount, (index, localData) => localData = Math.Max(localData, Math.Abs(this._nonZeroValues[index])), Math.Max);
0,
this.NonZerosCount,
(index, localData) => localData = Math.Max(localData, Math.Abs(this.NonZeroValues[index])), Math.Max);
} }
#endregion #endregion
#region Parse Functions #region Parse Functions
@ -1437,17 +1496,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endregion #endregion
#region Implementation
/// <summary> /// <summary>
/// Delete, Add or Update the value in NonZeroValues and NonZeroIndices /// Delete, Add or Update the value in NonZeroValues and NonZeroIndices
/// </summary> /// </summary>
/// <param name="index">Value real index in array</param> /// <param name="index">Value real index in array</param>
/// <param name="value">Value</param> /// <param name="value">The value to set.</param>
/// <remarks>This method assume that index is between 0 and Array Size</remarks> /// <remarks>This method assume that index is between 0 and Array Size</remarks>
private void SetValue(int index, double value) private void SetValue(int index, double value)
{ {
// Search if "index" already exists in range "0 - real nonzero values count" // Search if "index" already exists in range "0 - real nonzero values count"
int itemIndex = Array.BinarySearch(NonZeroIndices, 0, NonZerosCount, index); var itemIndex = Array.BinarySearch(this._nonZeroIndices, 0, this.NonZerosCount, index);
if (itemIndex >= 0) if (itemIndex >= 0)
{ {
@ -1455,97 +1513,103 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (value == 0.0) if (value == 0.0)
{ {
// Value is zero. Let's delete it from Values and Indices array // Value is zero. Let's delete it from Values and Indices array
for (int i = itemIndex + 1; i < NonZerosCount; i++) for (var i = itemIndex + 1; i < this.NonZerosCount; i++)
{ {
NonZeroValues[i - 1] = NonZeroValues[i]; this._nonZeroValues[i - 1] = this._nonZeroValues[i];
NonZeroIndices[i - 1] = NonZeroIndices[i]; this._nonZeroIndices[i - 1] = this._nonZeroIndices[i];
} }
NonZerosCount -= 1;
this.NonZerosCount -= 1;
// Check if the storage needs to be shrink. This is reasonable to do if // Check if the storage needs to be shrink. This is reasonable to do if
// there are a lot of non-zero elements and storage is two times bigger // there are a lot of non-zero elements and storage is two times bigger
if ((NonZerosCount > 1024) && (NonZerosCount < NonZeroIndices.Length / 2)) if ((this.NonZerosCount > 1024) && (this.NonZerosCount < this._nonZeroIndices.Length / 2))
{ {
Array.Resize(ref NonZeroValues, NonZerosCount); Array.Resize(ref this._nonZeroValues, this.NonZerosCount);
Array.Resize(ref NonZeroIndices, NonZerosCount); Array.Resize(ref this._nonZeroIndices, this.NonZerosCount);
} }
} }
else else
{ {
NonZeroValues[itemIndex] = value; this._nonZeroValues[itemIndex] = value;
} }
} }
else else
{ {
itemIndex = ~itemIndex; //Index where to put new value itemIndex = ~itemIndex; // Index where to put new value
// Check if the storage needs to be increased // Check if the storage needs to be increased
if ((NonZerosCount == NonZeroValues.Length) && (NonZerosCount < Count)) if ((this.NonZerosCount == this._nonZeroValues.Length) && (this.NonZerosCount < this.Count))
{ {
// Value and Indices arrays are completely full so we increase the size // Value and Indices arrays are completely full so we increase the size
int size = Math.Min(NonZeroValues.Length + GrowthSize(), Count); var size = Math.Min(this._nonZeroValues.Length + this.GrowthSize(), this.Count);
Array.Resize(ref NonZeroValues, size); Array.Resize(ref this._nonZeroValues, size);
Array.Resize(ref NonZeroIndices, size); Array.Resize(ref this._nonZeroIndices, size);
} }
// Move all values (with an position larger than index) in the value array // Move all values (with an position larger than index) in the value array
// to the next position // to the next position
// move all values (with an position larger than index) in the columIndices // move all values (with an position larger than index) in the columIndices
// array to the next position // array to the next position
for (int i = NonZerosCount - 1; i > itemIndex - 1; i--) for (var i = this.NonZerosCount - 1; i > itemIndex - 1; i--)
{ {
NonZeroValues[i + 1] = NonZeroValues[i]; this._nonZeroValues[i + 1] = this._nonZeroValues[i];
NonZeroIndices[i + 1] = NonZeroIndices[i]; this._nonZeroIndices[i + 1] = this._nonZeroIndices[i];
} }
// Add the value and the column index // Add the value and the column index
NonZeroValues[itemIndex] = value; this._nonZeroValues[itemIndex] = value;
NonZeroIndices[itemIndex] = index; this._nonZeroIndices[itemIndex] = index;
// increase the number of non-zero numbers by one // increase the number of non-zero numbers by one
NonZerosCount += 1; this.NonZerosCount += 1;
} }
} }
/// <summary> /// <summary>
/// Calculates the amount with which to grow the storage array's if they need to be /// Calculates the amount with which to grow the storage array's if they need to be
/// increased in size. /// increased in size.
/// </summary> /// </summary>
/// <returns>The amount grown.</returns>
private int GrowthSize() private int GrowthSize()
{ {
int delta; int delta;
if (NonZeroValues.Length > 1024) if (this._nonZeroValues.Length > 1024)
{ {
delta = NonZeroValues.Length / 4; delta = this._nonZeroValues.Length / 4;
} }
else else
{ {
if (NonZeroValues.Length > 256) if (this._nonZeroValues.Length > 256)
{ {
delta = 512; delta = 512;
} }
else else
{ {
delta = NonZeroValues.Length > 64 ? 128 : 32; delta = this._nonZeroValues.Length > 64 ? 128 : 32;
} }
} }
return delta; return delta;
} }
#endregion
#region System.Object override #region System.Object override
/// <summary> /// <summary>
/// Check equality. If this is regular vector, then chek by base implementation. If Sparse - use own equition /// Check equality. If this is regular vector, then chek by base implementation. If Sparse - use own equition
/// </summary> /// </summary>
/// <param name="obj">Object to compare</param> /// <param name="obj">Object to compare</param>
/// <returns></returns> /// <returns>
/// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
var sparseVector = obj as SparseVector; var sparseVector = obj as SparseVector;
if (sparseVector == null) if (sparseVector == null)
{
return base.Equals(obj); return base.Equals(obj);
}
// Accept if the argument is the same object as this. // Accept if the argument is the same object as this.
if (ReferenceEquals(this, sparseVector)) if (ReferenceEquals(this, sparseVector))
@ -1561,13 +1625,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// If all else fails, perform element wise comparison. // If all else fails, perform element wise comparison.
for (var index = 0; index < this.NonZerosCount; index++) for (var index = 0; index < this.NonZerosCount; index++)
{ {
if (!this.NonZeroValues[index].AlmostEqual(sparseVector.NonZeroValues[index]) || (this.NonZeroIndices[index] != sparseVector.NonZeroIndices[index])) if (!this._nonZeroValues[index].AlmostEqual(sparseVector._nonZeroValues[index]) || (this._nonZeroIndices[index] != sparseVector._nonZeroIndices[index]))
{ {
return false; return false;
} }
} }
return true; return true;
} }
/// <summary> /// <summary>
/// Returns a hash code for this instance. /// Returns a hash code for this instance.
/// </summary> /// </summary>
@ -1581,14 +1647,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
for (var i = 0; i < hashNum; i++) for (var i = 0; i < hashNum; i++)
{ {
#if SILVERLIGHT #if SILVERLIGHT
hash ^= Precision.DoubleToInt64Bits(this.NonZeroValues[i]); hash ^= Precision.DoubleToInt64Bits(this._nonZeroValues[i]);
#else #else
hash ^= BitConverter.DoubleToInt64Bits(this.NonZeroValues[i]); hash ^= BitConverter.DoubleToInt64Bits(this._nonZeroValues[i]);
#endif #endif
} }
return BitConverter.ToInt32(BitConverter.GetBytes(hash), 4); return BitConverter.ToInt32(BitConverter.GetBytes(hash), 4);
} }
#endregion
#endregion
} }
} }
Loading…
Cancel
Save