C#矩阵类设计(转置方法)

3
我目前正在用C#实现矩阵。这不是关于如何工作或类似问题的问题。这更多关乎“设计部分”...因此,我想实现一个函数,它可以转置矩阵(http://en.wikipedia.org/wiki/Transpose)。虽然很简单,但对我来说选择最优雅的实现方式真的很困难。
以下是矩阵类的一些代码:
namespace Math
{
    public class Matrix
    {
        protected double[,] matrix;

        public Matrix(byte m, byte n)[...]
        public Matrix(Matrix matrix)[...]

        public byte M { get; private set; }
        public byte N { get; private set; }

        // Possibility 1 (changes the matrix directly)
        public void Transpose()[...]

        // Possibility 2 (getter method)
        public Matrix GetTransposed()[...]

        // Possibility 3 (property)
        public Matrix TransposedMatrix
        {
            get[...]
        }

        // Possibility 4 (static method; a bit like an operator)
        public static Matrix Transpose(Matrix matrix)[...]
    }
}

下面是如何使用不同的选项:

namespace MathTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a new matrix object...
            var mat1 = new Math.Matrix(4, 4);

            // Using possibility 2 (getter method, like "GetHashCode()" or sth. similar)
            var mat2 = mat1.GetTransposed();

            // Using possibility 3 (the transposed matrix is a property of each matrix)
            var mat3 = mat1.TransposedMatrix;

            // Using possibility 4 (definition and use is like an unary operator)
            var mat4 = Math.Matrix.Transpose(mat1);

            // Using possibility 1 (changes the matrix directly)
            mat1.Transpose();
        }
    }
}

你更喜欢哪种方式以及为什么?或者有更好的方法来实现矩阵转置吗?感谢!Benjamin
1个回答

0

我宁愿投票给

  public Matrix Transpose() { ... }

可能性1

在我看来,这种方法是可疑的,因为矩阵似乎是不可变的(所有其他方法都不会改变它)。此外,其他操作(如果您决定实现它们)例如算术运算符+、-、*、/也不会改变初始矩阵,而是返回一个新的矩阵。

   Matrix B = -A; // <- A doesn't changed
   Matrix D = A + B * C; // <- A, B, C don't changed
   Matrix E = F.Transpose(); // <- I hope to have F being intact as well

可能性2

是最好的选择;我宁愿将方法从GetTransposed()重命名为Transpose() - 我们通常使用主动语态的名称 - Perform、Send、Write,而不是GetPerformed、GetSent等。

  // looks better than
  // A.GetPerformed().GetValidated().GetSentTo(@"Me@MyServer.com"); 
  A.Perform().Validate().SendTo(@"Me@MyServer.com"); 

  // The same with transpose:
  // easier to read than
  // A.GetTransposed().GetAppied(x => x * x).GetToString();
  A.Transpose().Apply(x => x * x).ToString();

可能性3
个人而言,我不喜欢它,因为TransposedMatrix不像RowCount、ColCount、IsUnit、IsDegenrate那样是其名称典型意义下的属性。相反,TransposedMatrix看起来非常类似于函数,比如Exp()、Sqrt()...
  A.ColCount; // <- property of the matrix
  A.IsDegenerate; // <- another property of the matrix
  A.ToString(); // <- is not a property: it's conversion (function) into string representation
  A.Sqrt(); // <- is not a property, square root is a function
  A.Transpose(); // <- is not a propery either: it's a function too

可能性4:
在我看来,这听起来不自然。我的想法是:“我有一个矩阵实例A,我想从中得到一个转置矩阵,比如B,所以我应该对A做些什么。”然后我会开始寻找方法:
   B = A.Transpose();
   B = A.ToTransposed();
   B = A.GetTransposed();
   B = A.Rotate(); 
   B = A.Transform(...);
   B = A.DoSomething();

在我看来,静态方法非常适合用于创建。例如:

   A = Math.Matrix.Zero(5); // <- Create 5x5 Matrix, all zeroes
   B = Math.Matrix.Unit(6); // <- 6x6 unit matrix

谢谢 :)!是的,可能性1有点奇怪(和你的论点一样),但我想提及它以完整性。对于可能性3也是如此,因为在我看来,矩阵不能成为另一个矩阵的属性,但有几种其他观点,所以我也在这里提到了它。关于可能性2:好吧,但我会觉得矩阵会直接改变...不知道为什么,但这将是最小的问题;)...您是否也有想法,如果可能性4可以成为“替代方案”(或者我应该同时实现两个:二和四)? - user2656155
可能性4,在我看来有点奇怪——静态方法调用在这里对我来说相当不自然。然而,作为简单的Transpose()方法的补充,这也是可以的。所以,在我看来,可能性2仍然是最好的。 - Dmitry Bychenko
好的,看起来很合理。也许我会实现第四个,但是我肯定会先去做第二个...是的,我也认为,例如获取单位矩阵,并不需要已经有一个,所以我将这个方法设置为静态的。第四种可能性只是在我的脑海中出现,因为自定义运算符定义也被标记为静态,尽管你必须至少拥有该类的一个对象。所以,再次感谢你! - user2656155

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接