Итерационное решение для неизвестных в задаче о жидкости - PullRequest
2 голосов
/ 14 декабря 2010

Я инженер-механик с вопросом информатика. Вот пример того, с какими уравнениями я работаю:

x = & radic; ((y-z) & times; 2 / r)
z = f & times; (L / D) & times; (x / 2g)
f = что-то сумасшедшее с х в нем
и т. д. (в нем больше уравнений с x)

Ситуация такова:

Мне нужен r, чтобы найти x, но мне нужен x, чтобы найти z. Мне также нужен x, чтобы найти f, который является частью поиска z. Поэтому я угадываю значение для x, а затем использую это значение, чтобы найти r и f. Затем я возвращаюсь и использую значение, которое я нашел для r и f, чтобы найти x. Я продолжаю делать это до тех пор, пока предположение и расчет не совпадут.

Мой вопрос:

Как мне заставить компьютер сделать это? Я использовал mathcad, но пример на другом языке, например C ++, подойдет.

Ответы [ 5 ]

2 голосов
/ 14 декабря 2010

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

Например: *. * 1005

 x_0 = ..., f_0 = ..., r_0 = ...
 x_1 = ..., f_1 = ..., r_1 = ...

 ...

 x_n = ..., f_n = ..., r_n = ...

Теперь у вас есть представление о том, что вы должны реализовать (даже если вы не знаете как ). Если вам не удается найти выражение в закрытой форме для одного из x_i, r_i или любого другого_i, вам нужно будет численно решить одномерные уравнения. Это будет означать больше работы.

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

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

1 голос
/ 29 февраля 2012

Простой ответ на ваш вопрос - это псевдокод:

X = startingX;
lastF = Infinity;
F = 0;
tolerance = 1e-10;
while ((lastF - F)^2 > tolerance)
{
    lastF = F;
    X = ?;
    R = ?;
    F = FunctionOf(X,R);
}

Это может не соответствовать вашим ожиданиям.Он может дать правильный, но бессмысленный ответ или бесконечный цикл между альтернативными неправильными ответами.

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

В общем, стоит подумать о том, как вы можете превратить свою проблему в более легкую.

По моему опытуЛучше представить вашу проблему как одномерную ограниченную задачу поиска корней и использовать Метод Брента , если вы можете

Следующий худший вариант - многомерная минимизация с чем-то вроде BFGS.

Итеративные решения ужасны, но их легче решать, когда вы думаете о них как о X2 = f (X1), где X - входной вектор, и вы пытаетесь уменьшить разницу между X1 и X2.

1 голос
/ 04 января 2011

Если вы используете Mathcad, он имеет встроенную функциональность. Он называется решить блок .

Начните с ключевого слова "дано"

С учетом

определить значения догадки для всех неизвестных

х: = 2 F: = 3 г: = 2 ...

определите ваши ограничения

x = √ ((y-z) × 2 / r)

z = f × (L / D) × (x / 2g)

f = что-то сумасшедшее с х в нем

и т. Д. (Есть еще уравнения с x в нем)

рассчитать решение

find (x, y, z, r, ...) =

Обратитесь к справке Mathcad или Quicksheets за примерами точного синтаксиса.

1 голос
/ 14 декабря 2010

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

http://communities.ptc.com/index.jspa

0 голосов
/ 14 декабря 2010

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

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

Когда вы пишете свой код, постарайтесь организовать его в функции, которые зависят только от параметров, которые вы передаете подпрограмме. Поэтому напишите подпрограмму, которая принимает значения для y, z и r и возвращает вам x. Сделайте другой, который принимает в f, L, D, G и возвращает z. Теперь у вас есть тестируемые процедуры, которые вы можете проверить, чтобы убедиться, что они вычисляются правильно. Проверьте входные значения для ваших подпрограмм в подпрограммах - например, при вычислении x вы получите ошибку деления на 0, если передадите 0 для r. Подумайте, как вы хотите справиться с этим.

Если вы собираетесь решать эту проблему в интерактивном режиме, вам потребуется метод, который на основе результатов одной итерации определит, какими будут значения для следующей итерации. Это также должно быть заключено в подпрограмму. Теперь, если вы используете язык, который позволяет возвращать только одно значение из подпрограммы (это наиболее распространенные языки вычислений C, C ++, Java, C #), вам нужно упаковать все свои переменные в некую структуру данных, чтобы вернуть их , Вы можете использовать массив вещественных или двойных чисел, но было бы лучше выбрать объект, а затем вы можете ссылаться на переменные по их имени, а не по их положению (меньше вероятность ошибки).

Другим аспектом итерации является знание того, когда остановиться. Конечно, вы сделаете это, когда получите решение, которое сходится. Сделайте это решение в другой подпрограмме. Теперь, когда вам нужно изменить критерии сходимости, в коде есть только одно место для перехода. Но вам нужно рассмотреть другие причины остановки - что вы делаете, если ваше решение начинает расходиться вместо того, чтобы сходиться? Сколько итераций вы позволите прогону пройти, прежде чем сдаться?

Другим аспектом итерации компьютера является ошибка округления. Математически 10 ^ 40/10 ^ 38 равно 100. Математически 10 ^ 20 + 1> 10 ^ 20. Эти утверждения не соответствуют действительности в большинстве расчетов. Ваши расчеты, возможно, должны принять это во внимание, или вы получите цифры, которые являются мусором. Это пример сквозной проблемы, которая не поддается инкапсуляции в подпрограмме.

Я бы посоветовал вам взглянуть на язык Python и расширения pythonxy.com. На связанных форумах есть люди, которые могут помочь вам научиться выполнять итеративное решение системы уравнений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...