Scilab/Практикум. Часть 1
В данном разделе будут представлены конкретные примеры и способы их решения в среде Scilab. Целью данного раздела является закрепление уже накопленных вами знаний, а также попутное изучение возможностей среды.
Практически для всех тривиальных задач в системе заготовлены стандартные функции. Перед тем, как мы начнем их разбирать, возьмите за правило:
Если в системе существует функция, которая реализует по крайней мере часть задачи, которую вы решаете, всегда используйте эту функцию и не прибегайте к программированию.
Дело в том, что все функции, входящие в стандартную комплектацию, тестируются разработчиками и оптимизированы под среду. В этом случае любой ваш программируемый алгоритм будет всегда менее эффективен по скорости, чем уже готовый. Хотя возможно это и не всегда так, но поверьте, что затраты времени на «придумывание велосипеда» в большинстве случаев не окупаются.
Простые выражения
[править]Для начала попробуем повычислять простые выражения.
Пример 1
Вычислить
Данное выражение является сложным и требует предварительного разбора. Конечно, можно ввести данное выражение одной строкой в командное окно, но в данном примере мы вычислим его по частям для лучшего понимания материала.
Для начала необходимо определиться с очередностью выполняемых действий. При несложном разборе очередность такова:
- Рассчитать числитель дроби функции синуса;
- Рассчитать знаменатель дроби функции синуса;
- Числитель поделить на знаменатель;
- Найти синус от результата 3;
- Рассчитать выражение степени;
- Возвести результат 4 в степень результата 5.
Описанный алгоритм отражает следующий листинг
-->5*6*sqrt(94-56)+6*sqrt(291+2); // Вычисляем числитель
-->ans/(6*41.25^2*sqrt(25*26+1)); //Вычисляем знаменатель
-->sin(ans); // Вычисляем синус
-->ans^(log10(36.25)+log(34.25)) // Возводим в степень
ans =
8.715D-16
Обратите внимание на то, что мы используем для хранения промежуточных результатов переменную ans. В этом примере исходный алгоритм немного облегчен, так, в 4 строке листинга мы объединили пункты 4 и 5.
В этом примере мы использовали две новые функции:
- log10() — вычисляет десятичный логарифм;
- log() — вычисляет натуральный логарифм.
В среде нет функции, которая реализует логарифм по произвольному основанию, но это не является проблемой. По свойству логарифма
тогда, например, логарифм 4 по основанию 2 можно вычислить так
-->log10(4)/log10(2) // через десятичный логарифм
ans =
2.
-->log(4)/log(2) // через натуральный логарифм
ans =
2.
Стоит упомянуть, что в среде есть также встроенная функция для вычисления логарифмов по основанию 2 — log2().
Пример 2<br\> Вычислить<br\>
В примере мы вновь возвращаемся к проблеме вычисления логарифма по произвольному основанию, однако применение свойства в данном случае напрямую серьезно усложнит само выражение. В данном случае рациональнее всего объявить собственную функцию, которая бы вычисляла логарифмы при любом основании.
Воспользуемся свойством логарифма и объявим функцию logn().
-->deff('out=logn(m,n)','out=log10(m)/log10(n)')
// Имея теперь функцию, легко записать исходное выражение
-->(logn(4,6)+logn(9,7))/(logn(32,4^-1)*logn(500,5))
ans =
- 0.1971180
Алгебра
[править]В рамках данного раздела мы рассмотрим способы решения самых распространенных задач алгебры.
Решение алгебраических уравнений
[править]Найти корни уравнения
Ранее мы решали подобную задачу. Напомним, что для решения линейных уравнений в среде имеется функция roots(), которая принимает в качестве аргумента объект полином. Практически все действия выполняет за вас среда, необходимо только объявить полином. Напомним, что полином объявляется функцией poly(). В нашем случае полином составляется из коэффициентов, которые нужно переписать в обратном порядке.
-->p=poly([21 -7 -8 2],'x','c')
p =
2 3
21 - 7x - 8x + 2x
-->roots(p)
ans =
4.2415355
- 1.6987739
1.4572384
Функция roots() имеет флаг, определеяющий используемый алгоритм:
- 'f' — расчет по алгоритму Дженкинса-Трауба (RPOLY-алгоритм); используется по умолчанию;
- 'e' — расчет через собственные вектора сопровождающих матриц.
RPOLY-алгоритм используется главным образом для поиска действительных и комплексных корней с порядком полинома, не превышающем 100. Второй алгоритм существует как альтернатива ему. В большинстве случаев RPOLY-алгоритма достаточно для решения многих задач, поэтому пользоваться флагом приходится редко.
Для примера, найдем корни следующего полинома по второму алгоритму
-->roots(poly([-1 0.6 0.4 1],'x','c'),'e')
ans =
- 0.5576818 + 1.0425361i
- 0.5576818 - 1.0425361i
0.7153636
Решение систем уравнений
[править]Решение трансцендентных уравнений
[править]Трансцендентные уравнения решаются преимущественно численными методами. Обычно этот процесс заключается в выборе интервала, в который попадает по крайней мере один корень уравнения, а затем производится численное приближение к этому корню.
В Scilab определена всего одна функция для решения трансцендентных уравнений fsolve(). Если возможности этой функции по какой-либо причине не устраивают, то обычно пишут собственную функцию, реализующую некоторый численный метод.
Найти корни
// Объявляем функцию
-->deff('y=f(x)','y=exp(x)/10-2*(x-1)^2-x^(2/3)')
//Вызываем функцию
-->fsolve(6,f)
ans =
6.4401965
Для решения трансцендентных уравнений необходимо правильно выбирать приближение, для чего требуется представлять левую часть уравнения как функцию и строить график. Если начальное приближение очень далеко от корня, то нет гарантии, что функция fsolve() найдет решение.