Лекция Стивена Вольфрама

ВНИМАНИЕ!!!

БЛОГ ПЕРЕЕХАЛ НА НОВЫЙ АДРЕС https://blog.wolframmathematica.ru

Онлайн машина вычисления знаний Wolfram|Alpha ®

Онлайн машина вычисления знаний Wolfram|Alpha ®

воскресенье, 23 декабря 2012 г.

Продвинутое задание функций или Mathematica на русском языке
NobelPrizeWithWolframAlpha.png
Продвинутое задание функций или Mathematica на русском языке
Общее количество использованных в посте встроенных функций или символов: 138

Список имен используемых встроенных функций и символов в порядке их появления в коде:
SetDelayed (:=) | Pattern (:) | Blank (_) | Sin | Power (^) | List ({...}) | Plus (+) | Times (*, ×) | Pi (π) | Rational | Graphics | RGBColor | EdgeForm | Thickness | Large | Dashing | Small | Disk | ArcSin | Image | RawArray | Rule (->, ->) | ImageSize | Automatic | ColorSpace | Interleaving | True | Set (=) | N | Log | Factorial (!) | Timing | Cos | Integrate (∫) | FullSimplify | Out (%) | Length | Optional (:) | Red | PlotRange | Max | Axes | Circle | Blue | OptionsPattern | OptionValue | Condition (/;) | Greater (>) | Sqrt | LessEqual (<=, ≤) | Names | PatternTest (?) | PrimeQ | Framed | Table | Alternatives (|) | Integer | I (i) | Mean | Real | Complex | Re | Im | ImageMeasurements | Less (<) | Total | String ("...") | Style | Row | Orange | Options | Plot | Function (&) | Slot (#) | AspectRatio | GoldenRatio | AxesLabel | None | AxesOrigin | AxesStyle | Background | ClippingStyle | ColorFunction | ColorFunctionScaling | Epilog | Exclusions | ExclusionsStyle | Filling | FillingStyle | Frame | False | FrameLabel | FrameStyle | FrameTicks | FrameTicksStyle | GridLines | GridLinesStyle | LabelStyle | Mesh | MeshFunctions | MeshShading | MeshStyle | PlotLabel | PlotLegends | PlotPoints | Full | PlotStyle | Prolog | RegionFunction | RotateLabel | Ticks | TicksStyle | WorkingPrecision | MachinePrecision | Symbol | NumericQ | CompoundExpression (;) | Thick | Dashed | Cubics | GeneratedParameters | InverseFunctions | MaxExtraConditions | Method | Modulus | Quartics | VerifySolutions | Complexes | Reals | Integers | C | Infinity | Solve | AbsolutePointSize | Point | Line | Equal (==) | ReplaceAll (/.)
Одним из самых важных навыков в работе с системой Mathematica, является задание функций, которые имели бы самый разный вид, и зависели бы от разного количества переменных (от буквально ни одной переменной до бесконечного их количества), при этом некоторые переменные могли бы иметь значения, которые используются по умолчанию, если не вводятся их конкретные значения, другие имели бы вид опций, как у многих встроенных в Mathematica функций, или имели бы строгие ограничения на свой тип...
В данном посте будет показано как программировать в Mathematica на русском языке, а для этого я покажу как создать функции, имена которых задаются кириллицей, соответствующие оригинальным встроенным функциям. При этом вы познакомитесь с тем, как собственно задавать самые разные типы и виды функций.
Создание стандартных функций нескольких переменных
Отсроченное задание функции
Задать стандартную функцию можно с помощью конструкции вида:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_1.png
В данной конструкции участвуют три крайне важных функции Mathematica, первая — это отсроченное присваивание SetDelayed (в короткой форме имеет вид :=), вторая — шаблонное выражение Blank[] (в короткой форме имеет вид _), третья — шаблон с присвоенным ему именем Pattern[name, object] (в короткой форме имеет вид name:object, или, если шаблонный объект представляет собой просто _, то name_).
Рассмотрим подробнее зачем они нужны и как работают.
Отсроченное присваивание := употребляется в виде:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_2.gif
оно присваивает выражение rhs (сокращение от “right hand side” — справа) в качестве отсроченного значения объекта (символа) lhs (сокращение от “left hand side” — слева), при этом выражение rhs остается в невычисленном виде. Как только в коде встречается объект lhs, он заменяется на выражение rhs, которое после этого вычисляется.
Шаблонное выражение _ употребляется в виде:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_3.gif
оно олицетворяет собой любое выражение, написанное на языке Mathematica. При этом, шаблон _h задает любое выражение, головная часть которого совпадает с h.
Шаблон с присвоенным ему именем name_ употребляется в виде:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_4.gif
он служит для “передачи” объекта внутри используемых функциональных конструкций (правил замен, задании функций и т. п.)
Что ж, суммируя сказанное выше, можно сказать, что стандартное задание функции одной переменной имеет вид:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_5.png
которое в полной форме (в той, которой его на самом деле “видит” и использует Mathematica) выглядит так:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_6.png
Задание функции в виде отсроченного присваивания, которое в общем случае имеет вид:
f[pattern]:=lhs
работает следующим образом:
как только Mathematica встречает при вычислении кода функцию с именем f, она проводит сопоставление ее аргумента expr (если она встретила выражение f[expr]) с шаблоном pattern. В том случае, если выражение-аргумент expr удовлетворяют шаблону pattern, то конструкция f[expr] заменяется на выражение lhs, в котором все символы с именем, соответствующем имени шаблонного выражения pattern заменяются на выражение expr, после чего полученная конструкция вычисляется и замещает исходное выражение f[expr].
Понятно, что если используется задание функции вида f[v_]:=lhs[v], то, как было сказано выше, любое выражение expr удовлетворит шаблону v_.
Приведу пример. Зададим функцию, которая вычисляет Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_7.png:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Попробуем вычислить ее значение от разных аргументов:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_8.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_9.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_10.gif
Как видно из рассмотренных выше примеров, действительно любой объект (число, символ, картинка) удовлетворяют шаблону x_ и Mathematica легко работает со всеми выражениями, что демонстрирует необычайную гибкость ее языка.
Задание функции многих переменных полностью аналогично. Скажем, зададим функцию 3 переменных:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_11.gif
Создание функции, которая “помнит” свои вычисленные ранее значения
Если изменить отсроченное задание функции следующим образом:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_12.png
то однажды вычислив значение в некоторой “точке” (значение при некотором значении аргумента, аргументом может быть не обязательно число и необязательно точка в привычном ее понимании...), функция f будет помнить (правда только в рамках данной сессии Mathematica) это значение (здесь была использована функция Set (в короткой форме имеет вид =), которая позволяет присвоить некоторому символу некоторое значение).
Такое задание функции способно сэкономить массу времени, если вычисление правой части отсроченного присваивания функции занимает много времени, но при этом требует больше памяти.
Пример (время вычисления некоторой команды можно узнать с помощью функции Timing):
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_13.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_14.gif
Из примера видно, что однажды вычислив значение функции в точке, при таком задании функции, в следующий раз оно не займет никакого времени.
Внимание! Такое присваивание может сыграть с вами злую шутку. Так как значение функции в данной точке хранится в памяти, оно становится нечувствительным к изменению собственно правой части lhs[v] функции:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_15.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_16.gif
Абсолютное задание функции
В том случае, если использовать вместо функции SetDelayed (:=) функцию Set (=) в задании функции:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_17.png
то выражение справа lhs[v] будет вычислено сразу, после чего в него будут подставляться значения аргументов функции при встрече в дальнейшем выражения вида f[expr] в коде. Такая форма задания функции способна сэкономить время в том случае, если вычисление выражения lhs[v] трудоемко и по сути не зависит от конкретного значения аргумента v.
Сравним отсроченное и абсолютное задания функций.
Вычисление выражения lhs[v] не зависит от значения v напрямую:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_18.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_19.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_20.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_21.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_22.gif
Вычисление выражения lhs[v] зависит от значения v напрямую:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_23.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_24.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_25.gif
Из двух примеров выше можно сделать два важных вывода:
Внимание! Абсолютное задание можно использовать только в том случае, если вычисление конструкции lhs[v] не зависит напрямую от переменной v. Если это не так, то ответ может быть не верен.
В случае применения абсолютного задания функций, вы получаете возможность заметно ускорить свои вычисления в ситуации, когда вычисление правой части задания функции не зависит напрямую от аргумента.
Задание функции, некоторые аргументы которой имеют значения по умолчанию
В некоторых ситуациях удобно использовать функции, некоторые переменные которых имели бы значения по умолчанию. Задать такого рода переменную для функции можно с помощью функции Optional, которая употребляется следующим образом:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_26.png
Зададим функцию, которая строит круг или окружность, при этом по умолчанию центр этого круга (окружности) находится в точке (0, 0), он (она) имеет радиус равный 1, а также имеет красный цвет:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_27.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_28.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_29.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_30.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_31.gif
Очевидным неудобством работы с такими функциями является то, что если вы хотите использовать много аргументов со значениями по умолчанию, то использовать эти значения у вас получится только в том случае, если они стоят справа от тех аргументов, которым вы придаете какое-то значение. Если же вы меняете какое-то значение по умолчанию на конкретное, то вам придется в обязательном порядке явно указывать и все значения, что стоят левее от него. Таким образом, данное задание очень чувствительно к порядку следования аргументов, а значит переменные со значениями по умолчанию должны располагаться в порядке убыли частоты их использования, если же частота примерно одинакова, то целесообразность задания таких функций резко падает.
Задание функции с опциями
Для того, чтобы избавиться от проблемы, связанной с использованием переменных, которые имеют значения по умолчанию, которая рассматривалась выше, служат функции, которые имеют так называемые опции. Большинство встроенных функции Mathematica имеют те или иные опции.
Для того, чтобы задать опции для некоторой функции, служат встроенные функции OptionsPattern и OptionValue, смысл работы с которыми ясен из следующего примера: реализуем ту же функцию, что и ранее (строящую круг или окружность, с центром по умолчанию в точке (0, 0), радиуса 1, красного цвета), только все значения по умолчанию теперь задаются опциями:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_32.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_33.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_34.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_35.gif
Задание функции с наложенными на аргументы условиями
Для того, чтобы наложить на какой-то аргумент функции ограничение, служит функция Condition (имеющая короткую форму /;).
Скажем, создадим функцию, которая вычислялась бы, только если ее аргумент больше 2:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_36.gif
Или функцию, которая вычислялась бы, если ее аргумент является списком, состоящим не более чем из 4 элементов:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_37.gif
В примере выше также использовался шаблон с указанием головной части выражения List (x_List), который задает любой список.
Такого рода шаблоны могут быть самыми разными:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_38.gif
Также вы можете пользоваться всевозможными тестовыми функциями, которые проверяют, обладает ли выражение, определенным свойством. Это делается с помощью функции PatternTest (имеющая короткую форму ?), стандартный синтаксис которой выглядит следующим образом:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_39.png
Все тесты (как видно из кода ниже, их 108) в системе Mathematica это функции, которые оканчиваются на заглавную букву Q:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_40.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_41.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_42.gif
Скажем, вот так просто можно создать функцию, которая будет работать только с простыми числами:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_43.gif
Альтернативные шаблоны
В некоторых случаях функция должна работать с выражением, если оно удовлетворяет одному из заданных шаблонов. Реализовать подобную конструкцию можно с помощью функции Alternatives (имеющая короткую форму |).
Ниже представлена функция, аргумент которой может быть либо списком, либо целым числом, большим 4:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_44.gif
Множественное задание функций
В Mathematica у вас есть возможность задать определения функции,  которые будут применяться в разных ситуациях. Сделать это можно с помощью применения шаблонов с головными частями выражений, а также с использованием ограничений, наложенных на переменные.
В примере ниже создана функция, которая по разному обрабатывает входные данные в зависимости от их типа:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_45.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_46.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_47.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_48.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_49.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_50.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_51.gif
Пример - композиция из описанных ранее способов задания функции и ее аргументов
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_52.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_53.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_54.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_55.gif
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_56.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_57.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_58.gif
Программирование в Mathematica на русском языке
Теперь, когда мы знаем о том, как задаются функции, можно поставить перед собой такую задачу: сделать так, чтобы можно было программировать в Mathematica на русском языке с соблюдением основных парадигм: встроенные функции капитализированы и их названия в точности соответствуют действию, которое они осуществляют.
Для этого, нужно сделать русские аналоги встроенных функций.
Начнем с функции Plot, на русском языке ей будет соответствовать функция График. Синтаксис функции Plot имеет вид:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_59.png
Ее русский аналог будет полностью аналогичен.
Начнем с того, что узнаем список всех опций функции Plot и их значения по умолчанию, это можно сделать с помощью функции  Options:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_60.gif
Теперь создадим этот список на русском языке (здесь опущены некоторые опции, которые, по опыту, употребляются крайне редко при построении графика):
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_61.gif
Теперь зададим связь русских названий с встроенными аналогами:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_62.gif
Теперь мы можем задать русский аналог функции Plot:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Также нам потребуются некоторые стандартные обозначения толщины и цвета линий:
Нажмите, чтобы получить возможность скопировать код Wolfram Mathematica
закрыть
Аналогично зададим функцию Решить — русский аналог функции Solve, АбсолютныйРазмерТочкиAbsolutePointSize,  ТочкаPoint, ЛинияLine:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_63.gif
Попробуем создать некоторый график:
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_64.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_65.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_66.gif
Mathematica_na_russkom_jazyke_ili_prodvinutoe_zadanie_funkcij_67.gif
Таким образом, в Mathematica возможно создать пакет, который позволит программировать на обычном русском языке, подобно тому, как это делалось в СССР, скажем на языке АЛМИР-65.
Если у кого-то из вас появится желание развить данную идею, то вполне возможно сделать так, чтобы Mathematica работала на русском языке.

Блог принадлежит “Русскоязычной поддержке Wolfram Mathematica
При любом использовании материалов блога, ссылка на блог обязательна.
SpikeyСоздано с помощью Wolfram Mathematica 9

1 комментарий:

  1. Идея подобным образом русифицировать Mathematica, конечно, весьма забавна, но не более того. Скорее это можно рассматривать как хороший пример демонстрации возможностей системы. Спасибо за пост, Роман!

    ОтветитьУдалить