В
качестве еще одного интересного примера,
позволяющего освоить приемы программирования в
Maple напишем процедуру вычисляющую по заданной
функции F(x) функцию F(a*x+b) - так называемый оператор
аффинного преобразования переменной (назовем
его aff - оператор).
> aff:=proc(f::procedure,a::numeric,b::numeric)
local x;
unapply(f(a*x+b),x);
end;
Проверим
> aff(sin,2,1);
Построим график (рис. 70).
> plot(%,0..Pi);
Рис. 70
Мы видим, что процедура работает. Однако,
возьмем функцию от двух переменных
> A:=(x,y)->x*sin(y);
> aff(A,2,1);
Error, (in A) A uses a 2nd argument, y,
which is missing
Теперь у нас ошибка, поскольку в записи
процедуры мы указали только одну переменную для
формального параметра. Используем такой прием.
Внутри процедуры aff введем процедуру
преобразования одного из аргументов
вспомогательной глобальной функции F с
произвольным числом аргументов. А затем применим
оператор подстановки для замены вспомогательной
функции на фактическую. Теперь процедура будет
выглядеть так
> aff:=proc(f::procedure,a::numeric,b::numeric)
global F, g, h;
subs({'F'=f,g=a,h=b},x->F(g*x+h,args[2..-1]));
### WARNING: `g` is a lexically scoped global
### WARNING: `h` is a lexically scoped global
### WARNING: `F` is a lexically scoped global
end;
Здесь args[2..-1] перечисляет все аргументы
функции, начиная со второго.
> aff(sin,2,1);
> %(x);
Теперь проверим, как работает эта
программа для функции от двух переменных
> Aa:=aff(A,2,1);
> Aa(x,y);
Теперь процедура работает для функций
от нескольких переменных. Обобщим далее оператор
сдвига, чтобы он мог преобразовывать любую
переменную функции. Вторым параметром процедуры
теперь будет номер сдвигаемой переменной, а
третьим и четвертым - параметры преобразования.
> aff:=proc(f::procedure,n::posint,a::numeric,b::numeric)
global F,m,g,h;
subs('F'=f,m=n,g=a,h=b,proc() F(args [1..m-1],g*args[m]+h,args[m+1..-1]) end);
### WARNING: `m` is a lexically scoped global
### WARNING: `g` is a lexically scoped global
### WARNING: `h` is a lexically scoped global
### WARNING: `F` is a lexically scoped global
end;
Проверим написанную процедуру для
функции от двух переменных
> Aa2:=aff(A,2,2,1);
> Aa2(x,y);
Построим график (рис. 71).
> plot({A(1,y),Aa2(1,y)},y=0..10);
Рис. 71
|