tag:mathnet.uservoice.com,2008-02-07:/forums/general/activityMath.NET Numerics on UserVoice2012-05-13T01:55:12-07:00tag:mathnet.uservoice.com,2008-02-07:Event/113384332012-05-13T01:55:12-07:002012-05-13T01:55:12-07:00use RealMatrix<T>, RealDenseMatrix<T> and RealDiagonalMatrix<T>, to reduce the number of Matrix classes. [updated]<p>Currently there are 17 classes to implement.
DenseMatrix, SparseMatrix and Diagonal Matrix
and for each , MAtrix,Double, Single, Complex32 , Complex
This is 16 classes
as well as a single Generic:
IF using
Matrix<T>
RealMatrix<T>, RealDenseMatrix<T> and RealDiagonalMatrix<T>
CompleMatrix<T>, ComplexDenseMatrix<T> ComplexDiagonalMatrix<T>
would reduce it to 7.</p><p>Gregor said:<br /><div class="typeset"><p>Correction:
<br />The abstract class would be Matrix<T>
<br />and the concrete classe
<br />Matrix<T> </p>
<p>RealDenseMatrix<T> , RealSparseMatrix<T>, and RealDiagonalMatrix<T>
<br />ComplexDenseMatrix<T>, ComplexSparseMatrix<T>, ComplexDiagonalMatrix<T> </p>
<p>It would also make it quickly extentable to RealDenseMatrix<int> and any other number format.
</p></div></p>Gregortag:mathnet.uservoice.com,2008-02-07:Event/113383872012-05-13T01:42:20-07:002012-05-13T01:42:20-07:00AddSubMatrix [updated]<p>For FEM analysis the AddMatrix method is very useful. In opposite to SetMatrix this method summarize elements.</p><p>Gregor said:<br /><div class="typeset"><p>
You can now get the submatrix e..g </p>
<p>mySubMatrix= myMatrix.Submatrix(2,3,2,5) // = myMAtrix(2:5,2:7)</p>
<p>and with that submatrix you can get a sum of all the columns, by mutliplication with a 1 by n vector.:
<br />e.g. to sum all elements of myMatrix</p>
<p>var v = new DenseVector(myMatrix.ColumnCount,1);
<br />var w = new DenseVector(myMatrix.RowCount, 1);</p>
<p>SumMatrix= w * myMatrix * v ; //1 by 1 matrix , which is a sum of all elements.
<br />//can do the same for the mySubMatrix</p>
<p>I hope that answers the question, not sure what else 'FEM' analysis requires..More info needed.
<br /> </p></div></p>Gregortag:mathnet.uservoice.com,2008-02-07:Event/113383692012-05-13T01:35:12-07:002012-05-13T01:35:12-07:00Add interchange/swap function to Matrix class [updated]<p>Add interchange/swap function to Matrix class which would allow swapping two rows or columns in the matrix (i.e. m.swapRows(2,3)).</p><p>Gregor said:<br /><div class="typeset"><p>You can use permuteColumns and/or matrix.PermuteRows.
<br />the method is : virtual void PermuteColumns(Permutation p)
<br />and is available for any Matrix and you can have any Permutation.
</p></div></p>Gregortag:mathnet.uservoice.com,2008-02-07:Event/113360472012-05-12T09:07:13-07:002012-05-12T09:07:13-07:00Support Array Slicing [updated]<p>Array slicing is very handy. Ideally it would be nice if slicing could be implemented as straight forward as is done python with numpy arrays. However, packages like ublas for C++ also support slicing.</p><p>Gregor said:<br /><div class="typeset"><p>the basic functionalty exists via subvector.
<br /> if you need more am busy with a branch that can do setsubvector on a mask matrix, enumerable of indices etc.</p></div></p>Gregortag:mathnet.uservoice.com,2008-02-07:Event/113265872012-05-10T13:41:41-07:002012-05-10T13:41:41-07:00Implement a function minimization algorithm [updated]<p>Doug said:<br /><div class="typeset"><p>It would be very cool to have this in Numerics. We use an independent port of the Fortran but it's far from pretty.</p>
<p>I vote for L-BFGS-B. We've used it extensively on high (20+) dimensional problems with slow fn evaluations (10-100ms) and it works as advertised for multivariate bounded minimization. DIY gradient. An automated gradient is numerically risky due to scaling and rounding, but could be a nice option.</p>
<p><a href="http://users.eecs.northwestern.edu/~nocedal/lbfgsb.html" rel="nofollow" target="_blank">http://users.eecs.northwestern.edu/~nocedal/lbfgsb.html</a></p></div></p>Dougtag:mathnet.uservoice.com,2008-02-07:Event/112804952012-05-03T08:14:26-07:002012-05-03T08:14:26-07:00use RealMatrix<T>, RealDenseMatrix<T> and RealDiagonalMatrix<T>, to reduce the number of Matrix classes.<p>Gregor suggested:<br />Currently there are 17 classes to implement.
DenseMatrix, SparseMatrix and Diagonal Matrix
and for each , MAtrix,Double, Single, Complex32 , Complex
This is 16 classes
as well as a single Generic:
IF using
Matrix<T>
RealMatrix<T>, RealDenseMatrix<T> and RealDiagonalMatrix<T>
CompleMatrix<T>, ComplexDenseMatrix<T> ComplexDiagonalMatrix<T>
would reduce it to 7.</p>Gregortag:mathnet.uservoice.com,2008-02-07:Event/111755752012-04-17T08:32:22-07:002012-04-17T08:32:22-07:00Optimized DenseLU solve [updated]<p>/// <summary>
/// Solves A*X=B for X using LU factorization.
/// </summary>
/// <param name="columnsOfB">The number of columns of B.</param>
/// <param name="a">The square matrix A.</param>
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
public static unsafe void LUSolveUnsafe(int columnsOfB, double[] aIn, int order, double[] bIn)
{
#region Initialize
if (aIn == null)
throw new ArgumentNullException("a");
if (bIn == null)
throw new ArgumentNullException("b");
int i;
int j;
int k;
double* a = stackalloc double[aIn.Length];
double* b = stackalloc double[bIn.Length];
int* ipiv = stackalloc int[order];
// Marshal
for (i = 0; i < aIn.Length; i++)
a[i] = aIn[i];
for (i = 0; i < bIn.Length; i++)
b[i] = bIn[i];
#endregion
#region Factorize
// Initialize the pivot matrix to the identity permutation.
for (i = 0; i < order; i++)
ipiv[i] = i;
// Outer loop
for (j = 0; j < order; j++)
{
int indexj = j * order;
int indexjj = indexj + j;
// Apply previous transformations.
for (i = 0; i < order; i++)
{
// Most of the time is spent in the following dot product.
int kmax = Math.Min(i, j);
double s = 0.0;
for (k = 0; k < kmax; k++)
s += a[(k * order) + i] * a[indexj + k];
a[indexj + i] -= s;
}
// Find pivot and exchange if necessary.
int p = j;
for (i = j + 1; i < order; i++)
if (Math.Abs(a[indexj + i]) > Math.Abs(a[indexj + p]))
p = i;
if (p != j)
{
for (k = 0; k < order; k++)
{
var temp = a[k * order + p];
a[k * order + p] = a[k * order + j];
a[k * order + j] = temp;
}
ipiv[j] = p;
}
// Compute multipliers.
//if (j < order & a[indexjj] != 0.0)
if (a[indexjj] != 0.0)
for (i = j + 1; i < order; i++)
a[indexj + i] /= a[indexjj];
}
#endregion
#region LUSolveFactored
// Compute the column vector P*B
for (i = 0; i < order; i++)
{
if (ipiv[i] == i)
continue;
int p = ipiv[i];
for (j = 0; j < columnsOfB; j++)
{
var temp = b[j * order + p];
b[j * order + p] = b[j * order + i];
b[j * order + i] = temp;
}
}
// Solve L*Y = P*B
for (k = 0; k < order; k++)
{
var korder = k * order;
for (i = k + 1; i < order; i++)
for (j = 0; j < columnsOfB; j++)
{
var index = j * order;
b[i + index] -= b[k + index] * a[i + korder];
}
}
// Solve U*X = Y;
for (k = order - 1; k >= 0; k--)
{
var korder = k + (k * order);
for (j = 0; j < columnsOfB; j++)
b[k + (j * order)] /= a[korder];
korder = k * order;
for (i = 0; i < k; i++)
for (j = 0; j < columnsOfB; j++)
b[i + j * order] -= b[k + j * order] * a[i + korder];
}
#endregion
// Marshal
for (i = 0; i < bIn.Length; i++)
bIn[i] = b[i];
}
/// <summary>
/// Solves A*X=B for X using LU factorization.
/// </summary>
/// <param name="columnsOfB">The number of columns of B.</param>
/// <param name="a">The square matrix A.</param>
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
public static void LUSolveSafe(int columnsOfB, double[] aIn, int order, double[] bIn)
{
#region Initialize
if (aIn == null)
throw new ArgumentNullException("a");
if (bIn == null)
throw new ArgumentNullException("b");
int i;
int j;
int k;
double[] a = new double[aIn.Length];
int[] ipiv = new int[order];
Array.Copy(aIn, a, aIn.Length);
#endregion
#region Factorize
// Initialize the pivot matrix to the identity permutation.
for (i = 0; i < order; i++)
ipiv[i] = i;
// Outer loop
for (j = 0; j < order; j++)
{
int indexj = j * order;
int indexjj = indexj + j;
// Apply previous transformations.
for (i = 0; i < order; i++)
{
// Most of the time is spent in the following dot product.
int kmax = Math.Min(i, j);
double s = 0.0;
for (k = 0; k < kmax; k++)
s += a[(k * order) + i] * a[indexj + k];
a[indexj + i] -= s;
}
// Find pivot and exchange if necessary.
int p = j;
for (i = j + 1; i < order; i++)
if (Math.Abs(a[indexj + i]) > Math.Abs(a[indexj + p]))
p = i;
if (p != j)
{
for (k = 0; k < order; k++)
{
var temp = a[k * order + p];
a[k * order + p] = a[k * order + j];
a[k * order + j] = temp;
}
ipiv[j] = p;
}
// Compute multipliers.
//if (j < order & a[indexjj] != 0.0)
if (a[indexjj] != 0.0)
for (i = j + 1; i < order; i++)
a[indexj + i] /= a[indexjj];
}
#endregion
#region LUSolveFactored
// Compute the column vector P*B
for (i = 0; i < order; i++)
{
if (ipiv[i] == i)
continue;
int p = ipiv[i];
for (j = 0; j < columnsOfB; j++)
{
var temp = bIn[j * order + p];
bIn[j * order + p] = bIn[j * order + i];
bIn[j * order + i] = temp;
}
}
// Solve L*Y = P*B
for (k = 0; k < order; k++)
{
var korder = k * order;
for (i = k + 1; i < order; i++)
for (j = 0; j < columnsOfB; j++)
{
var index = j * order;
bIn[i + index] -= bIn[k + index] * a[i + korder];
}
}
// Solve U*X = Y;
for (k = order - 1; k >= 0; k--)
{
var korder = k + (k * order);
for (j = 0; j < columnsOfB; j++)
bIn[k + (j * order)] /= a[korder];
korder = k * order;
for (i = 0; i < k; i++)
for (j = 0; j < columnsOfB; j++)
bIn[i + j * order] -= bIn[k + j * order] * a[i + korder];
}
#endregion
}</p><p>Doug said:<br /><div class="typeset"><p>Designed for HPC and the performance obsessed. We hit this class very hard with inner loops running billions of times by the end of a run. Tested up to A = 1000x1000 and B = 1000x8. It will run into stack out of memory issues for untested sizes.</p>
<p>The stackalloc on the unsafe version is a significant heap (garbage collector) saver, and eliminating the array bounds checking in the rest of the code leads to significant performance gains.</p>
<p>In a non-toy application this gives us a 20% performance boost.</p></div></p>Dougtag:mathnet.uservoice.com,2008-02-07:Event/111755092012-04-17T08:25:48-07:002012-04-17T08:25:48-07:00Optimized DenseLU solve<p>Doug suggested:<br />/// <summary>
/// Solves A*X=B for X using LU factorization.
/// </summary>
/// <param name="columnsOfB">The number of columns of B.</param>
/// <param name="a">The square matrix A.</param>
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
public static unsafe void LUSolveUnsafe(int columnsOfB, double[] aIn, int order, double[] bIn)
{
#region Initialize
if (aIn == null)
throw new ArgumentNullException("a");
if (bIn == null)
throw new ArgumentNullException("b");
int i;
int j;
int k;
double* a = stackalloc double[aIn.Length];
double* b = stackalloc double[bIn.Length];
int* ipiv = stackalloc int[order];
// Marshal
for (i = 0; i < aIn.Length; i++)
a[i] = aIn[i];
for (i = 0; i < bIn.Length; i++)
b[i] = bIn[i];
#endregion
#region Factorize
// Initialize the pivot matrix to the identity permutation.
for (i = 0; i < order; i++)
ipiv[i] = i;
// Outer loop
for (j = 0; j < order; j++)
{
int indexj = j * order;
int indexjj = indexj + j;
// Apply previous transformations.
for (i = 0; i < order; i++)
{
// Most of the time is spent in the following dot product.
int kmax = Math.Min(i, j);
double s = 0.0;
for (k = 0; k < kmax; k++)
s += a[(k * order) + i] * a[indexj + k];
a[indexj + i] -= s;
}
// Find pivot and exchange if necessary.
int p = j;
for (i = j + 1; i < order; i++)
if (Math.Abs(a[indexj + i]) > Math.Abs(a[indexj + p]))
p = i;
if (p != j)
{
for (k = 0; k < order; k++)
{
var temp = a[k * order + p];
a[k * order + p] = a[k * order + j];
a[k * order + j] = temp;
}
ipiv[j] = p;
}
// Compute multipliers.
//if (j < order & a[indexjj] != 0.0)
if (a[indexjj] != 0.0)
for (i = j + 1; i < order; i++)
a[indexj + i] /= a[indexjj];
}
#endregion
#region LUSolveFactored
// Compute the column vector P*B
for (i = 0; i < order; i++)
{
if (ipiv[i] == i)
continue;
int p = ipiv[i];
for (j = 0; j < columnsOfB; j++)
{
var temp = b[j * order + p];
b[j * order + p] = b[j * order + i];
b[j * order + i] = temp;
}
}
// Solve L*Y = P*B
for (k = 0; k < order; k++)
{
var korder = k * order;
for (i = k + 1; i < order; i++)
for (j = 0; j < columnsOfB; j++)
{
var index = j * order;
b[i + index] -= b[k + index] * a[i + korder];
}
}
// Solve U*X = Y;
for (k = order - 1; k >= 0; k--)
{
var korder = k + (k * order);
for (j = 0; j < columnsOfB; j++)
b[k + (j * order)] /= a[korder];
korder = k * order;
for (i = 0; i < k; i++)
for (j = 0; j < columnsOfB; j++)
b[i + j * order] -= b[k + j * order] * a[i + korder];
}
#endregion
// Marshal
for (i = 0; i < bIn.Length; i++)
bIn[i] = b[i];
}
/// <summary>
/// Solves A*X=B for X using LU factorization.
/// </summary>
/// <param name="columnsOfB">The number of columns of B.</param>
/// <param name="a">The square matrix A.</param>
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
public static void LUSolveSafe(int columnsOfB, double[] aIn, int order, double[] bIn)
{
#region Initialize
if (aIn == null)
throw new ArgumentNullException("a");
if (bIn == null)
throw new ArgumentNullException("b");
int i;
int j;
int k;
double[] a = new double[aIn.Length];
int[] ipiv = new int[order];
Array.Copy(aIn, a, aIn.Length);
#endregion
#region Factorize
// Initialize the pivot matrix to the identity permutation.
for (i = 0; i < order; i++)
ipiv[i] = i;
// Outer loop
for (j = 0; j < order; j++)
{
int indexj = j * order;
int indexjj = indexj + j;
// Apply previous transformations.
for (i = 0; i < order; i++)
{
// Most of the time is spent in the following dot product.
int kmax = Math.Min(i, j);
double s = 0.0;
for (k = 0; k < kmax; k++)
s += a[(k * order) + i] * a[indexj + k];
a[indexj + i] -= s;
}
// Find pivot and exchange if necessary.
int p = j;
for (i = j + 1; i < order; i++)
if (Math.Abs(a[indexj + i]) > Math.Abs(a[indexj + p]))
p = i;
if (p != j)
{
for (k = 0; k < order; k++)
{
var temp = a[k * order + p];
a[k * order + p] = a[k * order + j];
a[k * order + j] = temp;
}
ipiv[j] = p;
}
// Compute multipliers.
//if (j < order & a[indexjj] != 0.0)
if (a[indexjj] != 0.0)
for (i = j + 1; i < order; i++)
a[indexj + i] /= a[indexjj];
}
#endregion
#region LUSolveFactored
// Compute the column vector P*B
for (i = 0; i < order; i++)
{
if (ipiv[i] == i)
continue;
int p = ipiv[i];
for (j = 0; j < columnsOfB; j++)
{
var temp = bIn[j * order + p];
bIn[j * order + p] = bIn[j * order + i];
bIn[j * order + i] = temp;
}
}
// Solve L*Y = P*B
for (k = 0; k < order; k++)
{
var korder = k * order;
for (i = k + 1; i < order; i++)
for (j = 0; j < columnsOfB; j++)
{
var index = j * order;
bIn[i + index] -= bIn[k + index] * a[i + korder];
}
}
// Solve U*X = Y;
for (k = order - 1; k >= 0; k--)
{
var korder = k + (k * order);
for (j = 0; j < columnsOfB; j++)
bIn[k + (j * order)] /= a[korder];
korder = k * order;
for (i = 0; i < k; i++)
for (j = 0; j < columnsOfB; j++)
bIn[i + j * order] -= bIn[k + j * order] * a[i + korder];
}
#endregion
}</p>Dougtag:mathnet.uservoice.com,2008-02-07:Event/110142792012-03-22T11:15:23-07:002012-03-22T11:15:23-07:00implement a real number type that supports exact arithmetic [updated]<p>a real number type that lazily increases its precision when needed up to a maximum user-defined precision.</p><p>Joel Linn said:<br /><div class="typeset"><p>I came along this feature request because i have some precision issues with your matrix solving algorithms. I use them to calculate the coefficients of polynomials for Splines. For some given points you could see gaps in the graph and, if you take even more worse values, the whole graph becomes just rubbish.
<br />However, when i use matlab to solve the matrix by using the rref (reduced row echelon form) command, the resulting values are similar but still differ, which result in them being unusable.</p>
<p>I guess this is because the algorithms do calculations where somehow precision is lost. I mean where it says 7.4390....... there should be 7.93498........
<br />To use another number type like suggested here is probably one suitable solution.</p></div></p>Joel Linntag:mathnet.uservoice.com,2008-02-07:Event/109246142012-03-09T05:48:24-08:002012-03-09T05:48:24-08:00Add Moore-Penrose pseudoinverse<p>Emile suggested:<br />This a proposition to add a Moore-Penrose pseudoinverse implementation (couldn't find it in Math.net numerics). This example is implemented as a Extension Method to the Matrix<double> class. The pseudoinverse it is computed using the singular value decomposition. The algorithm comes from Wikipedia. Save the code in your project and call Matrix.PseudoInverse()
--------------------------------------------
/*
* ExtensionMethods_2.cs
*
*/
using System;
using MathNet.Numerics.LinearAlgebra.Double.Factorization;
namespace MathNet.Numerics.LinearAlgebra.Double
{
public static class ExtensionMethods
{
/// <summary>
/// Moore–Penrose pseudoinverse
/// If A = U • Σ • VT is the singular value decomposition of A, then A† = V • Σ† • UT.
/// For a diagonal matrix such as Σ, we get the pseudoinverse by taking the reciprocal of each non-zero element
/// on the diagonal, leaving the zeros in place, and transposing the resulting matrix.
/// In numerical computation, only elements larger than some small tolerance are taken to be nonzero,
/// and the others are replaced by zeros. For example, in the MATLAB or NumPy function pinv,
/// the tolerance is taken to be t = ε • max(m,n) • max(Σ), where ε is the machine epsilon. (Wikipedia)
/// </summary>
/// <param name="M">The matrix to pseudoinverse</param>
/// <returns>The pseudoinverse of this Matrix</returns>
public static Matrix PseudoInverse(this Matrix M)
{
Svd D = M.Svd(true);
Matrix W = (Matrix)D.W();
Vector s = (Vector)D.S();
// The first element of W has the maximum value.
double tolerance = Precision.EpsilonOf(2) * Math.Max(M.RowCount, M.ColumnCount) * W[0, 0];
for (int i = 0; i < s.Count; i++)
{
if (s[i] < tolerance)
s[i] = 0;
else
s[i] = 1 / s[i];
}
W.SetDiagonal(s);
// (U * W * VT)T is equivalent with V * WT * UT
return (Matrix)(D.U() * W * D.VT()).Transpose();
}
}
}
</p>Emiletag:mathnet.uservoice.com,2008-02-07:Event/108359772012-02-25T16:53:03-08:002012-02-25T16:53:03-08:00boost performance by adding parallel implementationsBoris Kogantag:mathnet.uservoice.com,2008-02-07:Event/108071012012-02-21T14:33:31-08:002012-02-21T14:33:31-08:00implement vector "shifting"<p>Ben Mcmillan suggested:<br />because I'm working with time series, I find that I am often getting rid of the first element of my vector, and adding a new element at the end.
To do so I write a loop to iterate through the vector.
I assume my way of doing this is relatively slow, and it would be much faster if it was a native method.</p>Ben Mcmillantag:mathnet.uservoice.com,2008-02-07:Event/107281582012-02-09T13:50:19-08:002012-02-09T13:50:19-08:00Add BandedMatrix, BandedSymmetricMatrix, and SparseSymmetricMatrix classesAnonymoustag:mathnet.uservoice.com,2008-02-07:Event/103934172011-12-13T11:57:19-08:002011-12-13T11:57:19-08:00Add support for cuda<p>Anonymous suggested:<br />Is this possible to split the matrix multiplication algorithms to use processor and gpgpu all at the same time?
It would be an amazing feature to be added.</p>Anonymoustag:mathnet.uservoice.com,2008-02-07:Event/102411282011-11-16T11:03:08-08:002011-11-16T11:03:08-08:00Clone [updated]<p>Override .Clone for the various matrix storage classes. Right now it's in the generic class and calls .At a zillion times instead of just doing an array block copy.</p><p>Christoph Rüegg said:<br /><div class="typeset"><p>Good point though concerning the unnecessary Clone calls, need think about some options there...</p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/102404122011-11-16T09:16:33-08:002011-11-16T09:16:33-08:00Clone [updated]<p>Override .Clone for the various matrix storage classes. Right now it's in the generic class and calls .At a zillion times instead of just doing an array block copy.</p><p>Christoph Rüegg said:<br /><div class="typeset"><p>github issue #24</p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/102403032011-11-16T08:58:32-08:002011-11-16T08:58:32-08:00Clone [updated]<p>Override .Clone for the various matrix storage classes. Right now it's in the generic class and calls .At a zillion times instead of just doing an array block copy.</p><p>Christoph Rüegg said:<br /><div class="typeset"><p>Clone is just a call to CopyTo. Are we talking about the same codebase?</p>
<p><a href="https://github.com/mathnet/mathnet-numerics/blob/master/src/Numerics/LinearAlgebra/Generic/Matrix.cs#L250" rel="nofollow" target="_blank">https://github.com/mathnet/mathnet-numerics/blob/master/src/Numerics/LinearAlgebra/Generic/Matrix.cs#L250</a></p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/102299052011-11-14T22:12:04-08:002011-11-14T22:12:04-08:00Clone [updated]<p>Override .Clone for the various matrix storage classes. Right now it's in the generic class and calls .At a zillion times instead of just doing an array block copy.</p><p>Lacko said:<br /><div class="typeset"><p>Actually, it's Clone and not CopyTo that has to be overridden, as CopyTo might be called with a matrix in another storage format.</p>
<p>I've just started using math.net a few days ago to replace my not so elaborate matrix implementation and mkl wrappers with something that's community supported. I'm pretty much satisfied but the first application already revealed some performance bootleneck. For instance, there's no direct access to the U and Vt matrices of the SVD class, only via a clone call which I think is unnecessary. I'd change the U() function to a simple property. To prevent changes to the matrix (which is probably not a big issue because users of math libs are usually aware of what they're doing) an immutable matrix class could be added to the lib. Unfortunately, changing U() to a property would break the interface. Well, Clone could be removed though. I've changed the clone function to do a block copy instead of an itemwise clone via the At function and still this single Copy uses 5% of my runtime.</p>
<p>I don't know how to contribute to the package but would happily implement some of these changes. Also, I have a piece of robust principal component code that I can port to math.net and make it part of the package if anyone's interested.</p></div></p>Lackotag:mathnet.uservoice.com,2008-02-07:Event/102291082011-11-14T17:48:55-08:002011-11-14T17:48:55-08:00Clone [is now planned]<p>Override .Clone for the various matrix storage classes. Right now it's in the generic class and calls .At a zillion times instead of just doing an array block copy.</p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/102291072011-11-14T17:48:55-08:002011-11-14T17:48:55-08:00Clone [updated]<p>Override .Clone for the various matrix storage classes. Right now it's in the generic class and calls .At a zillion times instead of just doing an array block copy.</p><p>Christoph Rüegg (admin) responded:<br /><div class="typeset"><p>Confirmed, managed dense matrix implementations are missing a proper override of CopyTo (some other implementations already do override it). Needs a github ticket.</p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/102255412011-11-14T08:12:10-08:002011-11-14T08:12:10-08:00Clone<p>Lacko suggested:<br />Override .Clone for the various matrix storage classes. Right now it's in the generic class and calls .At a zillion times instead of just doing an array block copy.</p>Lackotag:mathnet.uservoice.com,2008-02-07:Event/100347092011-10-18T03:25:18-07:002011-10-18T03:25:18-07:00cache cdf in Categorical distribution function [updated]<p>makro said:<br /><div class="typeset"><p>ok apparantly this class is depracted, sorry.</p></div></p>makrotag:mathnet.uservoice.com,2008-02-07:Event/100346522011-10-18T03:09:44-07:002011-10-18T03:09:44-07:00add Empirical distribution function (see wiki)makrotag:mathnet.uservoice.com,2008-02-07:Event/100346162011-10-18T03:00:57-07:002011-10-18T03:00:57-07:00cache cdf in Categorical distribution functionmakrotag:mathnet.uservoice.com,2008-02-07:Event/98486032011-09-22T01:51:04-07:002011-09-22T01:51:04-07:00add regression ( linear, parabolic, etc ) [updated]<p>Solve for the variables.</p><p>DP said:<br /><div class="typeset"><p>would add to the feature set.</p></div></p>DPtag:mathnet.uservoice.com,2008-02-07:Event/98485992011-09-22T01:50:41-07:002011-09-22T01:50:41-07:00add regression ( linear, parabolic, etc )<p>DP suggested:<br />Solve for the variables.</p>DPtag:mathnet.uservoice.com,2008-02-07:Event/90229972011-07-17T14:32:20-07:002011-07-17T14:32:20-07:00add a Math.Ulp function [is now completed]<p>ULP mean Unit in the Last Place.
It is implemented in Java and is useful in some cases.
Here is some code I have write, but I'm not sure of my implementation :
float absX = Math.Abs(value);
byte[] bytes = BitConverter.GetBytes(absX);
if (BitConverter.IsLittleEndian)
bytes[0]++;
else
bytes[bytes.Length - 1]++;
float nextFloatNumber = BitConverter.ToSingle(bytes, 0);
return (nextFloatNumber - absX);
Take a look at :
http://stackoverflow.com/questions/1668183/find-min-max-of-a-float-double-that-has-the-same-internal-representation</p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90229952011-07-17T14:32:20-07:002011-07-17T14:32:20-07:00add a Math.Ulp function [updated]<p>ULP mean Unit in the Last Place.
It is implemented in Java and is useful in some cases.
Here is some code I have write, but I'm not sure of my implementation :
float absX = Math.Abs(value);
byte[] bytes = BitConverter.GetBytes(absX);
if (BitConverter.IsLittleEndian)
bytes[0]++;
else
bytes[bytes.Length - 1]++;
float nextFloatNumber = BitConverter.ToSingle(bytes, 0);
return (nextFloatNumber - absX);
Take a look at :
http://stackoverflow.com/questions/1668183/find-min-max-of-a-float-double-that-has-the-same-internal-representation</p><p>Christoph Rüegg (admin) responded:<br /><div class="typeset"><p>See Precision.EpsilonOf (and .Increment/.Decrement/.DumbersBetween/.CompareTo etc)</p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90229632011-07-17T14:28:14-07:002011-07-17T14:28:14-07:00add Log Normal distribution [is now completed]Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90229612011-07-17T14:28:14-07:002011-07-17T14:28:14-07:00add Log Normal distribution [updated]<p>Christoph Rüegg (admin) responded:<br /><div class="typeset"><p>LogNormal is available in Math.NET Numerics</p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90228752011-07-17T14:20:13-07:002011-07-17T14:20:13-07:00implement a real number type that supports exact arithmetic [updated]<p>a real number type that lazily increases its precision when needed up to a maximum user-defined precision.</p><p>Christoph Rüegg said:<br /><div class="typeset"><p>That would essentially be a fixed-precision number, i.e. a System.Numerics.BigInteger with a fixed number of bits (or maybe digits) shifted virtually to the right of the comma? As opposed to e.g. a rational number constructed as a fraction of two BigIntegers?</p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90227272011-07-17T14:09:26-07:002011-07-17T14:09:26-07:00Matrix allocation as single array instead of array of arrays [is now completed]<p>Change matrix (and any other) allocation/member from:
double[][]
to:
double[] OR double[,]
and handle indexing etc internally. Not having matrix data as one continuous memory area is not a good thing for e.g. interop. Additionally, allocation is a lot slower for many rows.</p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90227252011-07-17T14:09:26-07:002011-07-17T14:09:26-07:00Matrix allocation as single array instead of array of arrays [updated]<p>Change matrix (and any other) allocation/member from:
double[][]
to:
double[] OR double[,]
and handle indexing etc internally. Not having matrix data as one continuous memory area is not a good thing for e.g. interop. Additionally, allocation is a lot slower for many rows.</p><p>Christoph Rüegg (admin) responded:<br /><div class="typeset"><p>Math.NET Numerics uses double[] for matrice data storage (mainly for native code compatibility)</p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90226472011-07-17T14:07:45-07:002011-07-17T14:07:45-07:00Reintegrate the Sparse Linear Algebra toolkit [is now completed]<p>Iridium once supported sparse linear algebra (for a very short time) but then it was temporarily removed because of some issues. Solve them and integrate it back.</p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90226452011-07-17T14:07:45-07:002011-07-17T14:07:45-07:00Reintegrate the Sparse Linear Algebra toolkit [updated]<p>Iridium once supported sparse linear algebra (for a very short time) but then it was temporarily removed because of some issues. Solve them and integrate it back.</p><p>Christoph Rüegg (admin) responded:<br /><div class="typeset"><p>Math.NET Numerics supports sparse matrices again</p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90226312011-07-17T14:06:58-07:002011-07-17T14:06:58-07:00Add methods for linear and quadratic programming [is now under review]<p>Linear and quadratic programming methods are great techniques for minimization problems. Other, more complicated methodologies - such as MPC - can built on top of them fairly easily.</p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90226112011-07-17T14:06:17-07:002011-07-17T14:06:17-07:00Provide linux packages (for use with mono) [is now planned]<p>Extend the package generation scripts and provide the missing documents (and maybe consider to switch back to a classic version system) to build linux packages (e.g. deb for debian/ubuntu) that will run under mono.</p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90225752011-07-17T14:05:42-07:002011-07-17T14:05:42-07:00Histogram constructor with buckets. Data is applied to the buckets. [is now under review]<p>I need to create a histogram with buckets from another histogram and expect my data to be counted relative to those buckets.</p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90225512011-07-17T14:04:45-07:002011-07-17T14:04:45-07:00Savitzky–Golay [is now under review]<p>?</p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90225432011-07-17T14:04:08-07:002011-07-17T14:04:08-07:00Savitzky–Golay [updated]<p>?</p><p>Christoph Rüegg said:<br /><div class="typeset"><p>I assume you're referring to Savitzky–Golay smoothing filters, as in <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Savitzky%E2%80%93Golay_smoothing_filter" rel="nofollow" target="_blank">https://secure.wikimedia.org/wikipedia/en/wiki/Savitzky%E2%80%93Golay_smoothing_filter</a></p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90225112011-07-17T14:00:27-07:002011-07-17T14:00:27-07:00Say how to install the DLL and XML files in your download package [is now completed]<p>There are no installation instructions in the downloaded zip file or the chm file within it. What do I use to install the library?</p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/90225092011-07-17T14:00:27-07:002011-07-17T14:00:27-07:00Say how to install the DLL and XML files in your download package [updated]<p>There are no installation instructions in the downloaded zip file or the chm file within it. What do I use to install the library?</p><p>Christoph Rüegg (admin) responded:<br /><div class="typeset"><p>There are NuGet packages available by now that simplify referncing in VS remarkably.</p></div></p>Christoph Rüeggtag:mathnet.uservoice.com,2008-02-07:Event/83813252011-06-14T11:00:32-07:002011-06-14T11:00:32-07:00Savitzky–Golay<p>jbmckim suggested:<br />?</p>jbmckimtag:mathnet.uservoice.com,2008-02-07:Event/82741652011-06-10T09:42:39-07:002011-06-10T09:42:39-07:00Histogram constructor with buckets. Data is applied to the buckets.<p>neosimian suggested:<br />I need to create a histogram with buckets from another histogram and expect my data to be counted relative to those buckets.</p>neosimiantag:mathnet.uservoice.com,2008-02-07:Event/74137092011-05-11T03:18:24-07:002011-05-11T03:18:24-07:00Implement a function minimization algorithm [updated]<p>Tom Robinson said:<br /><div class="typeset"><p>Optimisation methods would be very useful.</p></div></p>Tom Robinsontag:mathnet.uservoice.com,2008-02-07:Event/74135812011-05-11T03:10:05-07:002011-05-11T03:10:05-07:00Implement the Efficient Global Optimisation (EGO) Algorithm for Expensive Black-box functions [updated]<p>Tom Robinson said:<br /><div class="typeset"><p>This is a general stochastic method for finding the global optimum of an unknown function in any number of dimensions. It is most useful for expensive black box functions (i.e. a objective 'function' which takes minutes/hours for a single iteration).</p>
<p>This method has various added benefits. One being: As the optimisation is performed, a response surface is fitted to the unknown function which can be used as a surrogate for future function evaluations. The 'kriging' response model parameterises the unknown functions input variables in terms of output sensitivity and smoothness.</p>
<p>An outline of the original method is described in:</p>
<p>Jones, D., Schonlau, M., and Welch, W., 1998, “Efficient Global Optimization
<br />of Expensive Black-Box Functions,” J. Global Optim., 13*4*, pp. 455–492.</p>
<p>A copy of which can be found via Google search here:</p>
<p><a href="http://www.ressources-actuarielles.net/EXT/ISFA/1226.nsf/9c8e3fd4d8874d60c1257052003eced6/f84f7ac703bf5862c12576d8002f5259/$FILE/Jones98.pdf" rel="nofollow" target="_blank">http://www.ressources-actuarielles.net/EXT/ISFA/1226.nsf/9c8e3fd4d8874d60c1257052003eced6/f84f7ac703bf5862c12576d8002f5259/$FILE/Jones98.pdf</a></p></div></p>Tom Robinsontag:mathnet.uservoice.com,2008-02-07:Event/74132652011-05-11T02:48:29-07:002011-05-11T02:48:29-07:00Implement the Efficient Global Optimisation (EGO) Algorithm for Expensive Black-box functionsTom Robinsontag:mathnet.uservoice.com,2008-02-07:Event/54326952011-02-10T00:38:04-08:002011-02-10T00:38:04-08:00Collection.product<p>dane dang suggested:<br />/// <summary>
/// Returns the cartesian product of the two collections <c>c1</c>
/// and <c>c2</c>.
/// </summary>
/// <param name="c1">Should not be null.</param>
/// <param name="c2">Should not be null.</param>
public static ICollection Product(ICollection c1, ICollection c2)
{
if(c1 == null)
{
throw new ArgumentNullException("c1", string.Format(Resources.ArgumentNull, "c1"));
}
if(c2 == null)
{
throw new ArgumentNullException("c2", string.Format(Resources.ArgumentNull, "c2"));
}
return null;
}</p>dane dangtag:mathnet.uservoice.com,2008-02-07:Event/52065372011-02-01T09:55:43-08:002011-02-01T09:55:43-08:00ODE Solver(RK4 etc.) [updated]<p>Neil Dalchau said:<br /><div class="typeset"><p>I agree with fischi. If the .NET framework is to make inroads into scientific computing, then ODE solvers are mandatory. Having access to ODE solvers in .NET would basically turn me away from Matlab and over to .NET for nearly all of my work.</p></div></p>Neil Dalchautag:mathnet.uservoice.com,2008-02-07:Event/42742592010-12-09T08:06:00-08:002010-12-09T08:06:00-08:00Allow for performing matrix calculations like in Matlabmayerwin