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() найдет решение.