Как стать автором
Обновить
14
0
Павел Прилуков @1ntr0

Пользователь

Отправить сообщение
При попытке использовать арифметические операции на параметризованном типе компилятор будет ругаться. Да и ни к чему это здесь. Серьёзно. Ценой производительности и удобства использования можно сделать всё, что угодно. Но всегда нужно исходить из имеющихся требований к разработке. Требования приведены в начале статьи.
Есть методы, сходимость которых обеспечивается высокой точностью вычислений. Поэтому Extended. При необходимости ускорить вычисления ценой потери точности, можно вызвать функцию Math.SetPrecision().
Альтернативы типу Extended для себя не вижу. Для моих задач важно при отладке видеть элементы «как есть», в численном представлении. С вещественными числами работать удобно.
Конструктор использовал для наглядности — мы же «класс» проектируем :)
Во-первых, шаблоны — штука полезная, но в Delphi их нет. Есть дженерики, а это совсем другая история. И в 21-ом веке пора бы их отличать. Дело в том, что над дженериками не определены арифметические операции, значит, вычислять на них нельзя.
Второй момент, матрицы — это не контейнеры, а математические объекты. Совсем разные понятия, лежащие в разных предметных областях. Контейнеры предназначены для хранения, для них определен стандартный интерфейс, куда должны входить методы «Добавить элемент» и «Удалить элемент». А матрицы применяются для решения систем уравнений и при рассмотрении линейных преобразований. Матрица — это частный случай тензора, а не контейнера.
Потери на контроле диапазонов вообще незаметны на фоне динамического выделения памяти процедурой SetLength(), которая действительно приводит к некоторому замедлению. Это плата за универсальность, за возможность работать с матрицами произвольных размеров. Альтернативой может быть размещение элементов в статическом массиве с наперед заданными границами, взятыми с большим запасом. Основной минус такого подхода — очень неудобно смотреть в отладчике на массивы 20х20, состоящие почти из одних нулей.
Здорово придумано! Спасибо.
При вызове Memoize происходит создание экземпляра TCache
Cache := TCache<Integer, Double>.Create;

Память выделяется, но где и когда ее освобождать? Обертка в интерфейс и объявление
Cache: ICache

позволяет организовать автоматический подсчет ссылок на экземпляр и автоматическое освобождение памяти из-под него, когда счетчик достигает нуля. Это происходит, когда Memoize выходит из области видимости.
Вычисление Mean & StdDev приводятся для примера, а именно: использование внешней свободной функции в качестве аргумента Reduce; связь контекста вызывающего кода MeanAndStdDev и вызываемого анонимного метода Map; каскадной цепочки вызовов «Data..Map..Reduce».
Разумеется, всего лаконичнее смотрится вариант использования библиотечной функции Math.MeanAndStdDev ;)
Языки C#, JavaScript, Java имеют свой синтаксис и возможности, однако статья про Delphi, где нет подобных «стандартных функций для обработки коллекций».
Может и проще, но у ForEach концепция не-функции, и поступать так я бы не стал :)
Это потребует дополнительного параметра в заголовке и дополнительной проверки if при проходе списка элементов, но идея, конечно, годная. Более красивое решение, чем try\except :)

Информация

В рейтинге
Не участвует
Откуда
Екатеринбург, Свердловская обл., Россия
Зарегистрирован
Активность