This project has moved and is read-only. For the latest updates, please go here.

How to apply operation over vector from each row/column of a matrix?

Jul 19, 2014 at 8:41 PM
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
Jul 20, 2014 at 10: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
Jul 20, 2014 at 10:22 PM
Probably FoldRows(f,state) is what I need to build it.

Function.Sum(v, Axis.Rows) looks like this (column-major):
 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 ;
Jul 20, 2014 at 11:00 PM
Ah, that looks more like:
m.MapIndexedInplace((i,j,x) => x + v.At(i));
Jul 21, 2014 at 1:42 AM
Edited Jul 21, 2014 at 1: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.");
 }
Jul 21, 2014 at 7: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 pre-scale 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);
}