score:6

Accepted answer

EDIT: The code below will work, but it's not as readable as using an explicit method. LINQ is great where it definitely adds to readability... but this isn't one of those cases.

This is a briefer version of CMS's answer - the extra let isn't required, and when you're just doing a projection it's simpler to just use dot notation:

int[] result = Enumerable.Range(0, a.Length)
                         .Select(i => a[i] * b[i])
                         .ToArray();

An alternative is to use the form of Select which takes an index:

int[] result = a.Select((value, index) => value * b[index])
                .ToArray();

score:2

You can do something like this:

int[] a = {10, 20, 30};
int[] b = {2, 4, 10};

if (a.Length == b.Length)
{
  int[] result = (from i in Enumerable.Range(0, a.Length)
          let operation = a[i]*b[i]
        select operation).ToArray();
}

But I recommend you if you will work with matrices and more advanced mathematical topics to get a good Math library, like NMath or search for a Matrix class implementation, there are many out there...

score:2

There is nothing built in, but you can always write your own functions. The first one below is a simple extension method doing what you want. The second allows you to specify the function to apply:

class Program
{
    public static void Main(string[] args)
    {
        int[] a = { 10, 20, 30 };
        int[] b = { 2, 4, 10 };
        int[] c = a.MatrixMultiply(b);
        int[] c2 = a.Zip(b, (p1, p2) => p1 * p2);
    }
}

public static class Extension
{
    public static int[] MatrixMultiply(this int[] a, int[] b)
    {
        // TODO: Add guard conditions
        int[] c = new int[a.Length];
        for (int x = 0; x < a.Length; x++)
        {
            c[x] = a[x] * b[x];
        }
        return c;
    }

    public static R[] Zip<A, B, R>(this A[] a, B[] b, Func<A, B, R> func)
    {
        // TODO: Add guard conditions
        R[] result = new R[a.Length];
        for (int x = 0; x < a.Length; x++)
        {
            result[x] = func(a[x], b[x]);
        }
        return result;
    }
}

score:0

Check out this MSDN article on the upcoming PLINQ (Parallel LINQ). From the article, here is an example of using PLINQ to parallelize matrix multiplication:

void ParMatrixMult(int size, double[,] m1, double[,] m2, double[,] result)
{
  Parallel.For( 0, size, delegate(int i) {
    for (int j = 0; j < size; j++) {
      result[i, j] = 0;
      for (int k = 0; k < size; k++) {
        result[i, j] += m1[i, k] * m2[k, j];
      }
    }
  });
}

It's using LINQ and a Lambda! And as a bonus it's spread across processors.

score:5

Using the Zip function (new to .NET 4.0) details here:

int[] a = { 10, 20, 30 };
int[] b = { 2, 4, 10 };

int[] c = a.Zip(b, (a1, b1) => a1 * b1).ToArray();

Until .NET 4 comes out you can use the zip implementation from the link above.

score:0

You can write a simple extension that works with matrices of any rank.

public static class TwodimensionalArrayExtensions
{
    public static int[][] MultiplyBy(this int[][] leftMatrix, int[][] rightMatrix)
    {
        if (leftMatrix[0].Length != rightMatrix.Length)
        {
            return null; // Matrices are of incompatible dimensions
        }

        return leftMatrix.Select( // goes through <leftMatrix matrix> row by row

                (leftMatrixRow, leftMatrixRowIndexThatIsNotUsed) =>

                    rightMatrix[0].Select( // goes through first row of <rightMatrix> cell by cell

                            (rightFirstRow, rightMatrixColumnIndex) =>

                                rightMatrix
                                    .Select(rightRow => rightRow[rightMatrixColumnIndex]) // selects column from <rightMatrix> for <rightMatrixColumnIndex>
                                    .Zip(leftMatrixRow, (rowCell, columnCell) => rowCell * columnCell) // does scalar product
                                    .Sum() // computes the sum of the products (rowCell * columnCell) sequence.
                        )
                        .ToArray() // the new cell within computed matrix
            )
            .ToArray(); // the computed matrix itself
    }
}

Here are some test values:

// Test1
int[][] A = { new[] { 1, 2, 3 } };
int[][] B = { new[] { 1 }, new[] { 2 }, new[] { 3 } };
int[][] result = A.MultiplyBy(B);

// Test2
int[][] A = { new[] { 1 }, new[] { 2 }, new[] { 3 } };
int[][] B = { new[] { 1, 2, 3 } };
int[][] result = A.MultiplyBy(B);

// Test3
int[][] A = new int[][] { new[] { 1, 2 }, new[] { 2, 2 }, new[] { 3, 1 } };
int[][] B = new int[][] { new[] { 1, 1, 1 }, new[] { 2, 3, 2 } };
int[][] result = A.MultiplyBy(B);

score:0

If the right matrix is transposed beforehand, multiplication can be expressed more elegantly as follows.

int[][] Multiply(int[][] left, int[][] right) =>
    left.Select(lr => 
            right
                .Select(rr => 
                    lr.Zipped(rr, (l, r) => l * r).Sum())
                .ToArray())
        .ToArray();

Related Articles