Изложенное далее будет касаться матриц взаимодействия. Эта категория описывает, каким образом взаимодействуют между собой зоны сложного дефекта для пары представлений сверхструктуры. Столбец ненулевого значения в матрице - это номер одного представления. Соответственно, строка задаёт номер другого. В зависимости от знака значения матрицы взаимодействующая пара зон складывается или вычитается из общего набора.

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

Хотелось бы коснуться варианта представления матрицы в виде списка данных listSetValue, структура которого представлена далее по тексту. Все алгоритмы при таком определении сильно упрощаются относительно таковых при описании матриц массивами. Сделаем выбор в сторону простоты алгоритма, может быть, в ущерб эффективности.

Рассмотрим типовые алгоритмы проекта. Ранее мы указали на равноценность способов описания функциональной зависимости. Если существует возможность представить порядок действий над данными из области определения с последующей записью данных в область значения, то результат действия алгоритма не отличается от использования функции в её аналитическом представлении. Начнем с рассмотрения алгоритма получения результирующей матрицы нахождения энергии сложного дефекта

Блок-схема алгоритма R

оперирует над данными, экземпляр которых описывается структурой со следующими полями:

struct setValue
{
    int c1; //----- номер первого представления сверхструктуры
    int c2; //----- номер второго представления сверхструктуры
    int a1; //----- номер зоны, равный столбцу матрицы взаимодействия
    int a2; //----- номер зоны, равный строке матрицы взаимодействия
    int value; //-- значение взаимодействия
};
						

Первоначальный сложный дефект - это не отсутствие дефекта, а именно плоскость, разделяющая полупространства с двумя представлениями сверхструктуры. Стоит отметить, что планарному дефекту, из которого путём простых операций мы будем получать более продвинутые компоненты, также соответствуют матрицы прямого и обратного законов. Их можно получить, если проделать процедуру нахождения результирующей матрицы над начальной конфигурацией.

Конфигурация:

$$Conf = \langle1,2\rangle$$

использующая набор представлений

$$\{1,2\}.$$

$$D^{a} = \begin{pmatrix} 0 & 0 \\ 1 & 0 \end{pmatrix}$$

$$D^{-a} = \begin{pmatrix} 0 & 1 \\ 0 & 0 \end{pmatrix}$$

$$D^{A} = D^{a} + (D^{-a})^{T} = \begin{pmatrix} 0 & 0 \\ 2 & 0 \end{pmatrix}$$

Результатом действия алгоритма будут матрицы взаимодействия для вычисления энергии планарного дефекта. Произвольную результирующую матрицу можно взять, если отдать алгоритму конфигурацию из единиц и двоек у нужных нам зон дефекта.

Алгоритм G

Данный алгоритм строит новую матрицу взаимодействия, взяв за основу текущую.

void G(const QString strG)
{

    QStringList strl = strG.split(' ');


//======= columns ===
    QVector < setValue >  vecCol;
    for (int i = 0; i < listSetValue.size(); i++) for (int j = 0; j < strl.size(); j++) {
         if (listSetValue[i].col == strl.at(j).toInt()) vecCol.push_back({listSetValue[i].c1,listSetValue[i].c2,j + 1,listSetValue[i].row,listSetValue[i].value});
    }
//======= rows ======
    QVector < setValue > result;
    for (int i = 0; i < vecCol.size(); i++) for (int j = 0; j < strl.size(); j++) {
        if (vecCol[i].row == strl.at(j).toInt()) result.push_back({vecCol[i].c1,vecCol[i].c2,vecCol[i].col,j+1,vecCol[i].value});
    }

    listSetValue.clear();
    listSetValue = result;
}

На входе алгоритм запрашивает строку генерации strG. Строка генерации управляет процессом модификации исходного списка listSetValue. На выходе алгоритм отдаёт новый список сэтов.

Строка генерации

Задаёт предыдущему алгоритму G протокол модификации. Парсер преобразует входные строковые данные в массив битов для последующего анализа и формирования strG:

QVector  < QBitArray > prs(QString text)
{
    QStringList lstAr = text.split("\\\\");
    int areaCount = lstAr.size();
    QStringList lstPl = lstAr.at(0).split("&");
    int planeCount = lstPl.size();

    QVector < QBitArray > vecr;

    for (int i = 0; i < areaCount; i++) {
        lstPl = lstAr.at(i).split("&");
        QBitArray ba;
        ba.resize(planeCount);
        for (int j = 0; j < planeCount; j++) {
            QString str = lstPl.at(j);
            str = str.trimmed();
            if (str == "+") ba[j] = true;
            }
        vecr.push_back(ba);
    }
    return vecr;
}


QString MainWindow::generate(QString txtMonitored,QString txtSupport,QString txtCommand)
{
    QString str = "";
    QVector < QBitArray > monitored = prs(txtMonitored);
    QVector < QBitArray > support = prs(txtSupport);
    QHash < QBitArray,int > hash;
    for (int i = 0; i < support.size(); i++) hash.insert(support[i],i);
    QVector < QBitArray > command = prs(txtCommand,monitored);

    QString forward = "";//---------- FORWARD ----------


    for (int i = 0; i < monitored.size(); i++) {
        int pos = hash.value(command[i]);
        forward += QString::number(pos+1) + " ";
    }
    forward.remove(forward.length()-1,1);
}

$$strG = generate(txtMonitored, txtSupport, txtCommand)$$

В сигнатуре функции присутствуют три текстовых параметра, которые подлежат парсингу в теле generate. Типичный пример txtMonitored:

- & - & - & - & - & - & - & - \\\
+ & - & - & - & - & - & - & - \\\
- & + & - & - & - & - & - & - \\\
+ & + & - & - & - & - & - & - \\\
- & + & + & - & - & - & - & - \\\
+ & + & + & - & - & - & - & - \\\
- & + & + & + & - & - & - & - \\\
+ & + & + & + & - & - & - & - \\\
- & + & + & + & + & - & - & - \\\
+ & + & + & + & + & - & - & - \\\
- & + & + & + & + & + & - & - \\\
+ & + & + & + & + & + & - & - \\\
- & + & + & + & + & + & + & - \\\
+ & + & + & + & + & + & + & - \\\
- & + & + & + & + & + & + & + \\\
+ & + & + & + & + & + & + & +

Такой текст, к примеру, определяет шестнадцать зон, как результат пересечения восьми плоскостей, которые и будут мониторить. Параметр txtSupport с аналогичной транскрипцией задаст опорные зоны, например тремя плоскостями. Терминатором строк является обратный двойной слеш. Напротив, терминатором элементов в строке будет амперсанд. Положительное или отрицательное полупространства плоскости обозначены соответствующим арифметическим знаком. Номер плоскости равен его позиции. Наконец:

txtCommand = "4\\\5\\\8"

укажет алгоритму номера плоскостей для мониторинга, при этом позиция номера соответствует опорной плоскости. Терминатором номеров плоскостей в командной строке также является обратный двойной слеш.

Алгоритм L

Алгоритм формирует матрицу взаимодействия для левой части дефекта в том случае, если введение дополнительной плоскости приводит к удвоению числа зон. Опишем алгоритм в виде последовательных действий над текущей матрицей M.

  1. 1. В качестве исходной рассматривается текущая матрица взаимодействия M дефекта до введения плоскости.
  2. 2. Определяется нулевая матрица O такого же размера.
  3. 3. Генерируется матрица левой части дефекта после удвоения зон дополнительной плоскостью:
  4. $$L = \begin{pmatrix} M & O \\ M & O \end{pmatrix}$$
  5. 4. Данный алгоритм повторяется у матриц для всех законов взаимодействия текущего компонента.

Повторим, что размер матриц взаимодействия после проделанной операции удваивается.

Законы взаимодействия

Типовые алгоритмы были рассмотрены на примере сверхструктуры с двумя представлениями. В таком случае понятие закона взаимодействия присутствует номинально, как бы в скрытой форме. Существует матрица взаимодействия, для которой меньшее представление относится к столбцам, большее к зонам, соотносимым со строками. Это так называемая прямая матрица. Правомерна запись матрицы, для которой большее представление сопоставлено столбцам, а меньшее строкам. В этом случае матрицу назовём обратной. Понятие законов взаимодействия, упомянутых ранее, становится актуальным в случае сложного дефекта, порождённого более чем двумя представлениями сверхструктуры. Тогда пар представлений становится больше, чем одна, а все возможные их комбинации и называются законами взаимодействия.

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

Нахождение матриц взаимодействия произвольного компонента

Рассмотрим пример расчёта матриц взаимодействия для компонента, соответствующего линии пересечения двух плоскостей подробнее. На рисунке компонент выделен красным. Плоскости, нормали которых параллельны соответственно осям X и Y, разобьют трёхмерное евклидово пространство на четыре зоны. Приведём этапы нахождение матриц.

Вначале отыщем матрицы для полуплоскости с нормалью, параллельной оси X. Обозначим данный компонент D1. Очевидно, что это левая часть исходного компонента D, рассмотренного выше. Алгоритм L применительно к D даст следующие матрицы:

$$D^{a}_{1} = \begin{pmatrix} 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \end{pmatrix}$$

$$D^{-a}_{1} = \begin{pmatrix} 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{pmatrix}$$

Далее отыщем матрицы для полуплоскости с нормалью, параллельной оси Y. Обозначим данный компонент D2. Его найдём из D1 при помощи алгоритма G. Достаточно отразить дефект так, чтобы плоскости поменялись местами. txtMonitored и txtSupport в этом случае совпадают и равны:

- & - \\\
+ & - \\\
- & + \\\
+ & +

txtCommand = "2\\\1" и с такими вводными алгоритм generate выдаёт strG = "1 3 2 4". Она меняет вторую строку с третьей местами у матрицы размера четыре на четыре. Таким же образом меняются и столбцы. После действия strG на матрицы D1 алгоритм G выдаст:

$$D^{a}_{2} = \begin{pmatrix} 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \end{pmatrix}$$

$$D^{-a}_{2} = \begin{pmatrix} 0 & 0 & 1 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{pmatrix}$$

Теперь находим результирующую матрицу, подставив строку конфигурации данного сложного дефекта, а она:

$$Conf = \langle1,2,2,2\rangle$$

в алгоритм нахождения результирующих матриц. Тогда:

$$R^{a} = \begin{pmatrix} 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \end{pmatrix}$$

$$R^{-a} = \begin{pmatrix} 0 & 1 & 1 & 1 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{pmatrix}$$

Вычтем из результирующих матриц все известные, а это D1 и D2 для прямого и обратного законов и отыщем матрицы U искомого линейного компонента:

$$R^{a} - D^{a}_{1} - D^{a}_{2} = U^{a} = \begin{pmatrix} 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ -1 & 0 & 0 & 0 \end{pmatrix}$$

$$R^{-a} - D^{-a}_{1} - D^{-a}_{2} = U^{-a} = \begin{pmatrix} 0 & 0 & 0 & 1 \\ 0 & 0 & -1 & 0 \\ 0 & -1 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{pmatrix}$$

Матрицы можно объединить следующим образом:

$$U^{A} = U^{a} + (U^{-a})^{T} = \begin{pmatrix} 0 & 0 & 0 & 0 \\ 0 & 0 & -1 & 0 \\ 0 & -1 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{pmatrix}$$

Более сложные компоненты можно отыскать по такому же протоколу: от простого к сложному, находя из их производных. На этом предварительный обзор типовых алгоритмов закончим.

Электронный адрес проекта: phys.mocate@yandex.ru