Как лучше реализовать двумерную матрицу, в строках которой находятся элементы (точки в многомерном пространстве), а в колонках — соответствующие координаты этих точек.
Особенность состоит в том, что нужна возможность добавлять точки,
и в то же время работать с целыми колонками (имеется ввиду не тип данных, а вся колонка). Чтобы можно было добавить новую координату(и не одну), которая вычисляется из предыдущих по указанному правилу (например, линейная комбинация- x1+0.5*x2+0.2*x4).
Как такое можно в достаточной мере оптимально (по скорости) организовать?
Здравствуйте, serg_stratos, Вы писали:
_>Как лучше реализовать двумерную матрицу, в строках которой находятся элементы (точки в многомерном пространстве), а в колонках — соответствующие координаты этих точек.
_>Особенность состоит в том, что нужна возможность добавлять точки, _>и в то же время работать с целыми колонками (имеется ввиду не тип данных, а вся колонка). Чтобы можно было добавить новую координату(и не одну), которая вычисляется из предыдущих по указанному правилу (например, линейная комбинация- x1+0.5*x2+0.2*x4).
_>Как такое можно в достаточной мере оптимально (по скорости) организовать?
Максимум скорости: линейный массив и адаптеры координат. Примерно так.
К> template<access_mode> struct traits {}; К> template<> struct traits<_ro_> { typedef const matrix matrix_t; typedef double data_t; };
Этот шаблон позволяет не делать const_cast если в функции аргумент-матрица константный?
А можно вопрос расширить. Если задачу придется рассматривать с другой точки зрения. матрицу можно хранить по разному.
Подобная вещь уже была сделана, отчасти. А если теперь хочется отделить представление матриц от того, как они хранятся?
Пока что — только идея объявить интерфейс самой матрицы.
class IMatrix {
size x,y;
myType& operator()(int row,col)
}
class IOperationMatrix{
IMatrix someMatr;
inverse();
другие операции..
}
Но — возникает проблема. От матрицы могут потребоваться специфические операции, которые могут быть удобны для одного случая хранения матрицы, и не так удобны для другого.
Как удобнее может быть объявлять подобные операции (как описанные выше — доступ к колонке или строке)?
Здравствуйте, serg_stratos, Вы писали:
_>Подскажите идею, плз.
_>Как лучше реализовать двумерную матрицу, в строках которой находятся элементы (точки в многомерном пространстве), а в колонках — соответствующие координаты этих точек.
_>Особенность состоит в том, что нужна возможность добавлять точки, _>и в то же время работать с целыми колонками (имеется ввиду не тип данных, а вся колонка). Чтобы можно было добавить новую координату(и не одну), которая вычисляется из предыдущих по указанному правилу (например, линейная комбинация- x1+0.5*x2+0.2*x4).
_>Как такое можно в достаточной мере оптимально (по скорости) организовать?
_>Заранее спасибо, _>Сергей.
IMHO, для колонок (осбенно для зависимых!) можно использовать proxy-объекты, а не хранить зависимые колонки внутри матрицы.
На эту тему очень толково написано в книге "Шаблоны С++", не помню кто автор, появилась совсем недавно.
Примерно в таком духе:
template <class TElement, template <class> class TStorage = TStorageInMemory> class CVector
{
TStorage<TElement> m_Data;
};
И соответствующим образом перегрузить арифметические операторы, присваивание и т.д. Тогда без дополнительных затрат на создание промежуточных массивов можно будет писать так:
CMatrix<double> M;
CVector<double> V = M.Col(1) + M.Col(2)*0.5 + M.Col(4)*0.2;
Здравствуйте, Andy Panda, Вы писали:
AP>Но — возникает проблема. От матрицы могут потребоваться специфические операции, которые могут быть удобны для одного случая хранения матрицы, и не так удобны для другого. AP>Как удобнее может быть объявлять подобные операции (как описанные выше — доступ к колонке или строке)?
или сделать соответствующий шаблонный конструктор копирования для каждого представления матрицы.
В последнем случае — будет даже удобнее, поскольку можно будет написать оптимальные специализации под каждый конкретный случай.
Также может оказаться полезным адаптер
class refmatrix
{
boost::shared_ptr<IMatrix> m_;
public:
// IMatrixconst int xsize() const { return m_->xsize(); }
const int ysize() const { return m_->ysize(); }
double at(int x, int y) const { return m_->at(x,y); }
double& at(int x, int y) { return m_->at(x,y); }
// constructionpublic:
refmatrix(int x, int y) : m_(new default_matrix(x,y)) {}
refmatrix(const IMatrix& m) : m_(new default_matrix(m.xsize(), m.ysize())) { *m_ = m; }
// copy ctor is defaultprivate:
refmatrix(IMatrix* pm) : m_(pm) {}
public:
template<class matrix_type>
static refmatrix make(int x, int y, matrix_type*=NULL) { return refmatrix(new matrix_type(x,y)); }
template<>
static refmatrix make<refmatrix> make(int x, int y, refmatrix*=NULL) { return refmatrix(x,y); }
// assignmentpublic:
refmatrix& operator=(const IMatrix& src) { *m_ = m; }
// copy assign is default
};