Home c# Transposing algorithms for matrices

Transposing algorithms for matrices

Author

Date

Category

Is there any other way to transpose square matrix?

for (int i = 0; i & lt; n; i ++)
{
  for (int j = 0; j & lt; i; j ++)
  {
    TMP = A [I, J];
    a [i, j] = a [j, i];
    A [j, i] = TMP;
  }
}

Answer 1, Authority 100%

You can change the algorithm in this way:

Why change the algorithm so? I do not know, but since you want another way, here’s:

for (int i = 1; i & lt; n; i ++)
{
 for (int j = 0; j & lt; i; j ++)
 {
  a [i, j] ^ = a [j, i];
  a [j, i] ^ = a [i, j];
  a [i, j] ^ = a [j, i];
 }
}

Answer 2, Authority 250%

Let the Izvrat Begin!

class matrix & lt; t & gt;
{
  T [,] PAYLOAD;
  BOOL ISTRANSPOSED = FALSE;
  Public Matrix (int n): this (n, n) {}
  Public Matrix (int m, int n) {payload = new t [m, n]; }
  // This will call if someone turns to the matrix by index:
  // Matrix & LT; int & gt; m = new matrix & lt; int & gt; (5);
  // m [0, 2] = 42; // & lt; - here
  Public T This [int i, int j]
  {
    // If the flag is that the matrix is ​​transposed, we change the indexes in places:
    Get {return istransposed? PAYLOAD [J, I]: PAYLOAD [I, J]; }
    set {if (iStransposed) payload [j, i] = value; else payload [i, j] = value; }
  }
  Public Void Transpose () {iStransposed =! Istransposed; }
}

exchanged transposition speed at the access speed.


Answer 3, Authority 225%

Abnormal programming 1 on C #? I have them! Meet – transpose matrix in functional style.

using system;
Using System.Collections.Genic;
Using System.Linq;
Namespace Main.
{
  Static Class MylinqExtensions
  {
    Public Static Ienumerable & lt; Ienumerable & lt; T & GT; & gt; Batch & Lt; T & GT; (This Ienumerable & LT; T & GT; Source, Int Batchsize)
    {
      Using (var enumerator = source.getenumerator ())
      {
        While (enumerator.movenext ())
        {
          Yield Return Yieldbatchelements (Enumerator, Batchsize - 1);
        }
      }
    }
    Private Static Ienumerable & lt; T & GT; Yieldbatchelements & lt; T & GT; (Ienumerator & lt; T & GT; Source, Int Batchsize)
    {
      Yield Return source.current;
      For (int i = 0; i & lt; Batchsize & amp; & amp; source.movenext (); i ++)
      {
        Yield Return source.current;
      }
    }
    Public Static Ienumerable & lt; Ienumerable & lt; T & GT; & gt; Zipmany & LT; T & GT; (This ienumerable & lt; ienumerable & lt; t & gt; & gt; enumerable
    {
      Return Enumerables.Select (Inner = & gt; Inner.select ((S, I) = & GT; new {s, i}))
               .SelectMany (A = & GT; A.Tolist ())
               .Groupby (a = & gt; a.i, a = & gt; a.s)
               .Select (A = & GT; A.Tolist ()). Tolist ();
    }
  }
  Class Program
  {
    Static Void Main (String [] Args)
    {
      Var Matrix = New []
      {
        {12},
        {3, 4},
        {5, 6},
        {7, 8},
        {9, 0}
      };
      Var TransposedMatrix = Matrix.cast & LT; int & gt; ()
                     .Batch (Matrix.getLength (1))
                     .Zipmany ()
                     .Select (xs = & gt; xs.tolist ())
                     .Tolist (); 
Foreach (Var Row in TransposedMatrix)
      {
        Console.WriteLine (String.join (",", Row.Select (E = & GT; E.Tostring ())));
      }
    }
  }
}

The shortest way to transpose matrix – call the zip function for the list of lines. On Python it takes one line:

in [1]: Matrix = [
  ...:   [12],
  ...: [3, 4],
  ...: [5, 6],
  ...: [7, 8],
  ...: [9, 0]
  ...:]
In [2]: Zip (* Matrix)
Out [2]: & lt; zip at 0x7f0b71191448 & gt;
In [3]: List (Zip (* Matrix))
Out [3]: [(1, 3, 5, 7, 9), (2, 4, 6, 8, 0)]

But in the case of C # we are faced with a number of problems:

  1. The initial matrix is ​​represented as a 2D array, and they do not support the line processing, especially through Linq
  2. function zip can only be reduced to two list.

This means that it is time to go somewhat diversify the standard LINQ expansion:

  1. Enter the extension that converts int [, in ienumerable & lt; Ienumerable & lt; int & gt; & gt; . The code is quite simple – an additional function is used, which for each transmitted object IEnumerator & lt; T & GT; counts the desired number of elements. It remains to cause it for the transmitted object Ienumerable & lt; T & GT; until it empties. This code is taken from This answer.
  2. Enter the extension Zipmany , which will be covered with all transmitted listings. The implementation is also sufficiently primitive – each element of each row is associated with its sequence number, and then all these elements are grouped by their sequence numbers. This code is taken from this answer.

It remains only to cause them for our array. Call Cast & Lt; Int & GT; Needed because multidimensional arrays can not work with LINQ directly.


1 : In general, FP on C # looks beautiful. But in this case we had to write a bunch of auxiliary code, due to the fact that the .NET does not provide us with functions. Therefore, in this case, the imperative approach looks better, I’m silent about Bainchmark.


Answer 4, Authority 150%

And you can make parallel (on Threads) option. A little bit the topic, because on C (GNU), but the author’s code in the question corresponds to something -)

# include & lt; pthread.h & gt;
#Include & lt; String.h & gt;
#Define swap (p1, p2) ({typeof (* p1) * _p1 = (p1), * _p2 = (p2), t = * _p1; \
   * _p1 = * _p2; * _p2 = t;})
#Define Memdup (P) (MEMCPY (Malloc (SizeOF (P)), & amp; p, SizeOF (P)))
Struct arg {
 INT * BASE;
 int dim;
 INT ROW;
};
// So in accordance with the PTHreads API, the function must be issued in the stream
void *
TROW (void * a)
{
 STRUCT ARG * PA = (TypeOf (PA)) a;
 int i = pa- & gt; row, j;
 // received a string, we transpine her tail for diagonal
 For (j = i + 1; j & lt; pa- & gt; dim; j ++)
  SWAP (PA- & GT; BASE + PA- & GT; DIM * I + J, PA- & GT; BASE + PA- & GT; DIM * J + I);
 FREE (A);
 Return 0;
}
Void.
PTRANS (INT N, INT A [N] [N] // GCC allows you to transmit matrices in this way
{
 pthread_t tid [n - 1];
 STRUCT ARG ARG = {& AMP; A [0] [0], N, 0};
 // Obviously, the last string from the 1st element can not be touched
 for (arg.row = 0; arg.row & lt; n - 1; arg.row ++)
  pthread_create (TID + ARG.ROW, 0, TROW, MEMDUP (ARG));
 --n;
 While (n--)
  pthread_join (TID [N], 0);
}

If you wish, using macros, it can be easily brought to the template-specified (scalar?) type.


Answer 5, Authority 150%

based on the answer from @vladd, only without excess checks.

First add several auxiliary classes:

interface iaccessor & lt; t & gt;
{
  T THIS [INT I, INT J] {Get; SET; }
}
Class DirectAccessor & LT; T & GT; : Iaccessor & lt; T & GT;
{
  Public DirectAccessor (T [,] PAYLOAD)
  {
    M_PayLoad = payload;
  } 
public T this [int i, int j]
  {
    get {return m_Payload [i, j]; }
    set {m_Payload [i, j] = value; }
  }
  T [,] m_Payload;
}
class TransposedAccessor & lt; T & gt; : IAccessor & lt; T & gt;
{
  public TransposedAccessor (T [,] payload)
  {
    m_Payload = payload;
  }
  public T this [int i, int j]
  {
    get {return m_Payload [j, i]; }
    set {m_Payload [j, i] = value; }
  }
  T [,] m_Payload;
}

And now he is a matrix class:

class Matrix & lt; T & gt;
{
  public Matrix (int n): this (n, n) {}
  public Matrix (int m, int n)
  {
    m_Payload = new T [m, n];
    m_Accessor = new DirectAccessor & lt; T & gt; (m_Payload);
  }
  public T this [int i, int j]
  {
    get {return m_Accessor [i, j]; }
    set {m_Accessor [i, j] = value; }
  }
  public void Transpose ()
  {
    if (m_Accessor is DirectAccessor & lt; T & gt;)
      m_Accessor = new TransposedAccessor & lt; T & gt; (m_Payload);
    ELSE.
      m_Accessor = new DirectAccessor & lt; T & gt; (m_Payload);
  }
  private IAccessor & lt; T & gt; m_Accessor;
  private T [,] m_Payload;
}

And another option class matrix:

class Matrix & lt; T & gt;
{
  public Matrix (int n): this (n, n) {}
  public Matrix (int m, int n)
  {
    var payload = new T [m, n];
    m_ActiveAccessor = new DirectAccessor & lt; T & gt; (payload);
    m_PassiveAccessor = new TransposedAccessor & lt; T & gt; (payload);
  }
  public T this [int i, int j]
  {
    get {return m_ActiveAccessor [i, j]; }
    set {m_ActiveAccessor [i, j] = value; }
  }
  public void Transpose ()
  {
    var tmp = m_ActiveAccessor;
    m_ActiveAccessor = m_PassiveAccessor;
    m_PassiveAccessor = tmp;
  }
  private IAccessor & lt; T & gt; m_ActiveAccessor;
  private IAccessor & lt; T & gt; m_PassiveAccessor;
}

Answer 6, authority 75%

Well, if a little Googling, you can find for example this option:

// in Sharpe, the same function is declared as follows:
 // public static unsafe void transpose (float * src, float * dst, int N, int M)
 void transpose (float * src, float * dst, const int N, const int M) {
  for (int n = 0; n & lt; N * M; n ++) {
    int i = n / N;
    int j = n% N;
    dst [n] = src [M * ​​j + i];
  }
 }

In this example, you first need to align the matrix and then raboat pointers. So we do not move data back and forth, but only pointers. That should give a serious boost in performance.

EDIT:
But experience has shown that such an option requires too much time on mathematical opertsii. As a result, it runs approximately 2 times longer.


Answer 7, authority 50%

Immutabelny option:

var newMatrix = new int [N, N];
for (int i = 0; i & lt; N; i ++)
{
  for (int j = 0; j & lt; N; j ++)
  {
    newMatrix [i, j] = a [j, i];
  }
}
// optional
a = newMatrix;

If a little brush:

static int [,] Transpose (int [,] matrix)
{
  if (matrix.GetUpperBound (0)! = matrix.GetUpperBound (1))
  {
    throw new InvalidOperationException ( "Non-square matrix");
  }
  if (matrix.GetLowerBound (0)! = 0 || matrix.GetLowerBound (1)! = 0)
  {
    throw new InvalidOperationException ( "Non-zero-based matrix");
  }
  int N = matrix.GetUpperBound (0) + 1;
  var newMatrix = new int [N, N];
  for (int i = 0; i & lt; N; i ++)
  {
    for (int j = 0; j & lt; N; j ++)
    {
      newMatrix [i, j] = matrix [j, i];
    }
  }
  return newMatrix;
}
// .....
// call:
a = Transpose (a);

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions