VISUAL MATLAB (ЛИСЕНОК ©)



БАЛОНИН НИКОЛАЙ АЛЕКСЕЕВИЧ

ЧАСТЬ I. ВВЕДЕНИЕ


Для скачивания представлен базовый вариант системы с возможностью обработки матриц размером не более 160x160. Расширенные возможности (большие размеры матриц, генерация avi) заложены в модули Photo Matlab и Webcamera MatLab. Работа с USB/COM-портом и вебкамерой, софт связи (обмена данными) с сервером позволяет системе создавать графические интерфейсы для нарождающейся Интернет робототехники.

Система VISUAL MATLAB ©, неформальное наименование – Лисенок (Foxcub), Studio Fox 2.5D. Предназначена для быстрой манипуляции двумерными плоскими рисунками, включая, однако, их поворот относительно вертикальной оси (полутрехмерность). В результате объект может поменять направление, на экране, что удобно.

Компактная менее 2 Мб. система объединяет в себе многие технологии: язык матричной алгебры для написания алгоритмов и язык визуализации, средства связи с сервером и с подключенным к USB порту роботом. Существует ознакомительная сетевая адаптация редактора рисунков. В алгоритмах синтеза пейзажей используется технология "пластических" масс: компьютерный пластилин ©.

ИНТЕРПРЕТАТОР ТЕКСТА В SIMPLE ENGLISH


В перспективе математическим системам следует "понимать" привычные нам нотации и, верх совершенства, словесное описание. Некоторая попытка на понимание естественного языка текста в системе предпринимается. Синтаксис языка визуализации приближен к "simple english" (the right arm turns up), причем есть адаптаторы к нескольким прочим не техническим (естественным) языкам.

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

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

Особое внимание отводилось удобочитаемости интерпретируемого транслятором текста: "кисть манипулятора поворачивается на X градусов влево", где вычислением переменной X занят, собственно, матричный сервис MatLab. Сочетание этих двух языков в одном трансляторе (математического и "обычного") создает эффективное средство визуализации математических вычислений Visual Matlab.

СЦЕНАРИЙ


Сценарий, это действие, заключенное обычно в скобки цикла.

ЦИКЛЫ REPEAT, DO (СЧЕТЧИК ТАКТА T)

Repeat ... show end

Размер (ограничитель) цикла может отсутствовать. Возможны привычные для программирования циклов конструкции, в том числе, для MatLab.

Do [размер цикла], ... end
Do while N>n, ... end
For t=1:N Do, ... end
For t Do, ... end

Запятая связывает интерпретируемые предложения, описывающие одновременное движение частей, точка служит цели вывода синтезированного изображения на экран монитора. Двойной цикл Do Do практически вечен (удобен для интерфейсов).

В добавляемом к сценарию словаре новых слов (глаголов) вместо прямого используется безличное обращение к подлежащему subject (объект) или местоимения he (он), she (она), it (оно), his (его), her (ее), this (этот, эта), that (тот,та).

ОСНОВНЫЕ ОТЛИЧИЯ VISUAL MATLAB


Перечислим сначала основные отличия Visual Matlab от MatLab. Их три.

Во первых, ось времени. C целью повышения скорости вычислений она генерируется специальной функцией t=time(протяженность), а не t=0:шаг:протяженность.

Во вторых, имена переменных декларируются matrices: имя, имя, имя (наименование матрицы в одну букву можно не декларировать).

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

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

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

ВИЗУАЛИЗАЦИЯ


ПРАВИЛА ФОРМИРОВАНИЯ СЛОВ

Глагол (фактически, это подпрограмма) описывается в императиве (go), в форме третьего лица (goes), может быть добавлена также инговая форма (going), через
запятую:

word: go, goes, going
<описание глагола>

Разрешается ветвить действие глагола анализом наречий (adverb), подлежащего (name), отсутствия рисунка (absent).

IF (ВЕТВЛЕНИЯ ПО НАРЕЧИЯМ И Т.П.)

If 'adverb' then ... else ... end
If subject is 'name' then ... else ... end
If subject is absent then ... else ... end
If a>b then ... else ... end

Объект имеет имя 'name' (конкретное имя или наречие употребляется без кавычек) и состояние state (ячейка памяти, ее можно, например, увеличивать state=state+1). Эта переменная позволяет описывать протяженное действие (continuous verbs).

Логические знаки в операции сравнения обычные <,>,<>,=,>=,<=,~=,==

БАЗОВЫЕ ГЛАГОЛЫ

Перечислим базовый набор глаголов, их всего несколько. Переменные, указанные в квадратных скобках, должны быть заменены на конкретные (без скобок) или пропущены (тогда берется их предыдущее значение). Все, что указано ниже в кавычках '..' заменяется конкретными именами файлов (name, без кавычек) или персонажей (subject, без кавычек). Если персонаж считан из файла, с именем name, то имя этого файла становится именем персонажа.

OPEN (ОТКРЫТЬ ФАЙЛ)

Open subject 'name.bmp/jpg' % открыть персонаж (bmp-фон прозрачен)
Open background 'name.bmp/jpg/wmf' [X:Y] % открыть фон размера X:Y
Open background 'name.bmp/jpg/wmf' [:] % открыть фон


Open background 'name01.jpg' [:] % открыть нумерованный файл
Open background >. % следующий кадр
Open background <. % предыдущий


Open [foreground] 'name[.box]' % открыть векторный рисунок
Open scene 'name' % открыть сцену

SHOW (ПОКАЗАТЬ)

Show обновляет экран, точка играет ту же роль!

MOVE (ПЕРЕМЕЩАЕТСЯ)

'Subject' moves [distance] up/down/left/right % дистанция в пикселах
'Subject' moves at [level] vertical/horizontal line % в пикселах
'Subject' moves at [x;y[;rad]] position % в пикселах и радианах

'Subject' moves to front/back

TURN (ПОВОРАЧИВАЕТСЯ, НЕ ДЛЯ ФОТО)

'Subject' turns [angle] [forward/backward] % относительный угол в радианах
'Subject' turns at [absolute angle] [forward/backward] % абсолютное значение

FLIP (ИНВЕРТИРУЕТСЯ)

'Subject' flips up-down/left-right/up/down/left/right % сверху-вниз или слева-направо

EXPAND-DIMINISH (УВЕЛИЧИВАЕТСЯ-УМЕНЬШАЕТСЯ)

'Subject' expands [number] [vertically/horizontally] % в количество раз
'Subject' expands [number] [up/down/left/right] % искажение вверх, вниз, влево, вправо
'Subject' expands [number] [up-right/up-left] % перекосы направо и налево
'Subject' diminishes [number] [vertically/horizontally] % в количество раз
'Subject' diminishes [number] [up/down/left/right] % искажение вверх, вниз, влево, вправо
'Subject' diminishes [number] [up-right/up-left] % перекосы направо и налево

LET X BE ... COORDINATE[S] P=[X Y]', S=[X Y Z]'

[Let] P are 'subject' position coordinates % вернуть позиционные координаты, пикселы
[Let] S are 'subject' coordinates % вернуть все координаты [x,y,rad]'
[Let] X is 'subject' horizontal coordinate % горизонтальная координата
[Let] Y is 'subject' vertical coordinate % вертикальная координата
[Let] Z is 'subject' angular coordinate % deg, в градусах

APPEAR-DISAPPEAR (ПОЯВЛЯЕТСЯ-ИСЧЕЗАЕТ)

'Subject' appears
'Subject' disappears

COPY (присоединить персонажи к фоновому изображению)

Copy foreground to background
Copy 'subject' to background

PLAY (ИГРАТЬ, ГОЛОС & МУЗЫКА)

Play name.wav % голос
Play name.mid/rmi % музыка
Replay, stop play, continue the play (перезапуск, остановка, продолжить)

PAUSE (ПАУЗА)

Pause N % в секундах

СТИЛИЗОВАННАЯ ВЕРСИЯ ЯЗЫКА МАТЛАБ



В студии Visual Matlab за основу принята стилизованная версия языка Matlab, изложенная в фундаментальной работе "Матричные Вычисления" авторов Дж. Голуба и Ч. Ван Лоуна.

Если вам нужно вести исследование с наличием матричных вычислений, то портативный модуль, это как раз то, что нужно. Это простая удобная среда для работы, с матрицами, в частности, с матрицами типа Адамара.

ФУНКЦИИ-ФОРМУЛЫ


Вызов функции непосредственно по ее формуле dX/dt=AX+BU

function: dX/dt=AX+BU
X=statestep(A*dt,B*U*dt) %тело функции

Используются только глобальные переменные (локальные создаются назначением уникальных имен matrices: имя, имя, имя, ...). Технология позволяет добавлять DLL-functions с тем, чтобы не тормозить интерпретатор.

ТИПИЧНЫЙ ПРИМЕР


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



Рисунок редактора системы Visual MatLab


Стабилизация ведется расчетом линейного регулятора с квадратичным критерием качества.

There is a Cart with TWO inverted pendulums.
% РАСЧЕТ ПАРАМЕТРОВ ОПТИМАЛЬНОГО РЕГУЛЯТОРА
R=0.001, Q=eye(A), P*A+A'*P=P*B/R*B'*P-Q, K=-B'/R*P
Let H be Cart horizontal coordinate.
DO while max(E)<150
Cart moves at H+0.5*X(1) horizontal line
Cart Pendulum1 turns at X(3) degrees
Cart Pendulum2 turns at X(5) degrees
dX/dt=AX+BU.
E=[abs(X(3)) abs(X(5))]
end
pause

function: dX/dt=AX+BU
a=A+B*K, X=statestep(a*T)

function: P*A+A'*P=P*B/R*B'*P-Q
P=are([A -B/R*B'; -Q -A']) % RICCATI EQUATION

word: There
Open Cart Image
Open Cart Scene, Copy sea to background
T=0.05, g=9.8, L=1, l=0.5, M=1, m=0.5, Cart mass W=2
A=[0 1 0 0 0 0; 0 0 -M*g/W 0 -m*g/W 0; 0 0 0 1 0 0]
A=[A; 0 0 g*(1+M/W)/L 0 g*m/(L*W) 0; 0 0 0 0 0 1; 0 0 g*M/(l*W) 0 g*(1+m/W)/l 0]
B=[0;1/W; 0; -1/(L*W); 0; -1/(l*W)]
X=zeros(B), X(3)=-10, X(5)=15
Cart Pendulum1 turns at X(3) degrees
Cart Pendulum2 turns at X(5) degrees.
E=0.
Pause 1

ЧАСТЬ II. ТЕХНИЧЕСКОЕ ОПИСАНИЕ СТУДИИ


НЕКОТОРЫЕ ВВОДНЫЕ ПРИМЕРЫ

Итак, договоримся считать, что матрицы обозначаются латинскими буквами A, B, ... x, y, z, в том случае, когда нам нужно привлечь более развитое обозначение, оно обязательно декларируется (уступка скорости трансляции) matrices: Xo, X1, X2, X3, и так далее.

Типичные матричные выражения выглядят также, как и в MatLab X=[ 1 1 ]', Y=X'*X. Штрих обозначает операцию транспонирования.

Вывод информации y=?; в виде графика y=??; [t y]=?2D (2D график); и т.д. Для того, чтобы не задерживаться на выводе графика, точка с запятой меняется на запятую. Стиль графика может варьироваться опциями ?- ?~ ?* ?J (for javascript).

Пример вывода графика функции: t=time(100), F=2*t+10*sin(0.5*t), [t F]=?2D_title;

Дополнительной опцией можно указать количество временных отсчетов t=time(T,200), по умолчанию принято генерировать сто точек, начиная с нуля.

Строки матрицы отделяются точкой с запятой А=[ 1 2 ; 3 4 ], процедура решения системы линейных уравнений AX=B выглядит как X=A\B. Левая и правая операции деления A\B и A/B отличаются тем, что в первом случае инвертируется матрица A, а во втором инвертируется уже B.

Матрицу можно вводить и формулой, например A=solve([n m],'1/(i+j)'), где n и m – размеры матрицы, в одинарных кавычках размещается функция от индексов элемента, описывающая его численное значение.

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

% это значок комментария

СЛОЖНЫЕ ГРАФИКИ

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

Каждая пара столбцов может рассматриваться как аргумент и функция, в таком случае вывод графика инициируется нотацией A=?@, например [t F]=?@. Опция W используется для вывода черно-белых графиков ?@W, что важно при их печати.

Функции нескольких переменных можно выводить как Y=?D, [X Y]=?2D, [X Y Z]=?3D. Реализован вывод матрицы в виде цветных портретов A=?C или поверхности (mesh) A=?M. Цвет задается опцией типа СR из набора {R/G/B/Y/F/T/W or I/X/3}, опция A=?СX используется с малоуровневыми матрицами (отражает уровень, знак и вариацию уровня цветом).

Третья координата Z может рассматривается как интенсивность свечения в [X Y Z]=?3R. Цвет или форма маркеров задается опцией из массива {R/G/B/+/O}.

Функцию F=F(t) можно рисовать импульсами [t F]=?@-. В ряде случаев на график наносятся маркерные точки [t F X Y]=?@+ или маркеры в виде окружностей наносятся так [t F X Y]=?@O, их координаты содержатся в векторах X и Y. Ненулевой маркер отвечает [t F x y]=?@:

Масштабы осей s=[Sx Sy] графика функцию двух переменных можно задавать заранее s=axis(Sx,Sy) или s=axis(Sy). Та же самая функция возвращает масштаб осей s=axis([t F]), если он неизвестен и вычисляется графикопостроителем автоматически.

Опции 1, 2, 11, 12, 21, 22, предложенные еще в первой версии MatLab, делят окно вывода на части, их можно указывать так s=axis(Sx,Sy,'12') или [X Y]=?@12.

Полюса и нули передаточных функций на комплексной плоскости можно различать между собой формой так [R I]=?+, [R I]=?O.

Режим удержания графика задается удвоением ?@@, команда close @ заканчивает режим удержания.

ПОТОЧЕЧНЫЕ ОПЕРАЦИИ

Сложение, вычитание, умножение, деление и инверсия элементов матриц задаются функциями R=A±B, R=mulp(A,B), R=divp(A,B), R=invp(A).

КОМПЛЕКСНАЯ АРИФМЕТИКА

Пусть A=[R I] это комплексная матрица R+jI.

Комплексные функции возвращают вещественный и мнимый ее аргументы re(A), im(A), модули mag(A), фазы angle(A), комплексно сопряженную матрицу conj(A), транспонированную матрицу tran(A). Vi=reim(A,i) возвращает i-й комплексный столбец, обратный процесс A=reim([ V1 V2 ... ]), комплексная диагональ D=diagc(A), диагональная матрица A=diagc(D).

Сложить A+B, вычесть A-B, умножить mulc(A,B), разделить divc(A,B), псевдообратить C=invc(A), поточечные умножения и деления: mulpc(A,B), divpc(A,B), умножение на вещественную матрицу mulc(real matrix,A), но mulc(A,real vector) вычисляет только умножение на вещественный вектор.

J=eigc(R) это комплексная жорданова матрица.

Компоненты [V,J]=eigc(R) или [V,J,S]=eigc(R), J=reim(roots(R)), J=?+

ЭЛЕМЕНТАРНЫЕ ФУНКЦИИ

В состав этих функции включены функции вычисления абсолютных значений элементов A=abs(B), возведения в степень A=B^n, факториал A=fact(n), корень квадратный A=sqrt(B), максимальный элемент матрицы M=max(A), минимальный элемент матрицы m=min(A), две функции округления A=round(B) и A=floor(B), наращивания и вычитания единицы A=inc(B) и A=dec(B), cуммирования элементов столбцов X=sum(A), булева функция отрицания A=not(B).

Есть знаковая функции A=sign(B), в дополнение ее положительная A=signp(B) и отрицательная A=signn(B) разновидности, а также функция "выпрямления" A=diode(B).

ТРИГОНОМЕТРИЧЕСКИЕ ФУНКЦИИ

Тригонометрические функции: экспонента A=exp(B), функции логарифмов A=ln(B) и A=lg(B), и прочие функции A=sin(B), A=arcsin(B), A=cos(B), A=arccos(B), A=tg(B), A=arctg(Y[,X]), A=ctg(B), A=th(B), A=arth(B), A=sh(B), A=arsh(B), A=ch(B), A=arch(B).

Радианы в градусы и градусы в радианы переводятся D=deg(R), R=rad(D), Pi(n) это вектор из чисел Пи, одиночное число Пи возвращается и при нуле P=Pi(0), дополнительные функции pi2(x) и pi2pi(x) нормализуют значение аргумента, проецируя его на интервалы от нуля до двух Пи или не более Пи по абсолютному значению.

МАТРИЧНЫЕ ФУНКЦИИ

Корень квадратный A=sqrtm(B), матричная экспонента A=expm(B) и матричный логарифм B=lnm(A)

D=eig(A) возвращает вещественнозначную жорданову матрицу (каждое комплексное число a+jb представлено блоком [a b;-b a], матрица собственных векторов содержит в этом случае в соседствующих столбцах вещественную и мнимую компоненты комплексного собственного вектора), [V,D]=eig(A) или [V,_]=eig(A) возвращает компоненты разложения A=VD/V.

S=svd(A) возвращает сингулярные значения A, [U,S,V]=svd(A) возращает компоненты сингулярного разложения A=USV'.

A=inv(B) это псевдоинверся || AB-E ||->min, || A ||->min (совпадающая с обратной матрицей в невырожденном случае), кроме того вычисляются детерминант d=det(A), число обусловленности c=cond(A), ранк r=rank(A) и фробениусова норма n=norm(A).

РАЗМЕРНОСТИ МАТРИЦ

Функции n=rows(A), m=cols(A) возвращают количество строк n или столбцов m матрицы A соответственно. Функция size(A) возвращает максимальную размерность матрицы. Размерности ее можно вычислять как n=size(A,1), m=size(A,2).

FOR-ЦИКЛ

For i=n:size, ... end (size>=0)

IF-ЛОГИКА (ОПЕРАЦИИ СРАВНЕНИЯ <,>,<>,=,>=,<=,~=,==)

If a>b then ... else ... end

ДВОЕТОЧИЕ

A(i,:) это i-тая строчка, A(:,j) это i-тый столбец, A(i:q) это строчки от i до j, A(i:q,j:p) возвращает субблок.

Пример: C=zeros(n,m), For i=1:n, For j=1:m, C(i,j)=A(i,:)*B(:,j), End End

ГЕНЕРАТОРЫ ВЕКТОРОВ

Ось времени и целые числа генерируются функциями time(T), time(T,n), line(n), line(a,b). Последовательности из нулей, единиц или нормальный шум задаются zero(n), one(n), noise(n). В случае аргумента в виде матрицы или вектора вместо n используется размер, например, t=time(T), x=noise(t). Второй аргумет функции one(n,m) используется для генерации единичного орта с единственной отличной от нуля координатой m. Инверсную к ней функцию вычисляет zero(n,m).

Пример: l=line(3) это [1 2 3]', l=line(-3) это [-1 -2 -3]', l=line(-3,3) это [-3 -2 -1 0 1 2 3]',
z=zero(2) это [0 0]', e=one(2) это [1 1]', e=one(3,2) это орт [0 1 0]', z=zero(3,2) это [1 0 1]'

ГЕНЕРАТОРЫ МАТРИЦ

Нулевая матрица создается функциями zeros(n), zeros(n,m), zeros(A). Матрица из единиц генерируется сходно: ones(n), ones(n,m), ones(A). В последнем случае от A берутся ее размеры. Единичную матрицу возвращает функция eye(n). Кроме того есть функции генерации "шахматной доски" chess(n) и случайного шума rand(n). Функция rand(A) возвращает нормальный шум с амплитудами из A.

Пример: A=zeros(2) это [ 0 0 ; 0 0 ], B=ones(2) это [ 1 1 ; 1 1 ], C=eye(2) это [ 1 0 ; 0 1 ],
chess(8) это "шахматная доска" [0 1 0 1 .. ; 1 0 1 0 .. ], вывод A=?CR.

Генерация циклической матрицы A=circ(a) или A=circul(a), реверсной A=circulback(a), случайной матрицы заданного порядка A=circulrand(n). Блочный аргумент X=[A,B,...] используется для генерации блочных циклических матриц A=circul(X), включая теплицеву структуру A=toeplitz(X). Операция A=crossshift(a) вычисляет кросс-матрицу по вектор-строке, с блочным аргументом (или вектором) генерируется квадратная матрица. Циклический сдвиг строк A=cirshift(A), A=cirshiftback(A).

ФЛИП-ДИАГОНАЛИЗАЦИЯ-СРЕЗЫ-СДВИГИ

Флип вертикальный A=flipud(B), горизонтальный A=fliplr(B), сдвиг по вертикали A=pushud(B[,n]), по горизонтали A=pushlr(B[,n])

Теплицева матрица A=toeplitz(X).

Вектор диагонали D=diag(A), обратно A=diag(D), нижний треугольник L=tril(A), верхний треугольник R=triu(A), вектор из элементов нижнего треугольника X=trilx(L) и обратно L=trilr(X), построение симметричной матрицыA=trils(L).

Матрица вектор столбцов X=colsx(A), вектор строк X=rowsx(A).

Удаление каймы справа и внизу A=cut(B), n-каймы A=cut(B,n), срез сверху A=cutu(B[,n]), снизу A=cutd(B[,n]), слева A=cutl(B[,n]) и справа A=cutr(B[,n]). Сохранение только крайних элементов B=border(A), замещение центральных B=border(A,C).

СОРТИРОВАТЬ, ВОССТАНОВИТЬ

Расширенные функции поиска максимума и минимума с указанием номера элемента [M,i]=max(X), [m,i]=min(Y).

Отсортировать каждую колонку или строку A=sortud(B), A=sortlr(B), причем векторы перестановок P=permud(B), P=permlr(B), иначе [A,P]=sortud(B), [A,P]=sortlr(B).

Сортировка с помощью вектора (или строки) перестановок p=[ 3 2 1 ... ]', всех столбцов p=permax(B), A=sortlr(B,p), всех строк p=permax(B'), A=sortud(B,p), восстановить матрицы B=restlr(A,p), B=restud(A,p).

Рассчитать вектор перестановок по наклонам сигналов (резкости возрастания фронтов) p=sharp(F) или частоте осцилляций p=sharpos(F), последующая сортировка столбцов A=sortlr(F,p)

БЛОЧНЫЕ ОПЕРАЦИИ

A=multiply(B,n) это n-раз размножение [B; B; ...]
Композиция A=[B C D .. ; E F G ..], декомпозиция [B C D ..]=A or [B; C; D; ..]=A
A(i,:) это i-я строка, A(:,j) это j-й столбец, A(q:i) это строки от q до i, A(q:i,p:j) это субматрица. Пусть J=[k j] тогда A(J) возвращает строки A([k j]) от k до j. Пусть I=[m i] тогда A(J,I) возвращает блок B=A([k j],[m i]). Возможно K=[J; I], B=block(K,A).

В композициях ограничен анализ вложенных функций f(g(..)) глубиной не более четырех.

ФУНКЦИИ ДЛЯ РАБОТЫ В ПОЛЯХ ГАЛУА GF(p2)


Арифметика полей Галуа GF(p2), p – нечетное простое число, для псевдокомплексных чисел с двумя основаниями x=[a b], a, b – целые числа < p (mod p) или колонки чисел (вектор), задается оператором r=initgf(p,2), квадратичный вычет r используется для реализации команды умножения gfmul(x,y) скалярных чисел x, y (возможно умножение числа на вектор); степень k числа x или вектор степеней колонки заданных чисел дает оператор gfpow(x,k), оператор gfexp(x,k) дает колонку [x0; x1; ... ; xk–1]. Операции сложения и вычитания скаляров и векторов z=x+y и z=x-y требуют нормализации итога по z=mod(z,p). Сравнить друг с другом два равновеликих вектора x, y или выяснить принадлежность числа или вектора чисел x колонке y можно по gfeq(x,y).

ФУНКЦИИ ДЛЯ ИССЛЕДОВАНИЯ МАТРИЦ СЕМЕЙСТВА АДАМАРА


Генерация {1, –1} последовательности a=randseq(n) или матрицы M=randseq([m n]), M=randseq(A) размера A. Посредством M=randseq([m n k s]) задается регламентированное количество –1 в строках и индексом симметрии s. Расчет циклической и нега-циклической матрицы A=circul(a) и A=negacircul(a), реверсной A=circulback(a), случайной матрицы заданного порядка A=circulrand(n). Блочный аргумент X=[A,B,...] используется для генерации блочных циклических и нега-циклических матриц A=circul(X) и A=negacircul(X), включая теплицеву структуру A=toeplitz(X). A=eyez(n) матрица diag(1,–1,1,–1,..). Операция A=crossshift(a) вычисляет кросс-матрицу по вектор-строке, с блочным аргументом (или вектором) генерируется квадратная матрица. Циклический сдвиг строк A=cirshift(A) и A=negacirshift(A), добавлен реверс A=cirshiftback(A). Процедура error=maxabslsm(A) возвращает абсолютный максимум вне диагонали A*A'; c=circfind(M), массив M=[M;k1 k2 error=0/±2 algorithm=0/1/2/3] or M=[k1 k2 0/±2 0/1/2/3 w v], для C-матриц: M(1,1)=0, при c(3,1)>0 возвращает a=c(1,:), b=c(2,:) из бинарного массива Mv строк бициклов c SDS(n=2v;k1,k2;λ).

РЕШЕНИЕ УРАВНЕНИЙ

A=solve([n m],'1/(i+j)') возвращает значения элементов матрицы по формуле.

Пусть заданы интервал от a до b, а также в случае необходимости дополнительно количество точек n и точность решения tolerance. Тогда F=solve([a b],'f(x)=x*x+x-1') калькулирует значения аргумента и функции F=[x f].

С целью ускорения вычислений запрещено использовать вложенные скобки f(q(x)), записывается цепочечная система уравнений 'y=q(x)_z=p(x,y)_..f(x)=f(x,y,z,...)'.

Поиск экстремума X=solve([a b],'x*x+x-1->extr,x'), график [F X 0]=?@:_Extremum

Интервал P=[a b], на котором функция F=[x f] меняет знаки, уточняет P=fzero(F), это позволяет искать ее корень R=solve(P,'x*x+x-1=0,x'), [F R 0]=?@:_Root методом половинного деления.

Пусть T – шаг по времени, X=X(0) это некоторый вектор начального состояния.

Тогда X=solve(T,'dX/dt=A*X') возвращает следующую точку решения линейного или нелинейного дифференциального уравнения. Процедуру можно итерационно повторять. Это функция для моделирования динамических систем.

ГЕНЕТИЧЕССКИЕ АЛГОРИТМЫ

G=crossing(G) возвращает [G; crossing+mutation]
G=crossing(max,G) или G=crossing([min;max],G) с насыщением.

LL, LR, QR, LQ, LT ТРИАНГУЛЯЦИИ

Пусть S будет симметричная положительно определенная матрица S>0. Тогда матричное разложение Холецкого S=L*L' это L=ll(S).

Пусть Q будет ортогональной матрицей, L и R это левая и правая треугольная матрицы. Разложение A=L*R возвращает функция L=lr(A), причем [L,R]=lr(A). Разложение A=L*Q возвращает функция Q=lq(A), причем [L,Q]=lq(A). Разложение A=Q*R возвращает функция Q=qr(A), причем [Q,R]=qr(A).

Пусть Ax=B, A неотрицательно определенная симметричная матрица A=A'.

B-зависимая триангуляция A=L*T это [L,T,p,b]=lt(A,B), T это правая трапецевидная матрица, p это вектор перестановки, преобразованная правая часть b состоит из L\sortud(B,p).

МЕТОД НАИМЕНЬШИХ КВАДРАТОВ

Псевдоинверсия A°: P=inv(A) колоночным методом Гревилля [P,s]=pinv(A) возвращает ранг и синусы углов базиса векторов столбцов s=[rank(A), sin(углы колонок)]'. Пусть нормальная система уравнения имеет вид AX=B, A=A', A>0

Формула решения X=Xo+W(AW)°(B-AXo) обеспечивает минимизацию двух фробениусовых норм || AX-B || -> min, || inv(W) (X-Xo) || -> min

Пусть b=B or b=[B Xo diag(W)] и X=lsm(A,b), [X,r]=lsm(A,b), r это rank(A)

ТОЧНОСТЬ TOLERANCE

Функция h=tol(tolerance) возвращает прежнее и устанавливает новое значение точности, но только для следующей за ней операции триангуляции, метода наименьших квадратов, псевдоинверсии.

МОДЕЛИРОВАНИЕ ДИНАМИЧЕСКИХ СИСТЕМ

Пусть модель пространства состояний системы dX/dt=AX+Bu, y=CX+du задана матрицей S=[A B;C d]. Рассмотрим также передаточную функцию y=Qu, Q=N(p)/D(p), тогда S=tf(N,D) от коэффициентов полиномов.

СТУПЕНЧАТАЯ И ИМПУЛЬСНАЯ ВЕСОВАЯ ФУНКЦИИ

Пусть t=time(T), тогда h=step(S,t), q=impulse(S,t)

ПРЕОБРАЗОВАНИЯ МОДЕЛЕЙ

Определены операции S=tf2ss(N,D), [A,B,C,d]=tf2ss(N,D), [N,D]=ss2tf(rcform(S)).

Частности [A,B,C]=tf2ss(N,D), [A,B]=tf2ss(N,D), A=cut(S), B=cut(cutl(S,rows(A))), C=cut(cutu(S,rows(A))).

Для вычисления Q(p)=N(p)/D(p)=N1(p)/D2(p)*N2(p)/D2(p) используется операция конволюции N=conv(N1,N2), D=conv(D1,D2).

A=compan(D) это матрица Фробениуса.

КАНОНИЧЕСКИЕ ФОРМЫ (УПРАВЛЯЕМОСТИ)

Сбалансированная каноническая форма F=bcform(S). Столбцовая и строчная реализации F=ccform(S), F=rcform(S).

[F,T,H]=bcform(S) или [F,T]=ccform(S), [F,T]=rcform(S), возвращают матрицу преобразования A=T\AT, B=T\B, C=CT, d=d и ганкелевы сингулярные числа H.

ВРЕМЕННАЯ ОБЛАСТЬ

Пусть dt будет шаг по времени (matrices: dt), X это вектор начального состояния, U это вектор отсчетов скалярного входного сигнала

Выходной сигнал: Y=lsim(S,[U;dt]), причем Y=lsim([S [X;0]],[U;dt]) учитывает начальное состояние X, X=lsim([S [X;1]],[U;dt]) вычисляет финальное состояние.

Пусть A=A*dt, B=B*dt , тогда X=statestep(A) это следующий шаг системы dX/dt=AX, функция двойного аргумента X=statestep(A,B*u) возвращает следующий шаг системы dX/dt=AX+Bu

Интегратор: Y=int(U,dt) или Y=int(U,t)

ДИСКРЕТНЫЕ СИСТЕМЫ

Xk+1=AXk+Buk, yk=CXk+duk

Выходной сигнал: Y=dsim(S,U), причем Y=dsim([S [X;0]],U) соответствует начальному состоянию X, X=dsim([S [X;1]],U) вычисляет финальное состояние.

Дискретный интегратор: Y=int(U)

ЧАСТОТНЫЕ ХАРАКТЕРИСТИКИ

Передаточная функция Q(p)=N(p)/D(p) задана коэффициентами полиномов. F=rcform(S) возвращает строчную каноническую форму F=[A B;C d], также справедливо F=tf(N,D) или F=tf2ss(N,D), причем [N,D]=ss2tf(F). Диаграммы Боде m=bode(F,w), m=?D. Найквиста G=nyquist(F,w), G=?2D для w=[0 W 2W ... ]' с шагом W. Можно установить и комплекснозначную выборку в виде двойной w=[re im]-колонки.

ПОЛИНОМИАЛЬНЫЕ МОДЕЛИ

Пусть N=[c1 c2 ... ]' вектор коэффициентов полинома c1xn+c2xn-1...

Фробениусова матрица рассчитывается A=compan(N), корни полинома R=roots(N) или R=roots(A). Коэффициенты можно рассчитать по корням N=polyc(R), операция свертки N=conv(N1,N2) возвращает коэффициенты произведения двух полиномов. Значение полинома в точке v=polyv(N,x), x=[a b] это комплексный аргумент a+jb.

ФУНКЦИИ ОБРАБОТКИ СИГНАЛОВ

Нормальный шум генерирует X=noise(t).

Флип инверсию, а также одномерное и двумерное сглаживания возвращают функции Y=flip(X), Y=smooth(X), B=smooth2D(A). Функция может быть прорежена Y=sample(X,n) с шагом n.

Скалярное произведение двух векторов Y'*X возвращает S=muls(Y,X). Квадратичная форма x'Ax вычисляется для каждого значения аргумента x' из колонки аргументов X как F=qform(A,X). Корелляционную и автокорреляционную функции вычисляют K=xcor(Y,X), R=xcor(X). Дискретное Фурье преобразование F=fft(Y).

Есть функция насыщения Y=sat(X,m) с уровнем m. Дистанция между трэком на плоскости и точкой вычисляется функцией D=dist([Y X],[y x]).

Протяженность процесса l=length(X).

МАТРИЧНЫЕ АЛГЕБРАИЧЕСКИЕ УРАВНЕНИЯ

Алгебраическое уравнение Риккати

P*A+A'*P-P*B/R*B'*P=-Q, P=are([A -B/R*B'; -Q -A'])

Уравнение Ляпунова

P*A+A'*P=-Q, P=are([A zeros(A); -Q -A'])

КВАДРАТИЧНЫЕ ФУНКЦИОНАЛЫ

dX/dt=AX+Bu, Y=CX+dU, функционал f=0.5 § (X'QX+U'RU) dt -> min

Пусть H=[A -B/R*B'; -Q -A'], P=are(H), K=B'/R*P (линейный регулятор: U=-KX)

ЛИНЕЙНЫЕ ОПЕРАТОРЫ

Пусть задана импульсная весовая функция q=impulse(S,t) с шагом T, тогда матрица оператора свертки будет M=T*toeplitz(q)

В общем случае M=lom(S,t,'Option'), Y=lsim(S,[U;dt],'Option'), для дискретных систем: M=dom(S,t,'option'), Y=dsim(S,U,'Option').

Вычисление главной сингулярной функции и сингулярного числа: f=eigf(S,t,'Option'), [f,d]=eigf(S,t,'Option').

Option для свертки это S, для сопряженного FSF оператора это A (adjoint), для прочих составных операторов FS, SF, FSF, S+A, S-A, SA, S+FS, S-FS, S+SF, S-SF, FS+SF, FS-SF, для теплицева оператора это T, ганкелева FT оператора это H, для прочих составных операторов FT, TF, FTF, T+A, T-A, T+FT, T-FT, T+TF, T-TF, FT+TF, FT-TF, все операторы 0.5-нормализованы.

НЕЛИНЕЙНЫЕ СИСТЕМЫ

Маятник: dX/dt=F(X), F=chain([Masses;Lengths],X) возвращает производные F(X),
X=[A;dA/dt] где A это относительные углы элементов цепочки.

X=solve(dt,'dX/dt=f(X)') это шаг дифференциального уравнения, Y=qsim(a,Yo*line(size)) это процесс Yk+1=a Yk (1 - Yk)

Множество Мандельброта: Zk+1=C+Zk*Zk, Z=[Re Im], Zo=[0 0], M=qsim(Mo,size), get C from Mo=[Re1 Re2 Im1 Im2]. Множество Джулиа: Zk+1=C+Zk*Zk, Z=[Re Im], взять Zo из Mo, M=qsim(Mo,[size max(| Z |) C] для некоторого C=[Re Im]. M содержит финальные нормы | Z | для раскраски M=?CR

РАБОТА С ВЕБКАМЕРОЙ

Компактная система Visual Matlab имеет несколько конфигураций, ориентированных на разные классы задач, в частности, вебкамеру обслуживает pcMatLab.exe. Сбор информации идет в цикле с паузой (в секундах):

do
X=read('camera.bmp')
e=write(0,'camera:file=image.jpg')
open background image.jpg [:], show
pause 1
end

Команда X=read('camera.bmp') чтения изображения в память X. Некоторые драйверы вебкамер требуют контроля считываемости.

Команда e=write(0,'camera:file=image.jpg') записи изображения на диск. Есть дополнительная пара команд визуализации open background image.jpg [:], show. Усечение e=write(0,'camera:') передает информацию на экран и есть опции коррекции.

e=write(0,'http://mathscinet.ru_folder=name_file=image.jpg') позволяет записать фото из каталога, в котором хранится текст с командой, в каталог (folder) c именем name. В приемном каталоге вебкниги зарезервировано стандартное наименование для изображения вебкамеры image.jpg.

Радиомодем запускается командой e=exe('линк на стартовую программу').

СВЯЗЬ С COM-ПОРТОМ (RS232, UART)

Режим передача и прием через com-порт (номер запоминается) организуется, например, так

A=1, e=write(A,'com1'), B=0, do 2, if B=0, B=read('com'), end, B=?

Предусмотрено сбрасывание зависшего соединения, надежность считывания обеспечивается дублированием и троированием (не должно быть большим). Предустановлена стандартная частота 9600, иначе пишем e=write(0,'com152000'), закрываем порт по e=write(0,'comclose').

КОМАНДЫ USB МОДУЛЯ АЦП-ЦАП от LCARD E14-140D

Эти команды работают в специализированной версии системы с предустановленным драйвером модуля LCARD.



Сначала устанавливаются размеры векторов измерения и управления. Для односвязных систем y=0, u=0. Чтобы задействовать три выхода, два синфазных входа: y=[0 0 0]', u=[0 0]', y=read(u).

Для аналоговых портов y=read(u), для дискретных y=readig(u). В последнем случае u=3 означает в двоичной системе счисления 11 (установка в единичку двух первых логических выводов DO TTL-логики для управления реле).



Для управления в режиме реального времени c заданным шагом в 1 секунду инициализируется таймер по open timer support и пишется программа обработки прерывания word/function: timer 1000 mсs

ЧИТАТЬ И ЗАПИСЫВАТЬ МАТРИЦЫ

open Matrix A (get A.txt), save Matrix A (<16 cols).

A=read('name[.txt]'), e=write(A[,'name[.txt]']), A.txt и a.txt не отличаются содержанием (то же самое имя) !

ЧИТАТЬ И ЗАПИСЫВАТЬ ОКРУЖЕНИЕ

Размер экрана X=read('maxX'), e=write(X,'maxX'), также: Y=read('maxY'), e=write(Y,'maxY'), строку параметров exe-файла: V=read('mean'),

P=read('name.bmp/jpg'[,color]) чтение из фотографии, colors: 'red', 'green', 'blue', P=read('lastfile.bmp/jpg'[,color]), P=read('previous.bmp/jpg'[,color]), '../' is P=read('@@/lastfile.jpg'), 'C:' is P=read('C$lastfile.jpg')

16-bits звуковой файл <5000, options: 'head','mix', H=read('name.wav','head'), V=read('name.wav'), e=write([H;V],'outname.wav')

S=read('name.int') читает 16-bits int-ленту (anyx120)

ИНТЕРНЕТ

A=read('http://server/name.xml'), e=write(A,'http://server/name.php?data=')

ЗАПУСК ВНЕШНИХ ФАЙЛОВ

e=exe('filename_parameters'), FTP-СЦЕНАРИЙ e=exe('script.ftp'), script содержит манипуляции с сервером, комментируемые в справочной системе Windows.

open XXXXXX.com
login
password
cd folder
binary
send c:/file.jpg
quit

ТЕКСТОВЫЕ МАКРОСЫ (ОБРАБОТКА ТЕКСТА СЦЕНАРИЯ)

Пусть y, x это место слова в сценарии из q линий, e ошибка (должна быть равна 0)

Размер: q=linesize(0), w=wordsize(y,x), l=linesize(y), e=cutword(y,x), e=getword(y,x) затем e=putword(y,x), e=cutline(y), e=getline(y) затем e=putline(y), e=putline(y,'pattern')

Очистка буфера: e=cutline(y,'renew'), обновление e=putline(y,'renew')

Поиск позиции p: установить область A=a (0 is all), A=[a b], N – номер образца, p=findline(A,N) или просто p=findline(A,'pattern'), также e=getline(N) тогда p=findline(A)

Установить область A=0, A=a, A=[a b], A=[a b; c d], p=[y x]' или p=y, p=findword(A,'pattern'), p=findchar(A,'s'), также e=getword(x,y) then p=findword(A)

ОБЛАСТЬ ИНТЕРАКТИВНОГО ОБМЕНА ТЕКСТОМ

ASCII представление строки S=getline('str:текст_текст'), пробел заменяется связкой, двоеточие – знаком $. Перевод векторного представления в строку аккумулятора e=getmatrix(S).

Взять строку из активного сегмента e=getline(0,''), переустановить e=putline(0,'pattern'). Взять строку из окна диалога e=getline(1,'window'), положить e=putline(1,'window'), закрыть окно e=putline(2,'window').

word: click
if keyboard then <функция прерывания enter-key> end

ЧАСЫ CLOCK

Hour=clock(1), Min=clock(2), Sec=clock(3), MSec=clock(4), Year=clock(5), Month=clock(6), Day=clock(7)

ОГРАНИЧЕНИЯ

1. Максимальный размер матрицы [any]x160/1000 (фото-MatLab).
2. Имя не более 50 символов, строка до 160 & словарик не более 128 слов/функций
3. "Close A", "Close all" очищает матрицу, или память.

Inf & Не число (Not a Number)

Inf is 8880888, NaN is 7770777

ДЕСКРИПТОРНОЕ ОПИСАНИЕ ВЕКТОРНЫХ РИСУНКОВ

Существует редактор для отрисовки векторных объектов – кукол. Данное описание раскрывает формат данных. Дескрипторный рисунок помещается в текстовой файл, расширение name.box. Его можно набирать текстовым редактором, но надо заботиться, чтобы в завершениях строк не было пробелов. Первые две строки зарезервированы под наименование формата CARTOON и номер версии.

CARTOON
MMACXXI
Количество элементов
Стартовый дескриптор TF- или TT-элемента
Необязательная именная часть (до четырех строк наименований)
12-ти числовой регистр элемента
Двухколоночная таблица координат точек элемента
Следующий элемент (стартовый дескриптор, имена, регистр, таблица) и т.д.
END_CARTOON

Структурированные векторные рисунки содержат родительские и дочерние сегменты, подобно тому, как на руке имеются пальцы, а пальцы имеют фаланги. В итоге сложное подлежащее имеет вид: cat head (голова кота) и т.д.

СТАРТОВЫЕ ДЕСКРИПТОРЫ ЭЛЕМЕНТОВ

Принцип Неймана совмещает запись команд и данных. Аналогично, формат элемента TF описания структуры в дескрипторном представлении таков же, как и формат описания графического элемента TT (полигона). Первая булева переменная T отведена под корзину, элементы можно дезактивировать, меняя первое T на F. Вторая метка отводится под тип (графика T или структура F).

Третья и четвертая метки регулируют видимость и подвижность. Это относится, очевидно, как к структурам, так и к графике. Элементы, описывающие только графику, начинаются с TT. Дескриптор TTTT вводит активный графический явно видимый и подвижный элемент. Описатель экрана, напротив, имеет дескриптор TTFF. Экран неподвижен и прозрачен. Но у него есть размеры, как у простого графического элемента. Это роднит их. Экран в описании элементов всегда идет первым. Графические TT-элементы всегда размещают в конце.

Элементы, описывающие структуру, начинаются с TF. Cтартовый дескриптор у них нередко вдвое длиннее TFTTTTTT. Четыре последних флажка позволяют активировать поименное описание сегментов: сцена, персонаж, часть, деталь (построчно). Меняя первый флажок на F, можно не упоминать сцену по TFTTFTTT, описывая следующий ее персонаж. Неименованный слайд обходится укороченным дескриптором TFTT. Отметим, что в смешанном векторном формате удвоенный дескриптор позволяет включить в элемент произвольный текст или адрес подгружаемого bmp/jpg-рисунка.

За стартовым дескриптором и именами следует строка "регистра" элемента из 12 чисел в одну строку. Первое число N описывает, обычно, размер простого неименованного TT элемента (полигона), т.е. 2 отвечает линии, 3 – треугольнику и т.д. Далее в регистре идут индивидуальный номер структурного элемента (его абсолютный адрес), и номер персонажа, номер части, номер детали, номер слайда. Потом идут два числа, обозначающие цвет полигона и цвет бордюра (окаймления полигона) в цветовой палитре языка Паскаль (Delphi, где черный цвет – просто ноль, красный, зеленый, синий и белый это 255, 65280, 16711680, 16777215). Последние четыре числа регистра – модификаторы полигона, позволяющие его фрактально окрашивать. В простейшем случае это 0 0 0 N (обычный полигон) или 0 0 1 N (с бордюром). Модификаторы значительно разнообразят векторную графику, делают ее выпуклой, трехмерной и т.д.

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

За регистром в двух колонках следуют N координат X и Y опорных точек TT элемента (полигона). У структурных TF элементов в опорных точках хранятся центры вращений – текущий (актуальный), далее экрана, сцены, персонажа, части, детали, координаты идут в порядке заголовка элемента, т.е. если сцена в заголове элемента опущена, то ее центр вращения не рассматривается, всего зарезервировано 6 обязательных точек. Выделение текущего центра вращения естественно, это позволяет гибко менять точку вращения в сложных движениях персонажа и его сегментов.

ПРИНЦИП ДОПОЛНЕНИЯ

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

ПРИМЕР ВЕКТОРНОГО РИСУНКА

Приведенной информации достаточно, чтобы приступить к примерам. Нарисуем квадрат со стороной 100 пикселей в центре квадрата экрана со стороной в 200 пикселей.

В данном случае описание состоит из трех элементов. Первый простой элемент TTFF описывает черный экран (первая и третья точки его – резервные, вторая точка отведена под размеры экрана). Второй элемент TF описывает структуру и задает центры вращения. Третий элемент TT описывает, собственно, красный квадрат.

CARTOON
MMACXXI
3
TTFF
3 0 1 1 1 1 0 0 0 0 1 3
100 100
200 200
000 000
TFTTTTTT
Scene
Subject
Part
Detail
6 1 1 1 1 1 0 0 0 0 1 6
100 100
100 100
100 100
100 100
100 100
100 100
TTTT
4 1 1 1 1 1 255 255 0 0 1 4
50 50
50 150
150 150
150 50
END_CARTOON

Текстовой ассемблер приспособлен к манипуляциям над структурированными рисунками. Он позволяет легко наращивать объект. Добавим треугольник, например, в качестве второй независимо правляемой части этого объекта. Потребуется еще один структурный элемент TF и один простой TT
(зеленый треугольник).

CARTOON
MMACXXI
5
TTFF
3 0 1 1 1 1 0 0 0 0 1 3
100 100
200 200
000 000
TFTTTTTT
Scene
Subject
Part1
Detail
6 1 1 1 1 1 0 0 0 0 1 6
100 100
100 100
100 100
100 100
100 100
100 100
TFTFFFTT
Part2
Detail
6 2 1 1 2 1 0 0 0 0 1 6
100 100
100 100
100 100
100 100
100 100
100 100
TTTT
4 1 1 1 1 1 255 255 0 0 1 4
50 50
50 150
150 150
150 50
TTTT
3 2 1 1 2 1 65280 65280 0 0 1 3
100 50
50 150
150 150
END_CARTOON

Получаем Subject, у которого есть две управляемые руки (ветви) Part1 и Part2. Эти ветви визуально представлены двумя простыми графическими примитивами, число примитивов можно наращивать.

Rambler's Top100