Browse Source

Sparse Vectors: post-refactoring cleanup

la-knuth
Christoph Ruegg 14 years ago
parent
commit
9f8a58ebcb
  1. 126
      src/Numerics/LinearAlgebra/Complex/SparseVector.cs
  2. 126
      src/Numerics/LinearAlgebra/Complex32/SparseVector.cs
  3. 125
      src/Numerics/LinearAlgebra/Double/SparseVector.cs
  4. 126
      src/Numerics/LinearAlgebra/Single/SparseVector.cs
  5. 4
      src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs

126
src/Numerics/LinearAlgebra/Complex/SparseVector.cs

@ -276,9 +276,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
//populate the non zero values from this //populate the non zero values from this
var indices = _storage.Indices;
var values = _storage.Values;
for (int j = 0; j < _storage.ValueCount; j++) for (int j = 0; j < _storage.ValueCount; j++)
{ {
vnonZeroValues[_storage.Indices[j]] = _storage.Values[j] + scalar; vnonZeroValues[indices[j]] = values[j] + scalar;
} }
//assign this vectors arrary to the new arrays. //assign this vectors arrary to the new arrays.
@ -322,27 +324,29 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
// TODO (ruegg, 2011-10-11): Options to optimize? // TODO (ruegg, 2011-10-11): Options to optimize?
var otherStorage = otherSparse._storage;
if (ReferenceEquals(this, resultSparse)) if (ReferenceEquals(this, resultSparse))
{ {
int i = 0, j = 0; int i = 0, j = 0;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (j < otherStorage.ValueCount)
{ {
if (i < _storage.ValueCount && j < otherSparse._storage.ValueCount && _storage.Indices[i] == otherSparse._storage.Indices[j]) if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
{ {
_storage.Values[i++] += otherSparse._storage.Values[j++]; var otherValue = otherStorage.Values[j];
if (!Complex.Zero.Equals(otherValue))
{
_storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], otherValue);
}
j++;
} }
else if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] < otherSparse._storage.Indices[j]) else if (_storage.Indices[i] == otherStorage.Indices[j])
{ {
i++; // TODO: result can be zero, remove?
_storage.Values[i++] += otherStorage.Values[j++];
} }
else else
{ {
var otherValue = otherSparse._storage.Values[j]; i++;
if (otherValue != Complex.Zero)
{
InsertAtUnchecked(i++, otherSparse._storage.Indices[j], otherValue);
}
j++;
} }
} }
} }
@ -350,9 +354,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{ {
result.Clear(); result.Clear();
int i = 0, j = 0, last = -1; int i = 0, j = 0, last = -1;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (i < _storage.ValueCount || j < otherStorage.ValueCount)
{ {
if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherSparse._storage.Indices[j]) if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
{ {
var next = _storage.Indices[i]; var next = _storage.Indices[i];
if (next != last) if (next != last)
@ -364,11 +368,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
else else
{ {
var next = otherSparse._storage.Indices[j]; var next = otherStorage.Indices[j];
if (next != last) if (next != last)
{ {
last = next; last = next;
result.At(next, At(next) + otherSparse._storage.Values[j]); result.At(next, At(next) + otherStorage.Values[j]);
} }
j++; j++;
} }
@ -468,27 +472,29 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
// TODO (ruegg, 2011-10-11): Options to optimize? // TODO (ruegg, 2011-10-11): Options to optimize?
var otherStorage = otherSparse._storage;
if (ReferenceEquals(this, resultSparse)) if (ReferenceEquals(this, resultSparse))
{ {
int i = 0, j = 0; int i = 0, j = 0;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (j < otherStorage.ValueCount)
{ {
if (i < _storage.ValueCount && j < otherSparse._storage.ValueCount && _storage.Indices[i] == otherSparse._storage.Indices[j]) if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
{ {
_storage.Values[i++] -= otherSparse._storage.Values[j++]; var otherValue = otherStorage.Values[j];
if (!Complex.Zero.Equals(otherValue))
{
_storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], -otherValue);
}
j++;
} }
else if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] < otherSparse._storage.Indices[j]) else if (_storage.Indices[i] == otherStorage.Indices[j])
{ {
i++; // TODO: result can be zero, remove?
_storage.Values[i++] -= otherStorage.Values[j++];
} }
else else
{ {
var otherValue = otherSparse._storage.Values[j]; i++;
if (otherValue != Complex.Zero)
{
InsertAtUnchecked(i++, otherSparse._storage.Indices[j], -otherValue);
}
j++;
} }
} }
} }
@ -496,9 +502,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{ {
result.Clear(); result.Clear();
int i = 0, j = 0, last = -1; int i = 0, j = 0, last = -1;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (i < _storage.ValueCount || j < otherStorage.ValueCount)
{ {
if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherSparse._storage.Indices[j]) if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
{ {
var next = _storage.Indices[i]; var next = _storage.Indices[i];
if (next != last) if (next != last)
@ -510,11 +516,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
else else
{ {
var next = otherSparse._storage.Indices[j]; var next = otherStorage.Indices[j];
if (next != last) if (next != last)
{ {
last = next; last = next;
result.At(next, At(next) - otherSparse._storage.Values[j]); result.At(next, At(next) - otherStorage.Values[j]);
} }
j++; j++;
} }
@ -1183,62 +1189,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
#endregion #endregion
private void InsertAtUnchecked(int itemIndex, int index, Complex value)
{
// Check if the storage needs to be increased
if ((_storage.ValueCount == _storage.Values.Length) && (_storage.ValueCount < Count))
{
// Value and Indices arrays are completely full so we increase the size
var size = Math.Min(_storage.Values.Length + GrowthSize(), Count);
Array.Resize(ref _storage.Values, size);
Array.Resize(ref _storage.Indices, size);
}
// Move all values (with a position larger than index) in the value array
// to the next position
// Move all values (with a position larger than index) in the columIndices
// array to the next position
for (var i = _storage.ValueCount - 1; i > itemIndex - 1; i--)
{
_storage.Values[i + 1] = _storage.Values[i];
_storage.Indices[i + 1] = _storage.Indices[i];
}
// Add the value and the column index
_storage.Values[itemIndex] = value;
_storage.Indices[itemIndex] = index;
// increase the number of non-zero numbers by one
_storage.ValueCount += 1;
}
/// <summary>
/// Calculates the amount with which to grow the storage array's if they need to be
/// increased in size.
/// </summary>
/// <returns>The amount grown.</returns>
private int GrowthSize()
{
int delta;
if (_storage.Values.Length > 1024)
{
delta = _storage.Values.Length / 4;
}
else
{
if (_storage.Values.Length > 256)
{
delta = 512;
}
else
{
delta = _storage.Values.Length > 64 ? 128 : 32;
}
}
return delta;
}
#region System.Object override #region System.Object override
public override string ToString(string format, IFormatProvider formatProvider) public override string ToString(string format, IFormatProvider formatProvider)
@ -1264,7 +1214,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
for (var i = 0; i < hashNum; i++) for (var i = 0; i < hashNum; i++)
{ {
#if PORTABLE #if PORTABLE
hash ^= Precision.DoubleToInt64Bits(this._storage.Values[i].GetHashCode()); hash ^= Precision.DoubleToInt64Bits(_storage.Values[i].GetHashCode());
#else #else
hash ^= BitConverter.DoubleToInt64Bits(_storage.Values[i].GetHashCode()); hash ^= BitConverter.DoubleToInt64Bits(_storage.Values[i].GetHashCode());
#endif #endif

126
src/Numerics/LinearAlgebra/Complex32/SparseVector.cs

@ -276,9 +276,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
//populate the non zero values from this //populate the non zero values from this
var indices = _storage.Indices;
var values = _storage.Values;
for (int j = 0; j < _storage.ValueCount; j++) for (int j = 0; j < _storage.ValueCount; j++)
{ {
vnonZeroValues[_storage.Indices[j]] = _storage.Values[j] + scalar; vnonZeroValues[indices[j]] = values[j] + scalar;
} }
//assign this vectors arrary to the new arrays. //assign this vectors arrary to the new arrays.
@ -322,27 +324,29 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
// TODO (ruegg, 2011-10-11): Options to optimize? // TODO (ruegg, 2011-10-11): Options to optimize?
var otherStorage = otherSparse._storage;
if (ReferenceEquals(this, resultSparse)) if (ReferenceEquals(this, resultSparse))
{ {
int i = 0, j = 0; int i = 0, j = 0;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (j < otherStorage.ValueCount)
{ {
if (i < _storage.ValueCount && j < otherSparse._storage.ValueCount && _storage.Indices[i] == otherSparse._storage.Indices[j]) if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
{ {
_storage.Values[i++] += otherSparse._storage.Values[j++]; var otherValue = otherStorage.Values[j];
if (!Complex32.Zero.Equals(otherValue))
{
_storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], otherValue);
}
j++;
} }
else if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] < otherSparse._storage.Indices[j]) else if (_storage.Indices[i] == otherStorage.Indices[j])
{ {
i++; // TODO: result can be zero, remove?
_storage.Values[i++] += otherStorage.Values[j++];
} }
else else
{ {
var otherValue = otherSparse._storage.Values[j]; i++;
if (otherValue != Complex32.Zero)
{
InsertAtUnchecked(i++, otherSparse._storage.Indices[j], otherValue);
}
j++;
} }
} }
} }
@ -350,9 +354,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{ {
result.Clear(); result.Clear();
int i = 0, j = 0, last = -1; int i = 0, j = 0, last = -1;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (i < _storage.ValueCount || j < otherStorage.ValueCount)
{ {
if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherSparse._storage.Indices[j]) if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
{ {
var next = _storage.Indices[i]; var next = _storage.Indices[i];
if (next != last) if (next != last)
@ -364,11 +368,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
else else
{ {
var next = otherSparse._storage.Indices[j]; var next = otherStorage.Indices[j];
if (next != last) if (next != last)
{ {
last = next; last = next;
result.At(next, At(next) + otherSparse._storage.Values[j]); result.At(next, At(next) + otherStorage.Values[j]);
} }
j++; j++;
} }
@ -468,27 +472,29 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
// TODO (ruegg, 2011-10-11): Options to optimize? // TODO (ruegg, 2011-10-11): Options to optimize?
var otherStorage = otherSparse._storage;
if (ReferenceEquals(this, resultSparse)) if (ReferenceEquals(this, resultSparse))
{ {
int i = 0, j = 0; int i = 0, j = 0;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (j < otherStorage.ValueCount)
{ {
if (i < _storage.ValueCount && j < otherSparse._storage.ValueCount && _storage.Indices[i] == otherSparse._storage.Indices[j]) if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
{ {
_storage.Values[i++] -= otherSparse._storage.Values[j++]; var otherValue = otherStorage.Values[j];
if (!Complex32.Zero.Equals(otherValue))
{
_storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], -otherValue);
}
j++;
} }
else if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] < otherSparse._storage.Indices[j]) else if (_storage.Indices[i] == otherStorage.Indices[j])
{ {
i++; // TODO: result can be zero, remove?
_storage.Values[i++] -= otherStorage.Values[j++];
} }
else else
{ {
var otherValue = otherSparse._storage.Values[j]; i++;
if (otherValue != Complex32.Zero)
{
InsertAtUnchecked(i++, otherSparse._storage.Indices[j], -otherValue);
}
j++;
} }
} }
} }
@ -496,9 +502,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{ {
result.Clear(); result.Clear();
int i = 0, j = 0, last = -1; int i = 0, j = 0, last = -1;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (i < _storage.ValueCount || j < otherStorage.ValueCount)
{ {
if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherSparse._storage.Indices[j]) if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
{ {
var next = _storage.Indices[i]; var next = _storage.Indices[i];
if (next != last) if (next != last)
@ -510,11 +516,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
else else
{ {
var next = otherSparse._storage.Indices[j]; var next = otherStorage.Indices[j];
if (next != last) if (next != last)
{ {
last = next; last = next;
result.At(next, At(next) - otherSparse._storage.Values[j]); result.At(next, At(next) - otherStorage.Values[j]);
} }
j++; j++;
} }
@ -1183,62 +1189,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
#endregion #endregion
private void InsertAtUnchecked(int itemIndex, int index, Complex32 value)
{
// Check if the storage needs to be increased
if ((_storage.ValueCount == _storage.Values.Length) && (_storage.ValueCount < Count))
{
// Value and Indices arrays are completely full so we increase the size
var size = Math.Min(_storage.Values.Length + GrowthSize(), Count);
Array.Resize(ref _storage.Values, size);
Array.Resize(ref _storage.Indices, size);
}
// Move all values (with a position larger than index) in the value array
// to the next position
// Move all values (with a position larger than index) in the columIndices
// array to the next position
for (var i = _storage.ValueCount - 1; i > itemIndex - 1; i--)
{
_storage.Values[i + 1] = _storage.Values[i];
_storage.Indices[i + 1] = _storage.Indices[i];
}
// Add the value and the column index
_storage.Values[itemIndex] = value;
_storage.Indices[itemIndex] = index;
// increase the number of non-zero numbers by one
_storage.ValueCount += 1;
}
/// <summary>
/// Calculates the amount with which to grow the storage array's if they need to be
/// increased in size.
/// </summary>
/// <returns>The amount grown.</returns>
private int GrowthSize()
{
int delta;
if (_storage.Values.Length > 1024)
{
delta = _storage.Values.Length / 4;
}
else
{
if (_storage.Values.Length > 256)
{
delta = 512;
}
else
{
delta = _storage.Values.Length > 64 ? 128 : 32;
}
}
return delta;
}
#region System.Object override #region System.Object override
public override string ToString(string format, IFormatProvider formatProvider) public override string ToString(string format, IFormatProvider formatProvider)
@ -1264,7 +1214,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
for (var i = 0; i < hashNum; i++) for (var i = 0; i < hashNum; i++)
{ {
#if PORTABLE #if PORTABLE
hash ^= Precision.DoubleToInt64Bits(this._storage.Values[i].GetHashCode()); hash ^= Precision.DoubleToInt64Bits(_storage.Values[i].GetHashCode());
#else #else
hash ^= BitConverter.DoubleToInt64Bits(_storage.Values[i].GetHashCode()); hash ^= BitConverter.DoubleToInt64Bits(_storage.Values[i].GetHashCode());
#endif #endif

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

@ -238,10 +238,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
vnonZeroValues[index] = scalar; vnonZeroValues[index] = scalar;
} }
//populate the non zero values from this
var indices = _storage.Indices; var indices = _storage.Indices;
var values = _storage.Values; var values = _storage.Values;
//populate the non zero values from this
for (int j = 0; j < _storage.ValueCount; j++) for (int j = 0; j < _storage.ValueCount; j++)
{ {
vnonZeroValues[indices[j]] = values[j] + scalar; vnonZeroValues[indices[j]] = values[j] + scalar;
@ -288,27 +287,29 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// TODO (ruegg, 2011-10-11): Options to optimize? // TODO (ruegg, 2011-10-11): Options to optimize?
var otherStorage = otherSparse._storage;
if (ReferenceEquals(this, resultSparse)) if (ReferenceEquals(this, resultSparse))
{ {
int i = 0, j = 0; int i = 0, j = 0;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (j < otherStorage.ValueCount)
{ {
if (i < _storage.ValueCount && j < otherSparse._storage.ValueCount && _storage.Indices[i] == otherSparse._storage.Indices[j]) if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
{ {
_storage.Values[i++] += otherSparse._storage.Values[j++]; var otherValue = otherStorage.Values[j];
if (otherValue != 0.0)
{
_storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], otherValue);
}
j++;
} }
else if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] < otherSparse._storage.Indices[j]) else if (_storage.Indices[i] == otherStorage.Indices[j])
{ {
i++; // TODO: result can be zero, remove?
_storage.Values[i++] += otherStorage.Values[j++];
} }
else else
{ {
var otherValue = otherSparse._storage.Values[j]; i++;
if (otherValue != 0.0)
{
InsertAtIndexUnchecked(i++, otherSparse._storage.Indices[j], otherValue);
}
j++;
} }
} }
} }
@ -316,9 +317,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
result.Clear(); result.Clear();
int i = 0, j = 0, last = -1; int i = 0, j = 0, last = -1;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (i < _storage.ValueCount || j < otherStorage.ValueCount)
{ {
if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherSparse._storage.Indices[j]) if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
{ {
var next = _storage.Indices[i]; var next = _storage.Indices[i];
if (next != last) if (next != last)
@ -330,11 +331,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
var next = otherSparse._storage.Indices[j]; var next = otherStorage.Indices[j];
if (next != last) if (next != last)
{ {
last = next; last = next;
result.At(next, At(next) + otherSparse._storage.Values[j]); result.At(next, At(next) + otherStorage.Values[j]);
} }
j++; j++;
} }
@ -434,27 +435,29 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// TODO (ruegg, 2011-10-11): Options to optimize? // TODO (ruegg, 2011-10-11): Options to optimize?
var otherStorage = otherSparse._storage;
if (ReferenceEquals(this, resultSparse)) if (ReferenceEquals(this, resultSparse))
{ {
int i = 0, j = 0; int i = 0, j = 0;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (j < otherStorage.ValueCount)
{ {
if (i < _storage.ValueCount && j < otherSparse._storage.ValueCount && _storage.Indices[i] == otherSparse._storage.Indices[j]) if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
{ {
_storage.Values[i++] -= otherSparse._storage.Values[j++]; var otherValue = otherStorage.Values[j];
if (otherValue != 0.0)
{
_storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], -otherValue);
}
j++;
} }
else if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] < otherSparse._storage.Indices[j]) else if (_storage.Indices[i] == otherStorage.Indices[j])
{ {
i++; // TODO: result can be zero, remove?
_storage.Values[i++] -= otherStorage.Values[j++];
} }
else else
{ {
var otherValue = otherSparse._storage.Values[j]; i++;
if (otherValue != 0.0)
{
InsertAtIndexUnchecked(i++, otherSparse._storage.Indices[j], -otherValue);
}
j++;
} }
} }
} }
@ -462,9 +465,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
result.Clear(); result.Clear();
int i = 0, j = 0, last = -1; int i = 0, j = 0, last = -1;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (i < _storage.ValueCount || j < otherStorage.ValueCount)
{ {
if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherSparse._storage.Indices[j]) if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
{ {
var next = _storage.Indices[i]; var next = _storage.Indices[i];
if (next != last) if (next != last)
@ -476,11 +479,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
var next = otherSparse._storage.Indices[j]; var next = otherStorage.Indices[j];
if (next != last) if (next != last)
{ {
last = next; last = next;
result.At(next, At(next) - otherSparse._storage.Values[j]); result.At(next, At(next) - otherStorage.Values[j]);
} }
j++; j++;
} }
@ -1238,62 +1241,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endregion #endregion
private void InsertAtIndexUnchecked(int itemIndex, int index, double value)
{
// Check if the storage needs to be increased
if ((_storage.ValueCount == _storage.Values.Length) && (_storage.ValueCount < Count))
{
// Value and Indices arrays are completely full so we increase the size
var size = Math.Min(_storage.Values.Length + GrowthSize(), Count);
Array.Resize(ref _storage.Values, size);
Array.Resize(ref _storage.Indices, size);
}
// Move all values (with a position larger than index) in the value array
// to the next position
// Move all values (with a position larger than index) in the columIndices
// array to the next position
for (var i = _storage.ValueCount - 1; i > itemIndex - 1; i--)
{
_storage.Values[i + 1] = _storage.Values[i];
_storage.Indices[i + 1] = _storage.Indices[i];
}
// Add the value and the column index
_storage.Values[itemIndex] = value;
_storage.Indices[itemIndex] = index;
// increase the number of non-zero numbers by one
_storage.ValueCount += 1;
}
/// <summary>
/// Calculates the amount with which to grow the storage array's if they need to be
/// increased in size.
/// </summary>
/// <returns>The amount grown.</returns>
private int GrowthSize()
{
int delta;
if (_storage.Values.Length > 1024)
{
delta = _storage.Values.Length / 4;
}
else
{
if (_storage.Values.Length > 256)
{
delta = 512;
}
else
{
delta = _storage.Values.Length > 64 ? 128 : 32;
}
}
return delta;
}
#region System.Object override #region System.Object override
public override string ToString(string format, IFormatProvider formatProvider) public override string ToString(string format, IFormatProvider formatProvider)
@ -1319,7 +1266,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
for (var i = 0; i < hashNum; i++) for (var i = 0; i < hashNum; i++)
{ {
#if PORTABLE #if PORTABLE
hash ^= Precision.DoubleToInt64Bits(this._storage.Values[i].GetHashCode()); hash ^= Precision.DoubleToInt64Bits(_storage.Values[i].GetHashCode());
#else #else
hash ^= BitConverter.DoubleToInt64Bits(_storage.Values[i].GetHashCode()); hash ^= BitConverter.DoubleToInt64Bits(_storage.Values[i].GetHashCode());
#endif #endif

126
src/Numerics/LinearAlgebra/Single/SparseVector.cs

@ -233,9 +233,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
//populate the non zero values from this //populate the non zero values from this
var indices = _storage.Indices;
var values = _storage.Values;
for (int j = 0; j < _storage.ValueCount; j++) for (int j = 0; j < _storage.ValueCount; j++)
{ {
vnonZeroValues[_storage.Indices[j]] = _storage.Values[j] + scalar; vnonZeroValues[indices[j]] = values[j] + scalar;
} }
//assign this vectors arrary to the new arrays. //assign this vectors arrary to the new arrays.
@ -280,27 +282,29 @@ namespace MathNet.Numerics.LinearAlgebra.Single
// TODO (ruegg, 2011-10-11): Options to optimize? // TODO (ruegg, 2011-10-11): Options to optimize?
var otherStorage = otherSparse._storage;
if (ReferenceEquals(this, resultSparse)) if (ReferenceEquals(this, resultSparse))
{ {
int i = 0, j = 0; int i = 0, j = 0;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (j < otherStorage.ValueCount)
{ {
if (i < _storage.ValueCount && j < otherSparse._storage.ValueCount && _storage.Indices[i] == otherSparse._storage.Indices[j]) if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
{ {
_storage.Values[i++] += otherSparse._storage.Values[j++]; var otherValue = otherStorage.Values[j];
if (otherValue != 0.0f)
{
_storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], otherValue);
}
j++;
} }
else if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] < otherSparse._storage.Indices[j]) else if (_storage.Indices[i] == otherStorage.Indices[j])
{ {
i++; // TODO: result can be zero, remove?
_storage.Values[i++] += otherStorage.Values[j++];
} }
else else
{ {
var otherValue = otherSparse._storage.Values[j]; i++;
if (otherValue != 0.0)
{
InsertAtUnchecked(i++, otherSparse._storage.Indices[j], otherValue);
}
j++;
} }
} }
} }
@ -308,9 +312,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{ {
result.Clear(); result.Clear();
int i = 0, j = 0, last = -1; int i = 0, j = 0, last = -1;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (i < _storage.ValueCount || j < otherStorage.ValueCount)
{ {
if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherSparse._storage.Indices[j]) if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
{ {
var next = _storage.Indices[i]; var next = _storage.Indices[i];
if (next != last) if (next != last)
@ -322,11 +326,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
else else
{ {
var next = otherSparse._storage.Indices[j]; var next = otherStorage.Indices[j];
if (next != last) if (next != last)
{ {
last = next; last = next;
result.At(next, At(next) + otherSparse._storage.Values[j]); result.At(next, At(next) + otherStorage.Values[j]);
} }
j++; j++;
} }
@ -426,27 +430,29 @@ namespace MathNet.Numerics.LinearAlgebra.Single
// TODO (ruegg, 2011-10-11): Options to optimize? // TODO (ruegg, 2011-10-11): Options to optimize?
var otherStorage = otherSparse._storage;
if (ReferenceEquals(this, resultSparse)) if (ReferenceEquals(this, resultSparse))
{ {
int i = 0, j = 0; int i = 0, j = 0;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (j < otherStorage.ValueCount)
{ {
if (i < _storage.ValueCount && j < otherSparse._storage.ValueCount && _storage.Indices[i] == otherSparse._storage.Indices[j]) if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
{ {
_storage.Values[i++] -= otherSparse._storage.Values[j++]; var otherValue = otherStorage.Values[j];
if (otherValue != 0.0f)
{
_storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], -otherValue);
}
j++;
} }
else if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] < otherSparse._storage.Indices[j]) else if (_storage.Indices[i] == otherStorage.Indices[j])
{ {
i++; // TODO: result can be zero, remove?
_storage.Values[i++] -= otherStorage.Values[j++];
} }
else else
{ {
var otherValue = otherSparse._storage.Values[j]; i++;
if (otherValue != 0.0)
{
InsertAtUnchecked(i++, otherSparse._storage.Indices[j], -otherValue);
}
j++;
} }
} }
} }
@ -454,9 +460,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{ {
result.Clear(); result.Clear();
int i = 0, j = 0, last = -1; int i = 0, j = 0, last = -1;
while (i < _storage.ValueCount || j < otherSparse._storage.ValueCount) while (i < _storage.ValueCount || j < otherStorage.ValueCount)
{ {
if (j >= otherSparse._storage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherSparse._storage.Indices[j]) if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
{ {
var next = _storage.Indices[i]; var next = _storage.Indices[i];
if (next != last) if (next != last)
@ -468,11 +474,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
else else
{ {
var next = otherSparse._storage.Indices[j]; var next = otherStorage.Indices[j];
if (next != last) if (next != last)
{ {
last = next; last = next;
result.At(next, At(next) - otherSparse._storage.Values[j]); result.At(next, At(next) - otherStorage.Values[j]);
} }
j++; j++;
} }
@ -1233,62 +1239,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
#endregion #endregion
private void InsertAtUnchecked(int itemIndex, int index, float value)
{
// Check if the storage needs to be increased
if ((_storage.ValueCount == _storage.Values.Length) && (_storage.ValueCount < Count))
{
// Value and Indices arrays are completely full so we increase the size
var size = Math.Min(_storage.Values.Length + GrowthSize(), Count);
Array.Resize(ref _storage.Values, size);
Array.Resize(ref _storage.Indices, size);
}
// Move all values (with a position larger than index) in the value array
// to the next position
// Move all values (with a position larger than index) in the columIndices
// array to the next position
for (var i = _storage.ValueCount - 1; i > itemIndex - 1; i--)
{
_storage.Values[i + 1] = _storage.Values[i];
_storage.Indices[i + 1] = _storage.Indices[i];
}
// Add the value and the column index
_storage.Values[itemIndex] = value;
_storage.Indices[itemIndex] = index;
// increase the number of non-zero numbers by one
_storage.ValueCount += 1;
}
/// <summary>
/// Calculates the amount with which to grow the storage array's if they need to be
/// increased in size.
/// </summary>
/// <returns>The amount grown.</returns>
private int GrowthSize()
{
int delta;
if (_storage.Values.Length > 1024)
{
delta = _storage.Values.Length / 4;
}
else
{
if (_storage.Values.Length > 256)
{
delta = 512;
}
else
{
delta = _storage.Values.Length > 64 ? 128 : 32;
}
}
return delta;
}
#region System.Object override #region System.Object override
public override string ToString(string format, IFormatProvider formatProvider) public override string ToString(string format, IFormatProvider formatProvider)
@ -1314,7 +1264,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
for (var i = 0; i < hashNum; i++) for (var i = 0; i < hashNum; i++)
{ {
#if PORTABLE #if PORTABLE
hash ^= Precision.DoubleToInt64Bits(this._storage.Values[i].GetHashCode()); hash ^= Precision.DoubleToInt64Bits(_storage.Values[i].GetHashCode());
#else #else
hash ^= BitConverter.DoubleToInt64Bits(_storage.Values[i].GetHashCode()); hash ^= BitConverter.DoubleToInt64Bits(_storage.Values[i].GetHashCode());
#endif #endif

4
src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs

@ -76,7 +76,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
void InsertAtIndexUnchecked(int itemIndex, int index, T value) internal void InsertAtIndexUnchecked(int itemIndex, int index, T value)
{ {
// Check if the storage needs to be increased // Check if the storage needs to be increased
if ((ValueCount == Values.Length) && (ValueCount < Length)) if ((ValueCount == Values.Length) && (ValueCount < Length))
@ -100,7 +100,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
ValueCount += 1; ValueCount += 1;
} }
void RemoveAtIndexUnchecked(int itemIndex) internal void RemoveAtIndexUnchecked(int itemIndex)
{ {
// Value is zero. Let's delete it from Values and Indices array // Value is zero. Let's delete it from Values and Indices array
Array.Copy(Values, itemIndex + 1, Values, itemIndex, ValueCount - itemIndex - 1); Array.Copy(Values, itemIndex + 1, Values, itemIndex, ValueCount - itemIndex - 1);

Loading…
Cancel
Save