Комментарии 11
"Минусеры" - это, видимо, те кто, начиная еще с детсада или школы, любили исподтишка делать пакости. Вы уж "вякните" хоть что-нибудь, объясните свою позицию вместо того, чтобы подложить очередную "кнопку". Это будет честнее, понятнее, за это можно и нужно уважать, а вот за "подкладывание кнопок"... За это обычно в детстве давали подзатыльник, или ставили в угол...
Ну да ладно - проехали. У меня же просто просьба. Можно даже сказать - большая просьба. Может ли кто "наваять" на языке MATLAB код аттрактора с буферизацией, который как можно ближе был бы к приведенному в публикации на внутреннем языке SimInTech (см. рис. 10)? Очень хочется увидеть - проявится ли и в нем эффект 30-й секунды?... Ну, очень, честное слово.
В обсуждении предыдущей статьи правильно указали, что задача очень уж нестабильная, можно сказать даже "эталонно нестабильная". И все же удивительно, что 2 программы иногда дают одинаковые результаты.
В настоящей статье автором производится попытка свести задачу к устойчивой (но несколько другой) или докопаться до причины несоответствия. Практические цели призрачные, но дело интересное и опыт, возможно, когда-нибудь пригодится при устранении сложных неисправностей (программно-аппаратного решения).
Хоть я и не со всем согласен/не все понял, но считаю статью неплохой и призываю постараться оценить достоинства статьи. +1.
Спасибо за оценку моей работы. Это большой стимул продолжать ее (пусть кому-то это явно не нравится) ;)
И все же удивительно, что 2 программы иногда дают одинаковые результаты.
Зто как раз нормально. Программы должны давать или стабильно правильный или стабильно неправильный результат. Это базовое свойство любой программ. Если в них, конечно, не введен сознательно или по недосмотру недерминизм. В рассматриваемых аттракторах его нет и в помине. А потому все должно быть стабильно.
Практические цели призрачные, но дело интересное и опыт, возможно, когда-нибудь пригодится при устранении сложных неисправностей (программно-аппаратного решения).
Безусловно. Иначе бы я не тратил свои силы на это "хобби" :) А практические цели четкие - при прочих равных условиях все должно совпадать. Это, как в тесте. Это и есть тест. Хороший тест. А любой тест имеет практическое значение. И все почти получилось... пусть пока до 30-й секунды. И это говорит, что кто-то косячит явно. Хочется, как я сказал, посмотреть на МАТЛАВ в реализации на ЯП. В зависимости от того, что получится, можно будет делать и выводы. Мне хотелось, чтобы совпало с ВКПа. Но, безусловно, может быть все. Лично я готов ко всему :)
Но как бы то ни было все должно поддаваться объяснению. У всего есть причины. Мы все же не на картах гадаем, а анализируем и сравниваем работу программ. Это математика, а не теология. В определении алгоритма, ведь, сказано, что результат должен быть повторяем. Здесь он, возможно, не предсказуем (это и есть особенность аттракторов), но точно повторяем. Даже сейчас. Но пока до 30-й секунды :)
Но я, уверен, что разберемся. И преодолеем возникший "временной рубеж". В конце концов, я найду время и напишу эту программу на МАТЛАБ. Кстати, оказывается, достаточно много людей занимаются изучением и реализацией аттракторов. Нашел даже на С++, Java, но пока не дошли руки, чтобы разобраться. Так что фронт работ, как это не покажется странным, просто огромный. И я считаю, что задача стоит того.
И еще. Не в моих правилах просить ... эти, как их, - лайки ;) Но если кто-то положительно относится к моей работе, то не стесняйтесь - ставьте. Подленькое и гаденькое часто и активнее, да и запашок от него сильнее. Ведь известно про ... ложку дегтя и бочку меда. Они этим пользуются. Надо уметь им отвечать. Часто это имеет большое значение.
Ну, что, друзья, поздравьте! Все получилось так, как и предполагалось. Ниже графики в порядке следования - ВКПа, MATLAB и SimInTech. Внешне все идеально совпадает.

В целом все оказалось до банального просто. Самое сложное было - написать программу для MATLAB ;) Лично я доволен. Жду плюсов от "минусеров"... :)
Минусы не мои, но вот вам гипотеза: их ставят потому, что вы упорно разводите эзотерику вокруг букварных истин.
Есть модель в виде дифференциальных уравнений. Её численное решение — формулы, в которых значения одних переменных выражены через значения других. Заметьте, я не говорю: значения переменных в очередной момент времени выражены через значения тех же и других переменных в предыдущие моменты времени. X(0) = 0, X(i+1) = X(i) + U(i) можно записать как A = 0, B = A + C, D = B + E и так далее, просто это громоздко. Более того, мы говорим "переменные", но так мы видим, что нет меняющегося X(i), есть независимые и никогда после вычисления не меняющиеся значения A = X(0), B = X(1) и т. д. Времени во всем этом нет как понятия, величины шага по времени вычисляются так же, как любые другие переменные. Так как перевод модели в разностные уравнения зависит только от метода интегрирования, и вы хотите сравнить результаты разных сред моделирования при одном и том же методе, фактически вы хотите сравнить формулы. В этой статье вы итого написали одинаковые формулы вручную и, ожидаемо, получили одинаковые результаты. При задании модели через структурную схему формулы составляет среда. Из этого следует, что когда вы получали разные результаты в Simulink/SimInTech и ВКПа, это происходило потому, что формулы были разными. Итого вы доказали, что если считать по одинаковым формулам, получится одинаковый результат :)
Ни о каком "теневом буфере", но о каком "истинном параллелизме", ни о какой "инерционности операций" при вычислении формул вида A = B + C говорить не нужно и не приходится. Если вы считаете, что алгоритм, по которому ВКПа составляет уравнения, чем-то примечателен, это можно было бы обсудить. С другой стороны, если ВКПа, получив те же формулы, вычисляет по ним другой результат, это попросту неправильная работа, арифметика едина для всех.
Несколько потоков бывают нужны для ускорения вычислений, но значения всех отсчетов они должны вычислить такими же, как это сделал бы последовательный код. Это как если суммы в скобках H = (D+E) + (G+F) будут вычислять два человека одновременно — оно быстрее, но если третий скажет "я возьму E = C для вычисления I = E + J, пока они возятся" — это некорректно.
По поводу эзотерики и т.п. Отвечал не раз. В статьях по поводу используемой модели параллельных вычислений все . Что-то не так – критикуйте, опровергайте, обосновывайте. На все отвечу. Придумать что-то другое – уже не могу ;) Если что-то и обсуждать , то что-то конкретное. В этом смысле аттракторы и есть то конкретное, что вписывается в тематику параллелизма.
Итак. Их реализация. Исходная – визуальная, т.е. на языке визуального программирования (ВП). В чем его принципиальное отличие от внутренних языков программирования (ЯП) . Да ни в чем. Это с точки понимания, какой результат должен быть на ВП и ЯП. Еще раз. Языки внешне разные, но результат их работы в идеале должен быть один. Точка. Это аксиома программирования: результат работы программы не должен зависеть от языка программирования на котором она написана. Согласны? Если язык вносит какие-то нюансы в процесс работы программы, то все это должно быть контролируемым.
Поскольку речь о параллелизме, то варианты последовательной программы и параллельной должны выдавать одинаковый результат. Или по—другому – извне нельзя определить какой вариант программы, параллельный или последовательный, вам достался. Это первая аксиома.
Вторая аксиома. Извне, т.е. по результату, нельзя определить на каком языке – ВП или ЯП – написана программа. Надеюсь и с этим Вы согласны?
Теперь смотрим на аттракторы. На визуальном языке - одно. На ЯП – другое. Проблема? Проблема. Нарушена вторая аксиома.
У нас есть последовательная реализация аттрактора (будем на примере Лоренца). Она дает один результат. У нас есть параллельная реализация – результат другой. Заметим, что язык программирования при этом один – внутренний ЯП. Нарушена теперь первая аксиома.
Да, нужна и третья аксиома. Программы, написанные в разных пакетах (MATLAB, SimInTech и ВКПа) должны быть также неотличимы. И она нарушается! Мы обнаруживаем и здесь отличия. Даже на уровне внутренних языков программирования.
Но есть один случай, когда все три аксиомы исполняются. Это параллельная реализация на внутренних языках программирования. Ну, какая здесь изотерика? Все строго доказуемо и по теории и по практике ее использования в реализации конкретных задач (аттрактор Лоренца). Ну, все ж расписано. Или что-то не так? Ну, каюсь, была одна ошибка на аттракторе Рикитаке. Но спасибо ему – была обнаружена и исправлена.
Теперь-то что не так? Что или где не корректно? Использование параллелизма? Так это в самую тему, т.к. система уравнений параллельна изначально по своей природе. Т.е. все (!) реализации аттракторов, в которых не используется в той или иной форме параллелизм некорректны. И это было показано. Т.е. и SimInTech и MATLAB в визуальной форме дают ошибочное их решение. Просто потому, что в их внутренней природе параллелизм не учитывается от слова совсем. И это не их критика. Это констатация факта. Как можно доверять программным пакетам с такими пробелами в организации/реализации моделей, в которых процессы параллельны. В сложных моделях, как правило, всегда параллелизм присутствует. Нужны ли еще какие-то доказательства о существующих проблемах в этих и подобных пакетах, а по большому счету и наличие проблемы параллельных вычислений вообще? По мне – нет. Или такой проблемы нет? Может она ушла, например, с введением параллелизма в С++? Нет и еще раз нет.
Вот такая получается «изотерика» современного программирования
в любых его формах и проявлениях. И никак не меньше. :)
Это аксиома программирования: результат работы программы не должен зависеть от языка программирования на котором она написана.
Вынужден придраться к формулировке не из вредности, а потому что это важно. Правильно: "все программы, корректно реализующие алгоритм, должны выдавать одинаковый результат". Алгоритм нужно ввести, потому что должен быть идеал, с которым сравнивать. Какую задачу решает алгоритм? Дифференциальное уравнение. Как задан алгоритм? Вычислительной схемой для численного интегрирования, то есть системой алгебраических уравнений (можно записать их сразу для всех отсчетов). Любая реализация должна искать именно их решение. В том числе реализация а) в виде решения вручную и реализация б) методом последовательных приближений. Внимание, вопрос: это реализация параллельная или последовательная? У нас нет ни блоков, ни времени.
Если язык вносит какие-то нюансы в процесс работы программы, то все это должно быть контролируемым.
Однако языку могут принадлежать и программы, не соответствующие алгоритму. Иными словами, язык не обязан страховать от логических ошибок. Если структурная схема выглядит логично, как параллельное соединение блоков, это не гарантия, что она соответствует тем уравнениям (алгоритму), которых вы ожидаете. Что a <= b
на C приведет к "перетеканию" значения из b
в a
и обнулению b
тоже может звучать неплохо и эстетически логично, но не соответствует тому, что сделает C.
У нас есть последовательная реализация аттрактора (будем на примере Лоренца). Она дает один результат. У нас есть параллельная реализация – результат другой.
Вы называете "параллельной и последовательной реализациями" реализации двух разных алгоритмов, полученных из одних и тех же дифференциальных уравнений разными вычислительными схемами. Я не знаток аттракторов, но вот на примере двумерной задачи. Есть явная вычислительная схема, где значения в следующем слое выражаются через значения в предыдущем, и их в слое можно считать одно за другим. Есть неявная, где значения в очередном слое используют соседние значения в том же слое, и их нужно искать все вместе. При расчетах по каждой схеме будут свои результаты, это нормально.
Все буферизации при вычислениях в конечном счете отражают определенные уравнения, которые связывают x[i], x[i+1] и т. п. Ввели буферизацию = поменяли уравнения = использовали другую расчетную схему = реализовали другой алгоритм решения (той же задачи).
система уравнений параллельна изначально по своей природе
Что такое "параллельная природа системы уравнений"? Что каждая переменная выражена через все остальные? Это уже входит в понятие системы уравнений. Параллелизм, исходя из ваших же статей, имеет смысл только в контексте вычислений, как он может относиться к системе уравнений, которая существует вне связи с вычислениями?
Может [проблема параллельных вычислений] ушла, например, с введением параллелизма в С++?
Эта "проблема" — неверные ожидания того, какие уравнения будет составлены при визуальном моделировании. Рассуждения о том, что для корректного моделирования физически одновременных процессов нужно вести обсчет моделей этих процессов физически одновременно ("явный параллелизм, который еще нужно реализовать, используя то же множество ядер или потоков") — чушь, есть система алгебраических уравнений и ее можно решить хоть вручную.
Напомним, что мы решаем систему уравнений, которую запишем в следующей форме:
x' = s(у - x);
y' = x(r - z) - y;
z' = xy - bz;
Не нужно больших знаний в математике, чтобы запрограммировать ее решение. На С-подобном языке (опускаем детали) это можно представить примерно так:
while (1) {
dx = s*(y-x); x = integral(dx); // x
dy = x*(r-z) - y; y = integral(dy); // y
dz = x*y - b*z; z = integral(dz); // z
}
Именно такой алгоритм реализуют все рассмотренные нами языки, как визуальные, так и [внутренние] ЯП. И именно его реализация на всем множестве языков должна была по первой аксиоме приводить к одинаковым результатам. И … этого не получилось.
Чтобы не обосновывать сей конфуз нюансами визуальной реализации мы решили этот же алгоритм реализовать на внутренних языках программирования. Благо они везде есть - от SimInTech до ВКПа. И здесь мы достигли желаемого - все получилось тип-топ. И вот когда я написал последнюю фразу, то решил ее проверить. И … тип-топа не получилось. А получилось вот что:

SimInTech так и не подчинился моей воле ;) Но не будим винить его в этом. Но обратим на это внимание. Языки программирования должны быть такими, чтобы однозначно и ясно описывать алгоритмы. И вообще, программа – это лишь одна из форм описания алгоритма. Это про первую аксиому. Поэтому Ваша первая придирка про некорректность – отвергается. Реализация по определению должна быть корректной (в пределах аксиомы, конечно). Т.е. программа – это и есть алгоритм, но только в соответствующей форме представления.
По поводу второй аксиомы. Мне кажется, что язык SimInTech вносит что-то, что не позволило мне добиться нужного результата. Но, конечно, это может быть и мой косяк. Но пока я его не вижу. Отладка в нем тоже в зачаточном состоянии, а потому не помогла в этом разобраться. Но опять же – возможно я туплю… Тем не менее, вопросы есть. Например, почему нужно напрягаться, чтобы получить результат, который в MATLAB и С++ получился сам собой.
По поводу «параллельной и последовательной реализации»... Выше представлен алгоритм, который по умолчанию представляет последовательную форму алгоритма. Просто потому, что языки нынче по умолчанию последовательные. Поэтому мы уже изначально извращаем решение, применяя несоответствующий ему язык. Ведь уравнения в системе уравнений параллельны? Или нет? Т.е. мы должны сначала вычислить x’, затем y’ и только потом z’? Или последовательность их вычисления другая? Или все же одновременно, т.е. параллельно? Что Вы на это скажите? Т.е. фактически речь идет о … природе уравнения. И тогда какая она? Т.е. может ли уравнение существовать «вне связи с вычислениями»?
Ну и по поводу «чуши». Мы вправе рассматривать любую реализацию. Только, первое, в идеале она должна соответствовать «природе уравнения» и , второе, результат должен быть один при любой реализации. Последнее – это то, чего мы и добиваемся. И это то, что пока на деле нарушается и требует определенных «плясок с бубном», чтобы все же получить правильный результат. Например, SimInTech так и прокомментировал - какое же решение считать правильным: то, что мы имеем в нем сейчас, используя визуальный язык, или вычисленное на ЯП? Надо бы определиться. Или такое молчание можно трактовать как уход и от ответа и от ответственности...
Возникает закономерный вопрос – а какой результат считать правильным, если их столько много (даже выше их два)? И вот тут нужен, так сказать, консенсус J А какой результат из статьи Вы считаете правильным? Или, может, все правильные (трансляторы/компиляторы, ведь, не выдают ошибок)? Или виноваты только мы со своими «неверными ожиданиями»?
Да. А решив в ручную рассматриваемое уравнение, Вы получите какой, как Вы думаете, результат?
Не нужно больших знаний в математике, чтобы запрограммировать ее решение.
Погодите программировать! Мы ведь ищем не решение дифференциального уравнения, а приближение к нему. Напишем сначала алгебраические уравнения, которыми будем приближать дифференциальные.
Можно тривиально заменить df/dt на (f[i] - f[i-1]) / dt
, а f(t) на f[i]
:
(x[i] - x[i-1]) / dt = s * (y[i] - x[i])
(y[i] - y[i-1]) / dt = x[i] * (r - y[i])
(z[i] - z[i-1]) / dt = x[i] * y[i] - b * z[i]
Перепишем их для удобства сравнения, выразив неизвестные:
x[i] = (x[i-1] + dt * s * y[i]) / (1 + dt * s)
y[i] = (y[i-1] + dt * r * x[i]) / (1 + dt * r)
z[i] = (z[i-1] + dt * x[i] * y[i]) / (1 + dt * b)
По вашей C-подоброй программе, предполагая integral(df) = f[i-1] + df
, я восстановил, как смог:
x[i] = x[i-1] + dt * s * (y[i-1] - x[i-1])
y[i] = y[i-1] + dt * x[i] * (r - y[i-1])
z[i] = z[i-1] + dt * (x[i] * y[i] - b * z[i-1])
Легко видеть, что ваше второе и третье уравнения отличаются от моих множителями и индексами при y
и z
. Это другое приближение к решению той же исходной системы ДУ. Логику своего приближения я описал. Это все к чему:
Именно такой алгоритм реализуют все рассмотренные нами языки, как визуальные, так и [внутренние] ЯП.
Во-первых, почему вы думаете, что по визуальной схеме составляются уравнения одного приближения, а не другого?
Во-вторых, язык не может реализовывать алгоритм, это делает программа на языке — какую программу напишем, такое приближение и будет реализовано.
Языки программирования должны быть такими, чтобы однозначно и ясно описывать алгоритмы.
Но выразительность языков для реализации тех или иных алгоритмов сильно отличается. Так, например, на языке визуальных схем алгебраические уравнения для численного интегрирования задаются не особо наглядно.
Ваша первая придирка про некорректность – отвергается. Реализация по определению должна быть корректной (в пределах аксиомы, конечно). Т.е. программа – это и есть алгоритм, но только в соответствующей форме представления.
Как определется термин "корректность реализации"? Как соответствие чего чему?
Не готов защищать SimInTech, не знаю его. Представители SimInTech сказали вам, по сути, то же, что пытаюсь сказать я: вам кажется, что есть две реализации одного алгоритма, а на самом деле у вас реализации разных алгоритмов (способов приближений).
Выше представлен алгоритм, который по умолчанию представляет последовательную форму алгоритма.
Замкнутый круг какой-то (выделено мной).
Просто потому, что языки нынче по умолчанию последовательные.
Что такое "последовательный язык"?
Поэтому мы уже изначально извращаем решение, применяя несоответствующий ему язык.
Что значит "извращаем решение"? Тьюринг-полный язык позволяет корректно реализовать любой алгоритм. В силу выразительных средств языка для тех или иных задач это может быть более или менее удобно для программиста, но это не повлияет на результат.
Что Вы на это скажите? Т.е. фактически речь идет о … природе уравнения. И тогда какая она? Т.е. может ли уравнение существовать «вне связи с вычислениями»?
Алгебраическое уравнение описывает множество значений переменных, каждый элемент которого при подстановке в уравнение дает верное равенство. Дифференциальное уравнение описывает множество функций, каждая функция из которого при подстановке в уравнение дает тождество. То есть уравнение — это описание множества, элементы которого называются решениями. Иначе говоря, решение — элемент множества значений неизвестных, удовлетворяющий ограничению, которое описано уравнением. Система уравнений — это несколько ограничений в виде уравнений, которые должны соблюдаться все вместе для любого решения системы.
Уравнения не описывают вычисления, система уравнений не описывает процесс вычислений.
Что такое "природа уравнения" вообще и "параллельная природа системы уравнений" в частности? Пока нет четкого определения, невозможно говорить о том, соответствует ли язык и реализация "природе уравнений".
Да. А решив в ручную рассматриваемое уравнение, Вы получите какой, как Вы думаете, результат?
Во-первых, я говорил о решении вручную алгебраических уравнений, которых выше приведено две системы, для обеих выписано решение. Какое из них "рассматриваемое"? Во-вторых, вопрос не в том, какое решение получится, а является ли решение вручную последовательной или параллельной реализацией? Реализация заключалась в том, что я переставлял члены уравнений. Процесс составления уравнений в реализацию входить не может, потому что это постановка задачи на их решение.
Замкнутый круг какой-то (выделено мной).
Чтобы выйти из него...
Мы имеем: 1) исходное математическое уравнение аттрактора, 2) визуальную реализацию аттрактора в SimInTech на рис.1, 3) реализацию аттрактора в SimInTech же, но на ЯП , на рис. 3, 4) решения на рис. 4 и рис.5.
Вопрос: какое из решений, глядя полученные на результаты, на Ваш взгляд правильное - на рис. 4 или рис.5? Ответ фактически не предусматривает вариантов, т.е. это должно быть или рис.4 или рис.5.
Никакого замкнутого круга, когда вы создали струкутрную схему в Simulink и SimInTech вы задали математическое описание задачи для динамического моделирования. По сути дела вы записали систему дифференциальных и алгебраических уравнений. Далее вы должны выбрать метод их интегрирования по времени, их там множество и они разные. Далее, необходимо задать максимальный и минимальный шаг интегриования, для адаптивных методов, либо задать постоянным шаг для методов с постоянным шагом. Так же вы должны указать, абсолютноую и относительную ошибку, котоая будет использоватся для измегнения шага во время расчета. И если в процессе расчет выяснится, что шаг минимальный, а ошибка больше заданной, вам вдается предупреждение, что заданная точность не обеспечивается.
А когда вы нажмете на пуск, мат ядро начнет расчет используя выбранный вам метод. Разные методы решения дают разный результат, это нормально. И разные решения будут правильными для разных методов интегрирования.
Вот например аттрактор из демопримеров SimInTech. Меняем способ расчета и получаем разное решения для одной и той же схемы. На картинке два варианта одного решения при разных настройках решается, для методов Эйлера и для Рунге-Курта.

Какое решение правильное? Наверное - никакое :))))), поскольку все они дискретные, а система непррерывная. Конечно некоторые более приближены к решению, другие совсем далеко. Аттрактор поэтому и назвыается аттрактором, что малое отклонение вызывает больше изменения. Малая ошибка приводит к разным результатам.
Цена ошибки