Статическая типизация и написание библиотеки простых матриц - PullRequest
2 голосов
/ 05 июня 2010

Да, это было сделано миллион раз прежде, но, черт возьми, я хочу сделать это снова. Я пишу простую матричную библиотеку для C ++ с намерением сделать это правильно . Я столкнулся с чем-то, что довольно очевидно в математике, но не так очевидно для строго типизированной системы - факт, что матрица 1x1 - это просто число. Чтобы избежать этого, я начал ходить по волосистой дорожке матриц в виде композиции векторов, но также наткнулся на тот факт, что два вектора, умноженные вместе, могут быть числом или диадой, в зависимости от ориентации двух.

У меня такой вопрос: как правильный способ справиться с этой ситуацией в строго типизированном языке, таком как C ++ или Java?

Ответы [ 3 ]

3 голосов
/ 05 июня 2010

то, что довольно очевидно в математика, но не так очевидно для строго типизированная система - тот факт, что матрица 1x1 - это просто число.

Это спорно. Хардкорный математик (я не), вероятно, поспорил бы с этим, он сказал бы, что матрица 1x1 может рассматриваться как изоморфная (или что-то в этом роде) скаляру, но это концептуально разные вещи. Только в некотором неформальном смысле «матрица 1x1 является скаляром» (похоже, хотя и сильнее, что комплексное число без мнимой части «является действительным»).

Я не думаю, что эта переписка должна отражаться на строго типизированном языке. И я не думаю, что это так, в типичных реализациях (сложных или матричных), например. Java Apache Commons Math . Например, комплекс с нулевой мнимой частью не является числом (из типа POV - они не могут быть преобразованы друг в друга).

В случае матриц, соответствие еще более спорным. Должны ли мы быть в состоянии умножить две матрицы размеров (4x3) x (1x1)? Если мы рассматриваем второй как скаляр, он действителен, но не как матрица, поскольку он нарушает ограничение на размеры матрицы для умножения. И я верю, что Commons придерживается этого.

На слабо типизированном языке (например, Matlab) это будет другая история .

2 голосов
/ 05 июня 2010

Если вас не беспокоит оптимизация SIMD и тому подобное, я бы подумал, что лучшим способом будет настроить шаблонный тензор . Выберите свои максимальные тензорные размеры, и тогда вы сможете делать такие вещи:

typedef Tensor3D< float, 4, 1, 1 > Vector4;

И так далее. Математика, если она реализована правильно, будет работать только со всеми формами «матрица» и «вектор». В конце концов, оба являются частными случаями тензоров.

Редактировать: узнать размер шаблона на самом деле довольно просто. Добавьте функцию GetRows () и т. Д., И вы можете вернуть значение, переданное в шаблон при создании экземпляра.

е

template< typename T, int rows, int cols > class Tensor2D
{
public:
    int GetRows() { return rows; }
    int GetCols() { return cols; }
};
0 голосов
/ 05 июня 2010

Мой совет? Не беспокойтесь о случае 1x1 и спите ночью. Вы не должны беспокоиться о каких-либо случаях, когда вдруг решите использовать вашу библиотеку для моделирования набора чисел как матрицы 1x1 и жаловаться на вашу реализацию.

Никто, кто решает эти проблемы, не будет таким глупым. Если вы достаточно умны, чтобы использовать матриц, вы достаточно умны, чтобы правильно их использовать.

Что касается всех перестановок, которые вводят скаляры, я бы сказал, что вы должны их учитывать. Как пользователь библиотеки матриц, я ожидал бы, что смогу умножить две матрицы вместе, чтобы получить другую матрицу, матрицу на вектор (столбец или строку), получить векторный результат, и скалярное умножение матрицы на другую матрицу.

Если я умножу два вектора, я получу скаляр (внутреннее произведение) или матрицу (внешнее произведение). Твоя библиотека лучше отдай их мне.

Это не тривиально. Это было сделано "правильно" другими, но слава тому, чтобы проработать это для себя.

...