设计矩阵类并执行功能以更改表示形式 [英] Designing a matrix class and perform function to change the representation

查看:78
本文介绍了设计矩阵类并执行功能以更改表示形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在开发C ++程序,但难以理解如何解决它.

我必须设计一个Matrix类,该类将具有用于计算元素数量的公共操作,以及一种在不丢失数据的情况下更改矩阵表示形式的方法.这部分我最困惑.内部表示可以像一维或二维数组或矩阵中非零元素的链表.

感谢任何帮助!

Hi,

I am working on a C++ program and having difficulty understanding how to go about solving it.

I have to design a Matrix class that would have the public operations to count the number of elements, and a method to change the representation of the matrix without losing the data. This part I am most confused about. The internal representation can be like a 1-D or 2-D array or a linked list of non-zero elements in the matrix.

Appreciate any help!

推荐答案

请参阅我对问题的评论.

我不认为我们应该谈论改变矩阵的内部表示.我希望我们正在谈论该类的一些实用设计.从这个角度来看,该类应具有固定的内部表示形式(例如1-D数组或元素的链接列表),但应在公开的公共属性级别上公开几个替代表示形式.例如,由12个元素组成的一维数组可以在外部以矩阵1x12、12x1、2x6、6x2、3x4或4x3表示,而无需更改每个元素的值.

我必须注意,对于大多数典型的矩阵运算,链表毫无意义. (插入或删除矩阵元素是非常不寻常的;但这是一个链接列表很好的地方.)

通过通过[]运算符的定义来定义索引访问属性,可以最好地实现此功能.请参阅:
http://www.cplusplus.com/doc/tutorial/classes2/ [ http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html [ ^ ],
http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading [^ ].

—SA
Please see my comment to the question.

I don''t think we should talk about changing internal representation of the matrix. I hope we are talking about some practically sensible design of the class. From this standpoint, the class should have on fixed internal representation (such as 1-D array or a linked list of elements), but exposing several alternative representations at the level of exposed public properties. For example, the 1-D array of 12 elements could be presented externally as a matrix 1x12, 12x1, 2x6, 6x2, 3x4 or 4x3, without changing the value of each element.

I must note that for most typical matrix operations linked list makes no sense. (It''s very unusual that element of matrix should be inserted or removed; but this is where a linked list is good.)

This functionality is best implemented through the definition of indexed access property through [] definition of operator. Please see:
http://www.cplusplus.com/doc/tutorial/classes2/[^],
http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html[^],
http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading[^].

—SA


class Matrix2D {
   // the matrix elements for a 2x2 matrix
   double values[2][2];
public:
   // access operator to read a matrix element
   double operator()(unsigned int row, unsigned int column) const {
      if (row < 2 && column < 2)
         return values[row][column];
      //Todo: generate some error message or throw an exception
      return 0.;
   }
   // gets a reference to write to a matrix element
   double & operator()(unsigned int row, unsigned int column) {
      if (row < 2 && column < 2)
         return values[row][column];
      //Todo: generate some error message or throw an exception
      return 0.;
   }
};


矩阵元素的内部表示是


The internal representation of the matrix elements is

double values[2][2];


现在,更改表示形式意味着什么?这是代码的一部分,您无法在运行时更改它.您可以在开发程序时进行更改,例如G.到


Now, what do you mean by change the representation? This is part of your code, you can not change it at run time. You can change it while you develop the program, e. g. to

double values[2*2];


但是,如果这样做,则该类的其余部分将不再编译!您还必须修复功能的实现:


But if you do that, the remainder of your class will no longer compile! You''d have to fix the impementation of your functions too:

double operator()(unsigned int row, unsigned int column) const {
   if (row < 2 && column < 2)
      return values[(row-1)*2+column];
   //Todo: generate some error message or throw an exception
   return 0.;
}
// gets a reference to write to a matrix element
double & operator()(unsigned int row, unsigned int column) {
   if (row < 2 && column < 2)
      return values[(row-1)*2+column];
   //Todo: generate some error message or throw an exception
   return 0.;
}


更改内部表示形式是在处理代码时而不是在运行时执行的操作.并且当您这样做时,需要确保您的函数实现仍按预期工作.

您可以 进行的操作是将类的实例转换为其他等效的对象.例如如果您有一个描述3D旋转的矩阵,则可以将其转换为Quaternion类的对象,该对象可以将相同的旋转仅存储4个值,而不是9个值.但是,这不是更改内部表示的情况,而是创建了另一个等效的新对象.是你想要的吗?

转换为其他课程
我将举一个简单的例子,尽管它不会那么有用.我还将减少辅助代码,例如上面的索引检查,以使其简短.我要做的是将每个类的函数Matrix2DVector4D添加到可用于转换的函数:


Changing the internal representation is something you do while working on your code, not at runtime. And when you do, you need to make sure your function implementations still work as intended.

What you can do is convert an instance of your class to some other, equivalent, object. E. g. if you have a matrix describing some rotation in 3D, you could convert it to an object of class Quaternion, which can store the same rotation in just 4, instead of 9 values. That is not a case of changing the internal representation though, you create a new object of another class that is equivalent. Is it that what you want?

Converting to another class
I''ll give an easy example although it''s not going to be all that useful. I''ll also cut down on auxiliary code such as the index checking above, to keep it short. What I''ll do is add to functions to each class, Matrix2D and Vector4D that can be used for conversion:

// forward declaration to make the code compile
class Vector4D; // class definition below...

class Matrix2D {
   double values[2][2];
public:
   // default constructor
   Matrix2D() {}
   // conversion constructor
   Matrix2D(const Vector4D& v) {
      values[0][0] = v[0];
      values[0][1] = v[1];
      values[1][0] = v[2];
      values[1][1] = v[3];
   }
   // conversion operator
   operator Vector4D() const {
      return *this; // invokes the conversion constructor from Vector4D
   }
   // read matrix elements operator
   double operator()(unsigned int row, unsigned int column) const {
      return values[row][column];
   }
   // assignment operator
   Matrix2D& operator=(const Matrix2D& m) {
      values[0][0] = m.values[0][0];
      values[0][1] = m.values[0][1];
      values[1][0] = m.values[1][0];
      values[1][1] = m.values[1][1];
      return *this;
   }
};
class Vector4D {
   double values[4];
public:
   // default constructor
   Vector4D() {}
   // conversion constructor
   Vector4D(const Matrix4D& m) {
      values[0] = m(0,0);
      values[1] = m(0,1);
      values[2] = m(1,0);
      values[3] = m(1,1);
   }
   // conversion operator
   operator Matrix2D() const {
      return *this; invokes the conversion constructor from Matrix2D
   }
   // read vector elements operator
   double operator[](unsigned int index) const {
      return values[index];
   }
};   


现在,您可以随意创建一个类的实例,然后将它们转换为另一种类型:


Now you can create instances of one class and convert them to the other type and back, at your leisure:

void foo() {
   Matrix2D m1; // creates first instance of Matrix2D
   Vector4D v1(m1); // creates first instance of Vector4D by converting m1
   Matrix m2;
   m2 = (Matrix2D)v1; // calls conversion operator of Vector4D, then assignment operator of Matrix2D
}


这篇关于设计矩阵类并执行功能以更改表示形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆