Изображение квадрата Дюрера

ООО АВТОМАТИКА плюс

Rambler's Top100

Рейтинг@Mail.ru

Справочная система




Структура ядра

Основу ядра Matrix составляет класс TWorkspace (Workspace - рабочая область). Помимо того, что в рабочей области хранятся все массивы, класс TWorkspace дает программисту свойства и методы, достаточные для программирования любого вычислительного алгоритма. Сразу после подключения к приложению модуля Matrix программисту доступен объект Base, имеющий тип TWorkspace. Это постоянная рабочая область, которая создается и уничтожается автоматически без вмешательства программиста. Программист может создавать как временные, так и постоянные рабочие области и он должен сам заботится об их уничтожении. Для создания рабочей области служит конструктор Create(), а для уничтожения - метод Free(). В случае возникновения ошибки происходит каскадное удаление временных рабочих областей, при этом постоянные рабочие области (например, Base) остаются нетронутыми (здесь мы видим полную аналогию с рабочими областями системы Matlab - там есть постоянная рабочая область Base, и она никогда не разрушается при возникновении ошибок).

В модуле Matrix.pas, который собственно и является ядром системы, реализовано огромное количество различных функций. Они описываются в разделе "Функции ядра MatriX". Здесь отметим некоторые вещи, о которых программисту будет полезно узнать (правда, весь модуль хорошо документирован, и лучше все увидеть своими глазами).

Итак, класс TWorkspace работает со следующими полями:

  • FArrayList: TMatrixList - это список ссылок на массивы конкретной рабочей области. В этом списке находятся такие сведения, как адрес массива, его размеры и имя. Собственно, обращение к массивам происходит в основном в помощью имен, которые имеют строковый тип String и имеют длину, не превышающую 32 символа. Обращение к массивам по именам очень наглядно и значительно улучшает читабельность кода. Кроме того, к массиву можно обратиться по его индексу, но эту возможность целесообразно применять только при осуществлении доступа к конкретным элементам массива (способам доступа к элементам массива посвящен целый раздел).
  • FRefList: TList - список индексов массивов, переданных в данную рабочую область по ссылке ("данной рабочей областью" я называю любой созданный объект, имеющий класс TWorkspace). Основным способом передачи массивов в подпрограмму является передача по ссылке. При этом массив, переданный по ссылке должен использоваться исключительно для чтения. Индексы передаваемых по ссылке массивов запоминаются в списке FRefList, что исключает уничтожение таких массивов в подпрограмме.
  • FWorkspaceList: TList - список ссылок на дочерние рабочие области. Любая рабочая область может иметь неограниченное количество дочерных рабочих областей. В итоге может выстроиться иерархия рабочих областей в виде дерева. Такая иерархия позволяет реализовать механизм каскадного удаления всех дочерных рабочих областей, что существенно облегчает осуществление контроля за использованием памяти. Кроме того, данная технология гарантирует полное отсутствие утечки памяти. Это означает, что приложения, использующие Matrix, могут сутками работать, и ни один байт оперативной памяти за это не пропадет. Также механизм каскадного удаления действует в случае генерации исключительных ситуаций (они генерируются с помощью функции DoError()).
  • FParentWorkspace: TWorkspace - ссылка на родительскую рабочую область. Все рабочие области можно разделить на постоянные и временные. Постоянные рабочие области не имеют родителя, поэтому у них FParentWorkspace = nil. Временные рабочие области имеют родителя, поэтому они еще называются дочерними. Механизм каскадного удаления действует только для временных рабочих областей.
  • FUniqueNameCounter: Int64 - счетчик уникальных имен. Многие функции ядра Matrix используют массивы с уникальными именами для выполнения различных вычислений. Необходимость использования уникальных имен объясняется на простейшем примере. Допустим, наша функция выполняет операцию транспонирования и имеет на входе массив А. На выходе может быть массив с любым именем, в том числе массив с именем А. Понятно, что входной массив А невозможно транспонировать в выходной массив с тем же именем. На помощь приходят массивы с уникальным именем. В нашем случае мы должны создать массив с уникальным именем, выполнить операцию транспонирования, а затем просто переименовать этот массив, то есть присвоить ему имя А.
  • FElemCount: Integer - количество элементов в данной рабочей области. Вы в любой момент можете узнать, сколько памяти занимает ваша рабочая область с помощью функции GetElemCount(). При расчете значения FElemCount переданные по ссылке массивы не учитываются.
  • FName: string - имя рабочей области. Оно используется в основном только для вывода сообщений об ошибках.
  • FSelf: TWorkspace - хранит ссылку на данную рабочую область. В любом созданном объекте уже есть переменная Self, однако в нашем случае пользоваться ей крайне неудобно, т.к. при вызове внешних подпрограмм приходится каждый раз выполнять приведение типов следующим образом: TWorkspace(Self). Вместо этого вы можете воспользоваться свойством SelfWS.
  • FMStream: TMemoryStream - объект-поток. Используется в основном для работы с файлами. Объявление FMStream как поля класса позволяет избежать утечек памяти в случае возникновения исключения при обработке файла. Этот объект создается только при необходимости, а не в конструкторе, что позволяет ускорить процесс создания рабочей области.

Также отмечу, что в модуле Matrix.pas объявлено множество текстовых констант, используемых при выводе сообщений об ошибках. Благодаря этому приложения, использующие MatriX, легко локализуются на других языках.

И последнее: вместо функций FloatToStr() и StrToFloat() используйте функции FloatToStrExp(), FloatToStrGen(), AnyStrToFloat() - вы избежите проблем, связанных с использованием различных разделителей в региональных настройках.

Логинов Дмитрий © 2005-2015