Home > Enterprise >  How to initialize a two dimension array for a Matrix class in C#
How to initialize a two dimension array for a Matrix class in C#

Time:11-03

Problem

I am writing a Matrix class in C# and I know that this class needs a two dimension array to store the Matrix object. The constructor for my Matrix class takes two parameters, the m and n dimensions of the Matrix. I have tried to assign the array inside the constructor but I get the error that Invalid Rank Specifier. The code I tried is listed below.

class Matrix
    {
        //make the dimensions private
        private int m,n;

        //The Matrix constructor needs two parameters
        //The row and column dimensions
        //declare the two dimension array
        private int[][] array;
        public Matrix(int m, int n) {
          //assign the array inside the constructor
            array = new int[m][n];
        }
        //method to allocate the Matrix
    }

My goal is to initialize the array with the dimensions first so that assigning can be done without errors, Thank You.

 

CodePudding user response:

I feel like what you are trying to do is create a multi dimensional array, which you can learn more about here.

In your case this would mean that you would create an int[,] array as such:

class Matrix
{
    //make the dimensions private
    private int m,n;

    //The Matrix constructor needs two parameters
    //The row and column dimensions
    //declare the two dimension array
    private int[,] array;
    public Matrix(int m, int n) {
      //assign the array inside the constructor
        array = new int[m, n];
    }
    //method to allocate the Matrix
}

After that you can access your values through:

public int GetValue(int m, int n) => array[m,n];

And equally for settings values:

public void SetValue(int m, int n) => array[m,n] = value;

CodePudding user response:

You actually have a jagged array, i.e. array of array: int[][], note that 2d array is int[,]

To initialize int[][] you have to create each inner array:

 public Matrix(int m, int n) {
   array = new int[m][];         // outer array of size m which

   for (int i = 0; i < n;   i)   // contains
     array[i] = new int[n];      // arrays of length n 
 }

You can use Linq for shorter syntax:

 using System.Linq;

 ...

 public Matrix(int m, int n) {
   array = Enumerable
     .Range(0, m)
     .Select(_ => new int[n])
     .ToArray();
 }

Edit: Possible Matrix implementation:

  class Matrix {
    private int[][] array;

    public Matrix(int rows, int columns) {
      if (rows <= 0)
        throw new ArgumentOutOfRangeException(nameof(rows));
      if (columns <= 0)
        throw new ArgumentOutOfRangeException(nameof(columns));

      array = Enumerable
        .Range(0, rows)
        .Select(_ => new int[columns])
        .ToArray();
    }

    public int RowCount => array.Length;

    public int ColumnCount => array[0].Length;

    public int this[int row, int column] {
      get {
        if (row < 0 || row >= array.Length)
          throw new ArgumentOutOfRangeException(nameof(row));
        if (column < 0 || column >= array[row].Length)
          throw new ArgumentOutOfRangeException(nameof(column));

        return array[row][column];
      }
      set {
        if (row < 0 || row >= array.Length)
          throw new ArgumentOutOfRangeException(nameof(row));
        if (column < 0 || column >= array[row].Length)
          throw new ArgumentOutOfRangeException(nameof(column));

        array[row][column] = value;
      }
    }
  }

CodePudding user response:

I prefer to use a regular 1D array for 2D data. Something like:

public class MyMatrix<T> 
{
        public int Width { get; }
        public int Height { get; }
        public T[] Data { get; }
        public MyMatrix(int width, int height)
        {
            Width = width;
            Height = height;
            Data = new T[width * height];
        }
        public T this[int x, int y]
        {
            get => Data[y * Width   x];
            set => Data[y * Width   x] = value;
        }
}

This has some advantages over the typical 2D Multidimensional approach:

  • Interoperability: Multidimensional arrays are a .Net concept that does not exist in every language, but just about every language have some sort of 1D array.
  • Serialization: Most serialization libraries handle 1D arrays, support for 2D arrays are more spotty.
  • Performance: Sometimes you just need to iterate over all the items, using the backing 1D arrays is probably the fastest way to do this.
  • Avoiding pitfals: .GetLength() for multidimensional arrays is quite slow, not a large problem if you cache the values outside your loop, but can be a problem if you do not know about this, or forget.
  • Related