В C, если бы я хотел создать матричную структуру, я использовал бы:
struct matrix {
int col, row;
double data[1]; // I want the matrix entries stored
// right after this struct
}
Затем я могу выделить его с
matrix* allocate_matrix(int row, int col) {
matrix* m = malloc(sizeof(matrix) + sizeof(double) * (row * col - 1));
m->row = row; m->col = col;
return m;
}
Теперь я делаю equiv в C++?
Править:
Я хочу знать канонический способ реализовать матричный класс в C++.
load ()
инициирует запрос Ajax для извлечения HTML, который при возврате устанавливается в заданный селектор.
Все функции jQuery Ajax являются просто обертками для $ .ajax ()
так что:
$("#id").load(...);
, вероятно, эквивалентно:
$.ajax({
url: "...",
dataType: "html",
success: function(data) {
$("#id").html(data);
}
});
-121--1236922- Насколько я знаю, в Django ORM нет одношагового способа сделать это.
Но вы можете разделить его на два запроса:
bakeries = Bakery.objects.annotate(
hottest_cake_baked_at=Max('cake__baked_at')
)
hottest_cakes = Cake.objects.filter(
baked_at__in=[b.hottest_cake_baked_at for b in bakeries]
)
Если id's тортов продвигаются вместе с bake_at отметками времени, вы можете упростить и устранить неоднозначность вышеуказанного кода (в случае, если два торта приходят одновременно, вы можете получить оба из них):
hottest_cake_ids = Bakery.objects.annotate(
hottest_cake_id=Max('cake__id')
).values_list('hottest_cake_id', flat=True)
hottest_cakes = Cake.objects.filter(id__in=hottest_cake_ids)
Кредиты BTW за это достаются Дэниелу Розману, который однажды ответил на мой аналогичный вопрос:
Если вышеупомянутый метод слишком медленный, то я знаю и второй метод - вы можете написать пользовательский SQL, производящий только те Торты, которые являются самыми горячими в соответствующих пекарнях, определить его как базу данных VIEW, а затем написать неуправляемую модель Джанго для него. Он также упоминается в приведенном выше потоке django-users. Прямая ссылка на оригинальную концепцию здесь:
Надеюсь, что это поможет.
-121--915337-C++ в основном является супернабором C. Вы можете продолжать делать то, что делали.
При этом в C++ необходимо определить соответствующий класс Matrix, который управляет собственной памятью. Он может, например, поддерживаться внутренним std:: vector
, и можно переопределить оператор []
или оператор ()
для соответствующей индексации в вектор (например, см. Как создать оператор подстрочного индекса для класса Matrix? ) из C++ FAQ.
Начните:
class Matrix
{
public:
Matrix(size_t rows, size_t cols);
double& operator()(size_t i, size_t j);
double operator()(size_t i, size_t j) const;
private:
size_t mRows;
size_t mCols;
std::vector<double> mData;
};
Matrix::Matrix(size_t rows, size_t cols)
: mRows(rows),
mCols(cols),
mData(rows * cols)
{
}
double& Matrix::operator()(size_t i, size_t j)
{
return mData[i * mCols + j];
}
double Matrix::operator()(size_t i, size_t j) const
{
return mData[i * mCols + j];
}
(Обратите внимание, что выше не выполняется проверка границ, и я оставляю это как упражнение для создания шаблона, чтобы он работал для вещей, отличных от двойной
.)
Если вы хотите иметь возможность заполнения нуля, как необязательно, так и високосных секунд:
/^((0?[1-9])|(1[0-2])):[0-5]\d:(([0-5]\d)|(60)) [AP]M$/
Пробой:
(0? [1-9] | 1 [0-2])
1-9 (с опциональным нулем начала) или 10-12
[0-5] [0-9]
00-59 (0-5 для первой цифры, 0-9 для второй)
([0-5] [0-9]) | (60)
високосные секунды
[AP] M
AM/PM
Вот исходный код функции load
: http://github.com/jquery/jquery/blob/master/src/ajax.js#L15
Как вы видите, это $ ajax
с некоторыми функциями обработки. Другими словами, удобный способ.
Существует множество тонкостей в настройке эффективного и качественного класса матрицы. К счастью, существует несколько хороших реализаций.
Подумайте над тем, хотите ли вы класс матрицы фиксированного размера или класс переменной размера. то есть вы можете сделать это:
// These tend to be fast and allocated on the stack.
matrix<3,3> M;
или вы должны иметь возможность сделать это
// These are slower but more flexible and partially allocated on the heap
matrix M(3,3);
Есть хорошие библиотеки, которые поддерживают любой стиль, и некоторые, которые поддерживают оба. Они имеют разные узоры распределения и различные действия.
Если вы хотите кодировать его самостоятельно, то версия шаблона требует определенных знаний о шаблонах (duh). И динамичному нужно несколько взломов, чтобы обойти много небольших распределений, если используется внутри плотных петель.
Вы могут сделать это таким образом Отказ Единственное отличие заключается в том, что вам нужно будет отличить результат из Malloc
.
Скорее, вы будете использовать вектор
, либо в качестве 1D массива с вычисленной индексацией или встроенным вектором. (Первые соответствует вашему коду лучше.)
Например:
template <typename T> // often, they are templates
struct matrix
{
// should probably be hidden away, and the class would
// provide `at` and `operator()` for access
int col, row;
std::vector<T> data;
matrix(int columns, int rows) :
col(columns), row(rows),
data(col * row)
{}
}
matrix m(4, 4);
m.data[1 + 1 * 4] = /* ... */;
или:
template <typename T>
struct matrix
{
int col, row;
std::vector<std::vector<T> > data;
matrix(int columns, int rows) :
col(columns), row(rows),
data(col, std::vector(row))
{}
}
matrix m(4, 4);
m.data[1][1] = /* ... */;
Но это только примеры. Вы бы хотели сделать полноценный класс; Если вы хотите больше советов по этому вопросу, отредактируйте свой вопрос и уточните, вы хотите знать канонический способ реализации матричных классов.
Есть ранее существующие классы матрицы. Мой любимый состоит в том, что от Boost, UBLAS .
Вы можете использовать шаблон, например:
#include <iostream>
using std::cerr;
using std::endl;
//qt4type
typedef unsigned int quint32;
template <typename T>
void deletep(T &) {}
template <typename T>
void deletep(T* & ptr) {
delete ptr;
ptr = 0;
}
template<typename T>
class Matrix {
public:
typedef T value_type;
Matrix() : _cols(0), _rows(0), _data(new T[0]), auto_delete(true) {};
Matrix(quint32 rows, quint32 cols, bool auto_del = true);
bool exists(quint32 row, quint32 col) const;
T & operator()(quint32 row, quint32 col);
T operator()(quint32 row, quint32 col) const;
virtual ~Matrix();
int size() const { return _rows * _cols; }
int rows() const { return _rows; }
int cols() const { return _cols; }
private:
Matrix(const Matrix &);
quint32 _rows, _cols;
mutable T * _data;
const bool auto_delete;
};
template<typename T>
Matrix<T>::Matrix(quint32 rows, quint32 cols, bool auto_del) : _rows(rows), _cols(cols), auto_delete(auto_del) {
_data = new T[rows * cols];
}
template<typename T>
inline T & Matrix<T>::operator()(quint32 row, quint32 col) {
return _data[_cols * row + col];
}
template<typename T>
inline T Matrix<T>::operator()(quint32 row, quint32 col) const {
return _data[_cols * row + col];
}
template<typename T>
bool Matrix<T>::exists(quint32 row, quint32 col) const {
return (row < _rows && col < _cols);
}
template<typename T>
Matrix<T>::~Matrix() {
if(auto_delete){
for(int i = 0, c = size(); i < c; ++i){
//will do nothing if T isn't a pointer
deletep(_data[i]);
}
}
delete [] _data;
}
int main() {
Matrix< int > m(10,10);
quint32 i = 0;
for(int x = 0; x < 10; ++x) {
for(int y = 0; y < 10; ++y, ++i) {
m(x, y) = i;
}
}
for(int x = 0; x < 10; ++x) {
for(int y = 0; y < 10; ++y) {
cerr << "@(" << x << ", " << y << ") : " << m(x,y) << endl;
}
}
}
* Редактировать, исправить опечатку.
В C ++ вы можете использовать следующим образом:
matrix *p = new matrix;
после этого
delete p;
Вы можете сделать это с шаблоном, если размер матрицы известен при компиляции времени:
template <int width, int height>
class Matrix{
double data[height][width];
//...member functions
};
Для класса Matrix вы хотите держаться подальше от перегрузки оператора []
.
См. FAQ C ++ FAQ 13.10
Кроме того, поиск в Интернете для некоторых классов Matrix Freeware. Худший случай, они могут дать вам руководство. Лучший случай, меньше программного обеспечения, которое вы должны написать и отладку .
Этот ответ сейчас имеет 20 голосов, но он не предназначен для одобрения std::valarray
.
По моему опыту, время лучше потратить на установку и обучение использованию полноценной математической библиотеки, такой как Eigen. Valarray обладает меньшим количеством функций, чем у конкурентов, но он не является более эффективным или особенно простым в использовании.
Если вам нужно только немного линейной алгебры, и вы не хотите ничего добавлять в вашу цепочку инструментов, тогда, возможно, подойдет valarray
. Но застрять в неспособности выразить математически правильное решение вашей проблемы - это очень плохая позиция. Математика неумолима и неумолима. Используйте правильный инструмент для работы.
Стандартная библиотека предоставляет std::valarray
. std::vector<>
, предложенная здесь некоторыми другими, предназначена в качестве контейнера общего назначения для объектов. valarray
, менее известный, поскольку более специализированный (не использующий в качестве термина С++ термин "специализированный"), имеет несколько преимуществ:
вектор
округляется до ближайшей силы двойки при выделении, так что вы можете изменять его размер без перераспределения каждый раз. (Вы все еще можете изменить размер валаррея Valarray
; он все еще так же дорог, как realloc()
.)Конечно, преимущество перед использованием C заключается в том, что Вам не нужно управлять памятью. Размеры могут находиться в стеке или в фрагменте объекта.
std::valarray<double> matrix( row * col ); // no more, no less, than a matrix
matrix[ std::slice( 2, col, row ) ] = pi; // set third column to pi
matrix[ std::slice( 3*row, row, 1 ) ] = e; // set fourth row to e