
I have been porting some code that I had with my own Matrix<T> implementation but Math.Net is far more complete.
And I am wondering if there exists such a method here.
My code looked like this:
wu_v += Functions.Sum(v, Axis.Rows);
Where wu_v is a Matrix<T> and v is a Vector<T>. The alternative is to do:
wu_v = wu_v + ones * diag(v) or coding it by hand for performance, but I was wondering if there was such a construct already.
Federico


Coordinator
Jul 20, 2014 at 9:06 AM

Hi Federico,
I don't fully understand yet what the operation should do. What does Functions.Sum(v, Axis.Rows) do and how does it relate to
ones * diag(v) , exactly?
Maybe you're looking for FoldRows(f,state) which applies a binary function to each row vector of the matrix and a state vector (where the result becomes the state for the next row)? See also "Enumerators and Higher Order Functions" in
Matrices and Vectors.
Thanks,
Christoph



Probably FoldRows(f,state) is what I need to build it.
Function.Sum(v, Axis.Rows) looks like this (columnmajor):
for (int majorItem = 0; majorItem < t.Length; majorItem++)
{
for (int i = 0; i < items; i++)
t[majorItem] += mt[ptr + i * minorStride];
ptr += majorStride;
}
It treats every column of the matrix M as a vector mv and adds the vector v to it.
For every k in M
mv = M.GetColumnVector(k);
mv += v ;


Coordinator
Jul 20, 2014 at 10:00 PM

Ah, that looks more like:
m.MapIndexedInplace((i,j,x) => x + v.At(i));


Jul 21, 2014 at 12:42 AM
Edited Jul 21, 2014 at 12:43 AM

This is the implementation. Is there any way to avoid the casting?
public static Matrix<T> AddVectorOnEachColumn<T>(this Matrix<T> m1, Vector<T> v, T scale) where T : struct,
IEquatable<T>, IFormattable
{
Contract.Requires(m1 != null);
Contract.Requires(v != null);
if (m1 is Matrix<float>)
{
var fm1 = m1 as Matrix<float>;
var fv = v as Vector<float>;
var fscale = (float)(object)scale;
return fm1.MapIndexed((i, j, value) => fm1.At(i, j) + fscale * fv.At(j)) as Matrix<T>;
}
else if (m1 is Matrix<double>)
{
var dm1 = m1 as Matrix<double>;
var dv = v as Vector<double>;
var dscale = (double)(object)scale;
return dm1.MapIndexed((i, j, value) => dm1.At(i, j) + dscale * dv.At(j)) as Matrix<T>;
}
else throw new NotSupportedException("Type: {0} is not supported by the Matrix<T> class.");
}


Coordinator
Jul 21, 2014 at 6:19 AM

dm1.At(i, j) is already provided as value :
fm1.MapIndexed((i, j, value) => value + fscale * fv.At(j)) as Matrix<T>
Then you can prescale the vector, once, which is supported generically; getting rid of some of the casting:
var fm1 = m1 as Matrix<float>;
var fsv = (v * scale) as Vector<float>;
return fm1.MapIndexed((i, j, value) => value + fsv.At(j)) as Matrix<T>;
Do you actually need the extension function to be generic? If not, you can just overload per type individually, without any casting:
// Inplace:
public static void AddScaledVectorToEachColumnInplace(this Matrix<double> m, Vector<double> v, double scale)
{
double[] scaled = (v * scale).ToArray();
m.MapIndexedInplace((i,j,x) => x + scaled[i], Zeros.Include);
}
public static void AddScaledVectorToEachColumnInplace(this Matrix<float> m, Vector<float> v, float scale)
{
float[] scaled = (v * scale).ToArray();
m.MapIndexedInplace((i,j,x) => x + scaled[i], Zeros.Include);
}
// Outplace:
public static Matrix<double> AddScaledVectorToEachColumn(this Matrix<double> m, Vector<double> v, double scale)
{
double[] scaled = (v * scale).ToArray();
return m.MapIndexed((i,j,x) => x + scaled[i], Zeros.Include);
}

