Практикум по компьютерной геометрии

Детализация

Разбить на страницы
Показывать лекцию целиком

Выражения - универсальный конструктор в Mathematica

Напомним, что f[x,y,...] - универсальный (канонический) вид выражения, где x, y,... могут быть выражениями или атомарными объектами (числами, символами, строками).

Последовательность аргументов x, y, ... называется Sequence.

In[1] :=f [Sequence [x,у,z] ]
Out[1]=f[x,y,z]
In[2]:=f [x, Sequence [y,z],w]
Out[2] = f [x,y,z,w]

f называется заголовком ( Head ) выражения f[x, y, ...]. Заголовок f может быть как символом, так и более сложным выражением (в приведенных ниже примерах заголовки - это f[2] и (a+b) ):

In[3]:=f [2][х,у] 
      (а + Ь)[х]
Out[3] =f[2][х, у]
Out[4] =(а+b)[х]

Еще пример: заголовком является InterpolatingFunction[{{0.,3.}},<>] (команда First - взятие первого элемента списка):

In[5]:=
     у/.First[NDSolve[{y''[х] == -у[х], у[0] == у'[0]==2} , 
      y,{х,0,3}]] 
     f[x] 
     f[2.3] 
     Plot[f[x],{x,0,3}]
Out[5] =InterpolatingFunction [{{0.,3.}}, <>]
Out[6] =InterpolatinqFunction [{f0.,3.}}, <>][х]
Out[7] =0.158858
In[9] := Clear [f]

Команда FullForm позволяет представить выражение в каноническом виде:

$$In[10]:=FullForm [\frac{x+y-zw)}{a+(b-c)^{\frac12}}] $$
Out[10] =
     Times[Power[
       Plus[a,Power[Plus [b, Times[-1, c]],Rational[1, 2]]],
         -1],Plus[x,y,Times[-1,w,z]]]

Выражения имеют структуру дерева:

$$In[11]:= TreeForm[\frac{x+y-zw}{a+(b-c))^{\frac12}}] $$

Список, как частный случай выражения, тоже имеет структуру дерева:

In[12]:=TreeForm[{a,{b,с},d}]

Если в одной скобке стоит последовательность выражений $$expr_1; expr_2; \dots$$, разделенных точкой с запятой, то на самом деле там имеется одно выражение $$CompoundExpression[expr_1; expr_2; \dots ] $$ . Например, последовательность выражений

In[13]:=х=2; у=х2;
        y
0ut[14]=4

представляет собой одно выражение

In[15]:=CompoundExpression[х=2,у=х2,у]
Out[15]=4
In[16]:=Clear[x,у]

Уровни выражения expr

Каждое выражение разбито на уровни. Посмотреть на них можно с помощью команды Level[expr,levelspec], где levelspec описывает интересующие уровни:

$$In[17]:=TreeForm [\frac{x+y-zw}{a+(b-c)^{\frac12}}] $$$$In[18]:= Table [Level \left [ \frac{x+y-zw}{a+(b-c)^{\frac 12}} , \{i\}\right ], \{i, 0, 7\}]\\ Out[18] =\\ \left \{ \left \{ \frac{x+y-wz}{a+\sqrt{b-c}}\right \},\left \{ \frac{1}{a+\sqrt{b-c}}, x+y-wz \right \}, \{a+\sqrt{b-c}, -1 x, y, -wz\},\\ \begim{matrix} \{a, \sqrt{b-c}, -1, w,z\}, \{b-c, \frac 12\}, \{b, -c\}, \{-1, c\}, \{\}\} \end{matrix}$$

levelspec ={n} - только n -й уровень (нулевой уровень - само выражение):

$$In[l9]: = Level \left [ \frac{x+y-zw}{a+(b-c)^{\frac 12}}, \{3\} \right]\\ Out[l9]=\{a, \sqrt{b - с} , -1, w, z\}$$

levelspec = n - все уровни от 1-го до n -го (нулевой уровень не включен):

$$In[20]: = Level \left [ \frac{x+y-zw}{a+(b-c)^{\frac 12}}, 3\right]\\ Out[20] = \{a, \sqrt{b - с} , а + \sqrt{b - с} , -1,\\ \begin{matrix} \frac{1}{a+\sqrt{b-c}^{\frac 12}}, х, у, -1, w, z, -w z, x+y-wz\} \end{matrix}$$

levelspec = {n, m} - уровни с номерами между n и m:

$$In[21]:= Level \left [\frac{x+y-zw}{a+(b-c)^{\frac 12}}, \{3, 5\}] $$ $$Out[21] = \{а, b, -с, b - с, \frac 12, \sqrt{b - с} , -1, w, z\} $$

levelspec = {n, Infinity} - уровни с номерами, не меньшими, чем n:

$$In[22]: = Level \left [ \frac{x+y-zw}{a+(b-c)^{\frac 12}} , \{0, Infinity\} \right]\\ Out[22] =\{a, b, -1, с, -с, b - с, \frac 12, \sqrt{b - с} , a + \sqrt{b - с} , -1,\\ \begin{matrix} \frac{1}{a+\sqrt{b-c}}, x, у, -1, w, z, -wz, x + y-wz, \frac{x+y-wz}{a+\sqrt{b-c}}\} \end{matrix}$$

Заголовок выражения

Заголовок выражения f[x, y, ...] - это f, заголовки атомарных объектов называются их типами.

In[23]:=Head[f [х, у] ]
Out[23] = f
In[24]: = Head[x + у]
Out[24] = Plus

Типы атомарных объектов:

  • целые числа - Integer ;
  • рациональные числа - Rational ;
  • вещественные числа - Real ;
  • комплексные числа - Complex ;
  • символы - Symbol ;
  • строки - String.
  • In[25]:= {Head[l] ,  FullFormfl]}
             {Head[l/2], FullForm[l / 2] } 
             {Head[l.l],  FullForm[l.l] } 
             {Head[l + i], FullForm[l+ i]} 
             {Head[x],  FullForm[x]} 
             {Head["abc"],  FullForm["abc"]}
    Out[25]= {Integer,   1}
    Out[26]= {Rational,  Rational [1,  2]}
    Out[27]= {Real,   1.1'}
    Out[28] = {Complex,  Complex[l,   1]}
    Out[29] = {Symbol,  x}
    Out[30]= {String,   "abc"}

    Интересный пример. Сравните:

    In[31] : = {Head [x + i] ,  FullForm [x + u] } 
    Out[31]= {Plus,  Plus [Complex [0,   1],  x] }

    Замена заголовка. Осуществляется командой Apply или @@:

    In[32]: = Apply[g, f[x,у]]
    Out[32] = g[x, у]
    In[33]: = Head[{a,b,с,d}]
    Out[33] = List
    In[34]: = Apply[Plus,{a,b,c,d}] 
    Out[34] =a+b+c+d 
    In[35]:=Plus@@{a,b,c,d}
    Out[35] = a + b + с + d

    Команда Apply не действует на атомарных объектах:

    In[36]: = х = Apply [List,  l]
    Out[36] = 1
    In[37]: = Head[x]
    Out[37] = Integer
    In[38]: = х = Apply [List,  1/2]
    Out[38] = 1/2
    In[39]:=Head[x] 
    Out[39]= Rational 
    In[40]: = x = . 
    In[41]:=Head[x]
    Out[41] = Symbol

    Преобразование типов атомарных объектов

    Важно уметь переходить от одного типа к другому.

    Команда IntegerString[integer] преобразует целое число integer в строку (знак игнорируется):

    In[42]:= IntegerString [25 361]  // InputForm
    Out[42] = "25361"

    Команда FromDigits[str] преобразует строку цифр в целое число, а также список цифр в целое число. Чтобы преобразовать число в список цифр, можно использовать команду IntegerDigits:

    In[43] :=FromDigits ["43476"]
             FromDigits[{5,  2,  3,  8}] 
             IntegerDigits[374 632]
    Out[43] = 43476
    Out[44] = 52 3 8
    Out[45]={3, 7, 4, 6, 3, 2}

    Команда ToString[expr] преобразует выражение expr в строку. При этом форму вывода form можно указать в качестве второго аргумента: ToString[expr,form]:

    In[46] := ToString [x2]
              ToString[x2]  // InputForm
    Out[46] = 2
    Out[47] = "2\nx"
    In[48]:=ToString [x2 , InputForm]
            ToString[x2, InputForm] // InputForm
    Out[48]=x^2 
    Out[49] ="х^2"

    Команда ToExpression[str] преобразует строку в соответствующее выражение. Модифицированная команда ToExpression[str,form] преобразует строку в выражение, используя при этом правило вывода form:

    In[50] := ToExpression [ "Sin [x] "]
    Out[50]= Sin [x]
    In[51] := ToExpression [ "sin (x) " ,  TraditionalForm]
    Out[51] = Sin [x]
    In[52] := ToExpression [ "\sin (x) ", TeXForm]
    Out[52] = Sin [x]

    Команда Symbol[str] превращает строку в символ:

    In[53]:= Symbol ["х"]
    Out[53]=x

    Строка из 10 символов:

    In[54] := Table [Symbol ["x" <> ToStringfi]] , {i, 10}]
    Out[54]={xl,  х2,  хЗ,  х4,  х5,  хб,  х7,  х8,  х9,  х10}
    In[55] := Table [ToExpression ["х" <> ToString[i] ] , {i, 10}]
    Out[55]={xl,  x2,  хЗ,  х4,  х5,  хб,  x7,  x8,  x9,  x10}

    Команда SymbolName[symbol] превращает символ symbol в строку - имя этого символа:

    In[56] := SymbolName [х]  // InputForm
    Out[56] = "x"

    Доступ к фрагментам выражения

    Доступ к фрагментам выражения осуществляется как к элементам списка (заголовок Head - нулевой элемент):

    $$In[57]:= TreeForm [\frac{x+y-zw}{a+(b-c)^{\frac12}}] $$$$In[58]:=\left \{ \left ( \frac{x+y-zw}{a+(b-c)^{\frac 12}} \right ) [[0]], \left ( \frac{x+y-zw}{a+(b-c)^\frac12 \right )[[1]], \left ( \frac{x+y-zw}{a+(b-c)^\frac 12}\right ) [[2]],$$ $$\begin{matrix} \left ( \frac{x+y-zw}{a+(b-c)^ \frac 12} \right ) [[3]] \right \} \end{matrix}\\ Part::partw: Part\; 3\; of \frac{x+y-wz}{a+ \sqrt{b-c}} does\; not\; exist. >>\\$$ $$Out[58] = \left \{Times, \frac{1}{a+ \sqrt{b-c}}, x+y-zw, \frac{x+y-zw}{a+ \sqrt{b-c}} [[3]] \right \}$$ $$In[59]:=TreeForm \left [ \left ( \frac{x+y-zw}{a+(b-c)^{\frac 12}} \right ) [[2]] \right ]$$ $$In[60]:=\left \{ \left ( \frac{x+y-zw}{a+(b-c)^{ \frac 12} \right ) [[2,1]], \left ( \frac{x+y-zw}{a+(b-c)^{\frac 12}} \right )[[2,2]], \left ( \frac{x+y-zw}{a+(b-c)^{\frac 12}} \right ) [[2,3]],\\ \begin{matrix} \left ( \frac {x+y-zw}{a+(b-c)^{\frac 12}} \right ) [[2,4]] \right \}\\ \end{matrix} $$
    Patt::partw: Part 4 of x + y-wz does not exist. >>
    $$Out[60]=\left \{x, y, -wz, \frac{x+y-zw}{a+\sqrt {b-c}} [[2, 4]] \right \}$$

    Символы и контексты (Contexts)

    Полное имя каждого объекта состоит из двух частей: контекста ( context ) и короткого имени ( short name ). Полное имя объекта пишется в следующем виде: context'short name. Обратная кавычка ' называется меткой контекста ( context mark ).

    In[61] : = abc'x
               abc'x =10 
               abc'х2
    Out[6l]=abc'x 
    Out[62]=10 
    Out[63]=100

    Символы с одинаковым именем, но разными контекстами - различны:

    In[64]: = х == х
              а'х==b'х
              а'х==а'у
    Out[64] =True
    Out[65] =а'х==b'х
    Out[66] =а'х==а'у

    В каждый момент времени фиксирован так называемый текущий контекст, имя которого находится в переменной $Context:

    In[67]:=$Context
    Out[67]=Global'

    Объекты текущего контекста можно называть их короткими именами:

    In[68]:=х==Global'х
    Out[68]=True

    Контексты аналогичны директориям (папкам) с файлами:

  • текущий контекст - текущая папка, к файлам которой можно обращаться по их именам, не указывая полный путь;
  • подобно тому как папки могут содержать другие папки, контексты могут быть сложными:
  • In[69]:=a'b'x==а'с'х 
    Out[69]=а'b'х==а'с'х

    Отметим, что в момент запуска Mathematica устанавливается контекст Global'. Пользовательские символы относятся именно к этому контексту. Однако, скажем, Pi имеет контекст System'. Чтобы в этом убедиться, примените к Pi команду Context[]:

    In[70]:= Context [x] 
             Context[Pi]
    Out[70] = Global'
    Out[71] = System'

    В Mathematica реализована возможность пользоваться краткими именами объектов, относящихся к разным основным контекстам. Все такие контексты перечислены в списке $ContextPath. Полный список имеющихся контекстов можно получить, выполнив команду Contexts[]:

    In[72]:=$ContextPath // InputForm
    Out[72] =
       {"PacletManager'", "WebServices'" , "System'", "Global'"}

    Если в $ContextPath встречаются два контекста, содержащих один и тот же символ, скажем x, то при обращении к x он интерпретируется в соответствии с тем контекстом, который встречается первым в списке $ContextPath (все остальные одноименные символы "затеняются"):

    In[73]:=$ContextPath={"а'","b'"}≈Join≈ $ContextPath 
             {а"х, b"х} 
             Context[x]
    Out[73]=
        {a", b', PacletManager', WebServices', System', Global'}
    Out[74]={x,b'x] 
    Out[75]=a'

    Таким образом, здесь x воспринимается как $$a'x$$. Если такой x больше не нужен, можно выполнить команду $$Remove[x] $$, и символ a'x будет уничтожен. Теперь x будет восприниматься как $$b'x$$:

    In [76]:=Remove [x] 
             Context[x]
    Out[77]=b'
    In[78]:=Remove [x] 
            Context[x]
    Out[79]=Global'
    In[80]:=$ContextPath=Drop[$ContextPath,2]
    Out[80]={PacletManager',WebServices',System',Global'}

    Пакеты (Packages)

    Пакеты - расширения Mathematica, написанные на языке Mathematica и содержащие определения, которые "учат" Mathematica работать в соответствующих областях. Загрузить такой пакет можно командой <<package или Needs[package], где package имеет такой же формат, как context:

    In[81]:=<< VectorAnalysis'

    Одной из функций, реализованных в этом пакете, является вычисление дивергенции $$Div[\xi] $$ (в заданной координатной системе) или в координатной системе coorsystem с помощью команды $$Div[\xi, coorsystem] $$:

    In[82] :=SetCoordinates [Cartesian [x, y, z] ]
                 (* задает  текущую  систему координат*)
                Div[{x2,y2,  z2}]
    Out[82] = Cartesian [x,  y,   z]
    Out[83] =2x+2y+2 z
    In[84] :=SetCoordinates [Spherical [r, θ, ϕ] ] 
             Div[{r2, θ2, ϕ2}]
    Out[84] = Spherical [r, θ, ϕ]
    $$Out[85]=\frac{Csc[\theta] (2 r \varphi + r \theta^2 Cos [\theta] +4 r^3 Sin [\theta] +2 r \theta Sin [\theta]}{r^2} $$
    In[86]: = CoordinateSystem
               (*выдает название текущей системы координат *) 
              Div [{r2, ϕ2, z2},Cylindrical [r,ϕ, z] ]
    Out[86] = Spherical
    $$Out[87]=\frac{3r^2+2rz+2 \varphi}{r} $$

    Текущий список загруженных пакетов присвоен переменной $Packages:

    In[88]:=$Packages
    Out[88] = {VectorAnalysis ',  JLink',
               PacletManager',  WebServices',  System',  Global'}

    Типичная ошибка при использовании пакета - попытка выполнить до его загрузки некоторую функцию f, короткое имя которой имеется у одной из функций пакета. Если такое произошло, то выполняемой функции автоматически присваивается контекст Global'. После загрузки пакета одноименная функция из этого пакета начинает затенять функцию Global 'f, о чем сообщается в диагностике. Если вам не нужна функция из пакета, а нужна определенная вами, выполните команду Remove[f] (см. выше).

    Отличие << (или Get ) от Needs: команда Needs загружает пакет только если он еще не был загружен, что определяется по тому, есть ли его имя в списке $Packages или нет.

    Просмотр определений. Разница между Unset и Clear

    Команда Definition[x] или ?x выводит определения для x (команда ?x дает больше информации), заданные с помощью команд = и :=:

    In[89]:=х=а-2;
            x
    Out|90]=-2+а
    In[91]:=Definition [x]
    Out[91] =
       х=-2+а
    In[92]:=?x
    х=-2+а
    In[93]:=Clear[x]
            Definition[x]
    Out[94]=Null

    Продемонстрируем разницу между Unset ( =. ) и Clear (команда Unset работает только для выражения, точно соответствующего тому, которому присваивали; Clear работает для всех ассоциированных выражений):

    In[95]:=f[x_]:=x2 ;
            f[x_,y_]=x+y; 
            Definition[f ]
    Out[97]= 
          f[x_]:=x2
          f[x_,y_]=x+у
    In[98]:=f=.
            Definition[f ]
    Out[99]=
           f[x_]:=x2
           f[x_,y_]=x+у
    In[100]:=f[y_]=.
             Definition[f]
    Out[101]=
         f[x_,y_]=x+y
    In[102]:=f [x_]:=x2 ;
             Definition[f ]
    Out[103]=
            f[x_,y_]=x+у
            f[x_]:=x2
    In[104]:=Clear[f ]
             Definition[f]
    Out[105]=Null

    Шаблоны (Pattern)

    Шаблоны используются как для описания возможного вида аргументов функций, так и для выбора объекта из списка.

    Шаблоны для описания аргументов функций

    Шаблон "_" (Blank[]) указывает на любой объект. Шаблон "x_" - на любой объект, которому, для обращения к нему, присвоено имя x:

    In[106]:=f [x_]:=х2

    Шаблон "_h " - любой объект, имеющий заголовок h:

    In[107]:=fint[x_Integer]:=х2
             {fint[2],fint[l/2],fint[x]}
    Out[108]={4,fint[1/2],fint[x]}

    Шаблон "s:obj" - объекты вида obj, которым приписано имя s:

    In[109]:=fobj[x:{-,-}]:=x[[l]]+x[[2]]
              {fobj[{l,2}],fobj[{l,2,3}],fobj[x]}
    Out[110]={3,fobj[{l,2,3}],fobj[x]}

    Шаблон "_ _" ( BlankSequence[] ) - любая последовательность, состоящая из одного или более выражений:

    In[111]:=fseq[x_]:={x}2
             fseq[3] 
             fseq[3, 5]
    Out[112]={9}
    Out[113]= fseq[3, 5]
    In[114]:=Clear [fseq]
             fseq[x__]:={x}2
             fseq[3] 
             fseq[3,5]
    Out[116]={9}
    Out[117]={9,25}

    Шаблон "_ _ _" ( BlankNullSequence[] ) - любая последовательность, состоящая из нуля или более выражений (в приведенном ниже примере <> обозначает объединение (конкатенацию) строк, а ToString[expr] превращает выражение expr в соответствующую строку):

    In[118]:=fnulseq[x___]:="число аргументов равно "<>
              ToString[Length[{х}]] 
             fnulseq[] 
             fnulseq[3] 
             fnulseq[3,5]
    Out[119] = число аргументов равно 0
    Out[200] = число аргументов равно 1
    Out[l2l] = число аргументов равно 2

    Шаблон Repeated[p] или "p.." обозначает так называемую последовательность ( Sequence ) из одного или более аргументов, каждый из которых соответствует шаблону (Pattern) p. Шаблон RepeatedNull[p] или "p..." обозначает последовательность ( Sequence ) из нуля или более аргументов, каждый из которых соответствует шаблону (Pattern) p.

    In[122]:=fpat[x:{_,_}..]:=Plus@@{х}
    In[123]:=fpat[{xl,х2},{yl,у2},{zl,z2}]
    Out[123]={xl+yl+zl,x2+y2+z2}
    In[124]:=fpat[{xl,x2},y,{zl,z2}]
    Out[124]=fpat[{xl,x2},y,{zl,z2}] 
    In[125]:=fpat[{xl,x2},{yl,y2},{{zll,zl2},z2}]
    Out[125]={{xl+yl+zll,xl+yl+zl2},x2+y2+z2}

    Аргументы, которые могут быть пропущены

    С помощью шаблона можно также описать, что делать, если аргумент функции отсутствует.

    Шаблон "x_:v" - если аргумент пропущен, то его значение по умолчанию ( Default ) равно v. Шаблон "x_h:v" - то же с указанием типа.

    Шаблон "x_." - если аргумент пропущен, то его значение по умолчанию ассоциировано с определяемой функцией, а именно, если имя этой функции f, то умолчание хранится в Default[f] (отметим, что Default[f] нужно задавать до определения функции):

    In[126]:=f[x_; 10] := x2;
             f[5] 
             f[5,  7] 
             f[]
    Out[127] = 25
    Out[128] = f [5, 7]
    Out[129] = l00
    In[130]:= Clear [f ]
              Default[f] =  9;
              f[x_.]  : = x2;
              f[5]
              f[5,  7]
              f[]
    Out[133] = 25
    Out[134] = f [5, 7]
    Out[135] = 81

    Команда Clear не очищает значение Default. Чтобы очистить его, воспользуйтесь либо Default[f] =., либо ClearAll[f] :

    In[136]:=Clear[f]
             Definition[f]
    Out[137] =
         Default[f]=9
    In[138]:=Default[f] =. 
             Definition[f]
    Out[139]=Null
    In[140]:=Default[f]=9; 
             f[x_]:=x2 ;
             Definition[f] 
             ClearAll[f]; 
             Definition[f]
    Out[142] =
         f[x_]:=x2
         Default[f]=9 
    Out[144]=Null

    Выбор объектов по шаблону

    Выбор из списка объектов {e1,e2,...} по шаблону pattern можно осуществить с помощью команды Cases[{e1,e2,...},pattern]:

    In[145]:=Cases [{l, {2, x2}, y3 , 2}, _^_]
    Out[145]={y3}

    Выбор из объектов {e1,e2,...} по шаблону pattern на уровнях, заданных levelspec, - командой Cases[{e1,e2,...},pattern,levelspec]:

    In[146]:=Cases [{l, {2, x2}, у3, 2}, _^_, {2}] 
    Out[146]={x2}

    Команда Cases[expr,pattern,levelspec] применима к произвольным выражениям expr:

    In[147]:= Cases [fexp[l, {2, x2} , y3 , 2, g[y, z1/2]], _^_,
              {0,  Infinity}]
    Out[147]={x2, y3, √z }
    In[148] :=Clear [f, tint, fobj ,  fexp,  fseq, fnulseq]

    Опции

    С опциями мы сталкивались выше, настраивая вид графики. Здесь мы разберемся с тем, как они устроены.

    Каждому объекту s можно приписать опции rhs, выполнив команду Options[s] = rhs:

    In[l49]:=Options[s]={a, b, c}
    Out[149]={a, b, c}

    Меняя Options, можно управлять процессом вычисления выражения. В приведенном ниже примере команда MemberQ[Options[s], a] проверяет, входит ли объект a в список Options[s] :

    In[150]:=s[x_]:=If[MemberQ [Options [s], a] , 
               Print["a входит в Options"], 
               Print["a HE входит в Options"]]
             s[2]
           а входит в Options
    In[152]:= Options[s]={b,с}; 
              s[2]
            a HE входит в Options

    У многих встроенных функций и констант имеются заранее заданные опции. Обычно они имеют вид правил $$lhs \to rhs$$. Чтобы посмотреть опции у объекта s, выполните команду Options[s]:

    In[154]:=Options[Plot]
    Out[154] =
         {AlignmentPoint -> Center, AspectRatio -> 1/(GoldenRatio),
         Axes  -> True, AxesLabel  -> None, AxesOrigin  -> Automatic,
         AxesStyle  -> {}, Background  -> None, 
         BaselinePosition  -> Automatic, BaseStyle  -> {},
         ClippingStyle  -> None, ColorFunction  -> Automatic, 
         ColorFunctionScaling  ->True, ColorOutput  ->Automatic, 
         ContentSelectable -> Automatic, 
         CoordinatesToolOptions -> Automatic, 
         DisplayFunction : -> $DisplayFunction, Epilogs {}, 
         Evaluated  -> Automatic, EvaluationMonitor  -> None,
         Exclusions  -> Automatic, ExclusionsStyle -> None, 
         Filling  -> None, FillingStyle  -> Automatic, 
         FormatType : -> TraditionalForm, Frame  -> False, 
         FrameLabel  -> None, FrameStyle  -> {},
         FrameTicks -> Automatic, FrameTicksStyle  -> {}, 
         GridLines  -> None, GridLinesStyle  -> {}, ImageMargins  -> 0.,
         ImagePadding ->  All, ImageSize -> Automatic,
         ImageSizeRaw  -> Automatic, LabelStyle  -> {}, 
         MaxRecursion  -> Automatic, Mesh  -> None, 
         MeshFunctions  -> {Bl }, MeshShading -> None, 
         MeshStyle  -> Automatic, Method  -> Automatic, 
         PerformanceGoal : -> $PerformanceGoal, PlotLabel -> None, 
         PlotPoints -> Automatic, PlotRange  -> {Full, Automatic}, 
         PlotRangeClipping -> True, PlotRangePadding  -> Automatic, 
         PlotRegion  -> Automatic, PlotStyle  -> Automatic, 
         PreservelmageOptions  -> Automatic, Prologs -> {}, 
         RegionFunction  -> (True s) , RotateLabel  -> True, 
         Ticks  -> Automatic, TicksStyle  -> {}, 
         WorkingPrecision -> MachinePrecision}

    Чтобы посмотреть значение конкретной опции объекта s, выполните команду Options[s,name], где name - имя требуемой опции:

    In[155]:=Options[Plot,Plotstyle]
    Out[155]={PlotStyle -> Automatic}
    In[156]:=Plot[{Sin[x],Cos[x]},{x,0,1}]

    Чтобы изменить опции объекта s с именами name1, name2,..., выполните команду $$SetOptions[s, \{name1 \to values1, name2 \to value2, \dots \}]$$:

    In[157]:=SetOptions [Plot,  PlotStyle -> Dashing [{. 05 ,   .01}]]; 
             Options[Plot, PlotStyle]
    Out[158]={PlotStyle ->Dashing[{0.05,0.01}] }
    In[159]:=Plot[{Sin[x], Cos[x]}, {x,0,1}]
    In[160]:=SetOptions [Plot, PlotStyle -> abc] ; 
             Options[Plot, PlotStyle] 
             Plot[{Sin [x] , Cos[x]}, {x,  0, 1}]
    Out[l6l]={PlotStyle -> abc}
    Graphics: :gprim: 
                    abc was encountered where a Graphics primitive or directive was expected. >>
    
    
                 Graphics: :gprim: 
                    abc was encountered where a Graphics primitive or directive was expected. >>

    Для опций, определенных в виде правил замены, имеются удобные способы их использования и изменения в пользовательских функциях. Выражение OptionsPattern[] используется в качестве последовательности опций определяемого выражения. Выражение OptionValue[name] - значение опции name (правая часть выражения $$name \to Rhs$$ ) из списка опций OptionsPattern[]:

    In[16З]:=Clear[s]
             Options[s]={u ->u0,v->v0}; 
             s[x_,OptionsPattern[]]:=
             {x,OptionValue[u],OptionValue[v]} 
             s[l]
             s[l,u->4]
             s[1,u->4,v->7]
             s[l]
    Out[166]={1, u0, v0}
    Out[167]={1, 4, v0}
    Out[168]={1, 4, 7}
    Out[169]={1, u0, v0}

    Список OptionsPattern[s] позволяет использовать в качестве аргумента выражения f опции другого выражения s, не меняя при этом опции самого выражения f:

    In[l70]:=f [x_, OptionsPattern[s]]:=
               {х, OptionValue[u], OptionValue[v]} 
             Options[f]
    Out[171]={}
    In[172]:=f [1]
             f [1,  u -> 4]
             f[l, u -> 4, v -> 7]
             f[l]
    Out[172]= {1, u0,  v0}
    Out[173]= {1, 4, v0}
    Out[174]= {l, 4, 7}
    Out[175]= {1, u0, v0}

    Правила в опциях могут быть как в виде Rule (или $$lhs \to rhs$$ ), так и в виде RuleDelayed (или lhs :> rhs ). В этом примере значение опции с именем u равно 10 и не меняется при изменении х:

    In[176]: = х = 10;
               Options [s]  = {u -> x, v -> v0}; 
               s[l]
    Out[179]= {1, 10, v0}
    In[179]: = x = 8; 
               s[l]
    Out[180]= {1, 10, v0}

    А в этом примере значение опции с именем u равно текущему значению выражения x:

    In[181]: = х = 12;
               Options [s]  = {u: -> x, v -> v0}; 
               s[l]
    Out[183] = {1, 12, v0}
    In[184]:=x = 9; 
             s[l]
    Out[185]= {1, 9, v0}

    В этом примере значение опции с именем u также равно текущему значению выражения x:

    In[186] := Clear [s, x]
               Options [s] = {u -> x} ;
               s[OptionsPattern[]] : = OptionValue[u]
               s[]
               s[u -> 1]
    Out[189] = x
    Out[190] = 1
    In[191]:=x = 5; 
             s[]
    Out[192] = 5
    In[193]: = x = 7; 
               s[]
    Out[194] = 7

    Команда Clear[s] не очищает опции для s. Чтобы очистить s полностью, вместе с опциями (и еще некоторыми связанными с s объектами), воспользуйтесь командой ClearAll[s]:

    In[195] := Clear [s,  f]
               Definition[s]
    Out[196] =
        Options [s]  = {u -> 9}
    In[197]:=ClearAll [s]
             Definition[s]
    Out[198]=Null

    Атрибуты

    Атрибуты служат для задания некоторых специальных неявных свойств функций, таких как коммутативность ( Orderless ), ассоциативность ( Flat ) и другие. Имеется 19 типов возможных атрибутов (см. Help ). Посмотреть атрибуты объекта можно командой Attributes[x]:

    In[199] : = Attributes [Plus]
    Out[199]= {Flat,  bistable, NumericFunction,
               Oneldentity, Orderless,  Protected}

    Задать атрибуты для x можно так: Attributes[x] ={attr1, attr2, ...}:

    In[200]:=С1еагА11 [f, x] 
    In[201]:=f [{1,  2,  3}]
    Out[201] = f [{1,   2,   3}]
    In[202]:=Attributes [f] = {Listable} 
             f [{1, 2,  3}]
    Out[202]= {Listable}
    Out[203] = { f [ 1 ] , f [2],  f [3]}

    Добавить атрибут attr для x можно командой SetAttributes[x,attr]:

    In[204]:=f [f [x, y] , z]
    Out[204] = f [f [x,  y] , z]
    In[205]:=SetAttributes[f,  Flat] 
             f[f[x, y],z]
    Out[206] = f [x, y, z]

    Удалить атрибут attr из списка атрибутов объекта x можно командой ClearAttributes[x, attr]:

    In[207]:=ClearAttributes [f, Flat] 
             f[f[x, y], z]
    Out[208] = f [f [x, y] , z]

    Полный список атрибутов символов в пакете Mathematica:

  • Orderless - коммутативность функции:

    In[209]:=f [х, у]  == f [у,  х]
    Out[209] = f [x, у] ==f[y, x]
    In[210] := SetAttributes [f, Orderless] 
               f [х, у]  == f[y, x]
    Out[211] = True 
    In[212]:=f [f [x, y] , z]
    Out[212] = f [z, f [x, y] ]
  • Flat - "обобщенная" ассоциативность функции (обобщенная в том смысле, что f[f[...[x]]] отождествляется с f[x] ):

    In[213]:=f [f [х, у] ,  z] 
             f[f[f[x]]]
    Out[213] = f [z,   f [x,   y] ]
    Out[214] = f [f [f [x] ] ]
    In[215] := SetAttributes [f,  Flat] 
               f[f[f[x]]] 
               f[f[x, y],  z]
    Out[216] = f [x]
    Out[217] = f [x,   y,   z]
    In[2l8]:= {f [f [a, a, a] , a] , f [f [f [a] , f [a] , f [a]] , a]}
    Out[218] = {f [a,  a,  a,  a],  f[a,  a,  a,  a]}

    Проиллюстрируем особенности взаимодействия функции с атрибутами Flat и Orderless и замены:

    In[219]:= f [a, b, с, d, e] /. f[b, с, d] -> х
    Out[219] = f[a,  e,  x]

    Здесь сначала f[a, b, c, d, e] отождествляется с f[a, f[b, c, d], e] и после делается замена. Аргументы x и e в результирующем выражении переставлены в силу коммутативности.

    Еще пример:

    In[220]:= f [а, Ь,  с, d,  e]  /. f[b,  с, d] -> f[x, у] 
    Out[220] = f [a,  e,  х,  у]

    Здесь после замены f[a, b, c, d, e] на f[a, f[x, y], e] последнее выражение отождествляется с f[a, x, y, e].

  • OneIdentity - наличие этого атрибута приводит к тому что выражение f[f[...f[a]]] заменяется на a внутри другой функции. Работает обычно совместно с атрибутом Flat.

    In[221]:= SetAttributes[f,  Flat]
              f [a, a, a, a]  /. f[x_, x_, x_] ->  g[x]
    Out[222] = f [a,  g[f [a] ] ]
    In[223]:= f [a, b, c, d] /. f [x_, y_, z_] -> g[z]
    Out[223] = g[f [c,  d] ]
    In[224] : = Attributes [f ]
    Out[224]= {Flat, bistable,  Orderless}

    В предыдущем примере атрибут Flat позволяет отождествить выражение f[a, a, a, a] с обоими выражениями: как с f[f[a, a, a], a], так и с f[f[f[a], f[a], f[a]], a]. Если нет атрибута OneIdentity, то происходит отождествление с f[f[f[a], f[a], f[a]], a], таким образом, внутренняя функция f[f[a], f[a], f[a]] заменяется, в итоге, по правилу f[x_, x_, x_] \to g[x] на g[f[a]]:

    In[225] := SetAttributes [f, Oneldentity]\\
               f [a, a, a, a]  /. f[x_, x_, x_] ->  g[x]
    Out[226] = f [ a,  g [ a ] ]

    Теперь установлен атрибут OneIdentity, поэтому выбирается отождествление с f[f[a, a, a], a], что приводит к замене f[a, a, a] на g[a].

  • Listable - функция, примененная к списку, автоматически применяется к каждому аргументу списка:

    In[227]:=f [{1,  2,  3}]
    Out[227]= { f [ 1 ] , f [2], f [3]}
    In[228] := SetAttributes [f, bistable] 
               f [{1, 2,  3}]
    Out[229] ={ f [ 1 ] , f [ 2 ] , f [ 3 ] }
  • Constant - все производные функции равны нулю:

    In[230]:=Dt[f]
    Out[230] = Dt [f ]
    In[231]:= SetAttributes [f, Constant] 
              Dt[f] 
              Dt[f g]
    Out[232] = 0
    Out[233] = f Dt [g]
    In[234] : = Attributes [π]
                Dt[π]
    Out[234]= {Constant,  Protected, ReadProtected}
    Out[235] = 0
  • NumericFunction - предполагается, что функция принимает числовые значения при условии, что ее аргументы - числа. В приводимом ниже примере NumericQ[expr] дает True, если выражение expr числовое, и False в противном случае:

    In[236]: = NumericQ[f [x] ]
               NumericQ[f[2]]
    Out[236] = False
    Out[237] = False
    In[238] := SetAttributes [f, NumericFunction] 
               NumericQ[f[x]] 
               NumericQff[2]]
    Out|239] = False
    Out[240] = True
  • Protected - определения функции не могут изменяться:

    In[241]:=f [х_] := х2
             f[2] SetAttributes [f, Protected]
    Out[242] = 4
    In[244]:=f [x_] : = x3
             f[2]
    SetDelayed::write: Tag f in f[x_] is Protected. >>
    Out[244] = $ Failed
    Out[245] = 4
    In[246]:=ClearAttributes [f, Protected] ; 
             f [x_] : = x3 
             f[2]
    Out[248] = 8
  • Locked - атрибуты функции не могут изменяться до конца текущей сессии Mathematica. Использование одновременно Protected и Locked запрещает менять функцию до конца сессии:

    In[249] := SetAttributes [f, Locked]
               ClearAttributes[f, Locked]
    Attributes::locked: Symbol f is locked. >>
  • ReadProtected - определение функции скрыто:

    In[251]:=g[x_]   := x2
             ?g
    g g[x_]   := x2
    In[253]:=g[x_] := x2
             SetAttributes[g, ReadProtected] 
             ?g
    Attributes[g] = {ReadProtected}
    In[256]:=g[x_] := x3
             ?g
    Attributes[g] = {ReadProtected}
    In[258]:= ClearAttributes [g, ReadProtected] 
             ?g
    g[x_] := x3
  • HoldFirst - первый аргумент функции не вычисляется:

    In[260]:= SetAttributes [h, HoldFirst] 
              h[l + 1, 2+2,  3 + 3]
    Out[261] =h[l + 1,   4,   6]

    В следующем примере ошибка возникает из-за того, что аргумент х сначала вычисляется, а потом уже обрабатывается функцией g. Поэтому происходит попытка присвоить числу 17 значение 25. Этой ошибки можно избежать с помощью атрибута HoldFirst:

    In[262]:=g[sym_, val_] :=  (sym=val^2) 
             x = 17; 
             g[x,  5]
             x
    Set::setraw: Cannot assign to raw object 17.<<
    Out|264] = 25
    Out[265] = 17
    In[266]:=SetAttributes [g,   HoldFirst] ; 
             g[x,  5]
             x
    Out[267] = 25 
    Out[268] = 25

    Аргумент все-таки можно вычислить, если применить к нему функцию Evaluate:

    In[269] :=h [Evaluate [1 + 1] ,  2 + 2,  3 + 3]
    Out[269] = h [ 2 ,   4,   6 ]
  • HoldRest - все аргументы функции, кроме первого, не вычисляются.
  • HoldAll - все аргументы функции не вычисляются.
  • HoldAllComplete - все аргументы функции не вычисляются ни при каких обстоятельствах, например, даже при применении функции Evaluate:

    In[270] := SetAttributes [h,  HoldAllComplete] 
               h[l + 1, 2 + 2,  3 + 3] 
               h [Evaluate [1 + 1] , 2 + 2 , 3 + 3]
    Out[271] = h[l + 1,   2 + 2,   3 + 3]
    Out[272] = h [Evaluate [1 + 1],   2 + 2,   3 + 3]
  • NHoldFirst - первый аргумент функции не подвергается обработке функцией N, переводящей числа в их приближенные десятичные записи.

    В следующем примере вычисляется разложение в ряд Тейлора длины k для функции cos[x] в точке $$x_0$$, являющейся решением уравнения cos[x] = x. Решение этого уравнения находится с помощью функции FixedPoint[f,x], которая вычисляет значение f(f(… f(x))) до тех пор, пока оно не перестает меняться. Начальное значение x в рассматриваемом случае приходится задавать в виде десятичной дроби, иначе FixedPoint пытается все вычислять точно и не срабатывает. Тест ?InexactNumberQ как раз возвращает True, если его аргумент - десятичная дробь:

    In[273] :=ff [k_Integer, х_?InexactNumberQ]   : =
                    Module[{x0},  x0 = FixedPoint[Cos, х] ; 
                       Series [Cos [t] , {t, x0 , k}] ] ;
                gg[k_Integer, x_?InexactNumberQ] :=
                    Module[{x0}, x0 = FixedPoint[Cos, x] ; 
                       Series[Cos[t] ,  {t, x0 , k} ] ] ;
                SetAttributes[ff, NHoldFirst];
    In[276]:={ff [2,  1.] , gg[2,  1.],  ff[2,  1] ,  gg[2,  1]}
    Out[276] =
              {0.739085-0.673612  (t - 0 . 739085)  -
                 0.369543  (t-0.739085)2+O[t-0.739085]3,   0.739085-
                 0.673612  (t - 0.739085) -0.369543  (t - 0.739085)2 + 
                 0[t - 0.739085]3, ff[2,   1], gg[2, 1]}

    Мы видим, что обе функции ff и gg работают, если их аргументы имеют правильный тип, и не работают, если второй аргумент - целое число. Можно попробовать исправить последнее, применив функцию N. Но тогда первый аргумент функции gg перестанет быть целым и она снова не сработает, а функция ff сработает, так как ее первый аргумент не обрабатывается функцией N благодаря установленному атрибуту NHoldFirst.

    In[277]: = N@{ff [2, 1] , gg[2, 1]}
    Out[277] =
        {0.739085-0.673612  (t-0.739085)  -
         0.369543  (t - 0.739085) 2 + 0[t - 0.739085] 3, gg[2., 1 .] }
  • NHoldRest - все аргументы функции, кроме первого, не подвергаются обработке функцией N.
  • NHoldAll - все аргументы функции не подвергаются обработке функцией N.
  • SequenceHold - объекты типа "последовательность" ( Sequence ) не встраиваются в функцию.

    In[278]:= hh[a,  Sequence [b,  с]]
    Out[278] = hh [ a,  b,  с ]
    In[279] := SetAttributes [hh, SequenceHold] 
               hh[a, Sequence[b, c] ]
    Out[280]=hh [a,  Sequence [b,  c] ]
  • Temporary - локальная переменная уничтожается, как только перестает использоваться:

    In[281]: = Module[{x} ,  Print [х] ; Attributes [x] ]
               x$866
    Out[281]= {Temporary}
  • Stub - признак того, что символ закреплен за некоторым пакетом Package, который автоматически загружается при явном использовании этого символа.
  • Символы с атрибутом Stub создаются с помощью команды DeclarePackage[<пакет>,<имя или список имен>] >:

    In[282] :=DeclarePaakage ["ErrorBarPlots' ",  "ErrorListPlot"]
    Out[282] = ErrorBarPlots'

    В результате символ ErrorListPlot получает контекст ErrorBarPlots, который становится первым в списке контекстов. Кроме того, если теперь будет выполнена функция с именем ErrorListPlot, то до ее вычисления с помощью функции Needs будет загружен пакет ErrorBarPlots:

    In[283] : = Attributes ["ErrorListPlot"]
    Out[283]= {Stub}
    In[284] : = 
       ErrorListPlot[Table [ {i, RandomReal [0.5]} , {i, 10}]]

    Можно также определить свою функцию, использующую функции из какого-нибудь (одного) пакета:

    In[285]:=DeclarePackage["Combinatorica ' ",  "tc"] ;
    In[286] := tc [x_]: = ToCycles [x] ;
    In[287]:=tc[{l,  2,   3,  4,  5,   6,   7,   8,   9,   10}]
    Out[287] = { {1} , {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}} 
    In[288]:=ClearAll[ff, gg, g, h, hh, tc]

    Сообщения

    В пакете Mathematica предусмотрен механизм выведения сообщений при выполнении вычислений. Обычно это сообщения об ошибках и предупреждения. Имеется возможность приписывать сообщения любым символам. Чтобы приписать сообщение с именем tag символу symbol, выполните команду symbol::tag = "сообщение".

    In[289]:=g: :lt = " Аргумент  меньше  нуля"
    Out[289] = Аргумент меньше  нуля

    Чтобы вывести сообщение, выполните команду Message[symbol::tag]:

    In[290]:=Message[g: :lt]
    g::lt: Аргумент меньше нуля

    Теперь в определении функции можно задать вывод сообщения при выполнении некоторых условий:

    In[291]: = g[x_] /; If[x < 0, Message [g: : lt] ; False,  True]   : = √x 
    In[292]:=g[l]
    Out[292] = 1 
    In[293]:=g[-l]
    g::lt: Аргумент меньше нуля
    Out[293] = g [ - 1 ]

    В сообщение можно вставить значение выражений expr1,expr2,..., выполнив команду Message[symbol::tag, expr1,expr2,...] , при этом ссылка на выражение expri внутри текста сообщения должна иметь вид 'i':

    In[294] : =
           gg[х_]  / ; If [x < 0 , Message [gg: : It, х] ; False,  True]   := √x 
           gg::lt = "Аргумент   '1'   меньше  нуля";
           gg[-2]
    gg::lt: Аргумент -2 меньше нуля
    Out[296] = gg [-2]

    Отключить сообщение можно командой Off[symbol : tag]:

    In[297]:=Off [gg: :lt]
             gg[-i]
    Out[298]=gg [-1]

    Включить сообщение можно командой On[symbol : tag]:

    In[299]:=On[gg: :lt]
             gg[-i]
    gg::lt: Аргумент -1 меньше нуля
    Out[300] = gg [-1]

    Вывести список всех сообщений, приписанных символу symbol, можно выполнив команду Messages[symbol]:

    In[301] :=Messages [gg]
    Out[30l] = {HoldPattern[gg::It]: -> Аргумент '1' меньше нуля}

    Встроенные функции, как правило, снабжены сообщениями о возможных ошибках. Например,

    In[302]:=Sin[l,2,3]
    Sin::argx: Sin called with 3 arguments; 1 argument is expected.>>
    Out[302]= Sin[l, 2, 3]

    Эти сообщения можно отключить командой Quiet, хотя правильней от этого программа не становится:

    In[303]:=Quiet@Sin[l, 2,  3]
    Out[303] = Sin[l,   2,   3]

    Список сообщений для встроенных функций загружается в Mathematica по мере необходимости. При этом сначала Mathematica ищет сообщение с указанным именем среди сообщений, приписанных обрабатываемой функции. Если его там нет, программа переходит к просмотру списка сообщений для встроенного символа General. Так, в нашем примере сообщение Sin::argx получено именно из списка General. У самой функции Sin список сообщений пуст.

    In[304] :=Messages [Sin]
    Out[304]={ }
    In[305] := Style [Messages [General] ,  FontSize ->  6]
    Out[305] =
       {HoldPattern[General::appname]: -> The name '1' is not valid for the
               application. A valid name smarts with a letter and is followed by lexers and digits., 
        HoldPattern [General::argx]: -> '1' called with '2' arguments; 1 argument is expected.,
        HoldPattern [Generall::bktwrn]: -> " '1' " represents multiplication; use " '2' " 
        to represent a function. '4',
        HoldPattern[General:: catname]: -> The name  '1' is not valid for the
               category. A valid name starts with a letter and is followed by letters and digits.,
        HoldPattern[General::file] : -> ' 2 ' was encountered where a '1'  primitive or directive was expected., 
        HoldPattern[General: :meprec] : -> Internal precision limit $MaxExtraPrecision = '1'  
        reached while evaluating '2'.,
        HoldPattern [General: :multedge] : -> The input graph has multiple edges between some  vertices. These
               will be collapsed into single edges with weight equal to the sum of the individual edges.,
        HoldPattern[General::newsym] : -> $off[], HoldPattern[General::nfunfail] : -> $off[],
        HoldPattern[General: :nosite] :-> Site '1' is not an existing Paclet site.,
        HoldPattern[General: :obsppkgfn]: -> $Off [] ,
        HoldPattern[General::offline]: -> Mathematica is currently configured not to use the
               Internet. To allow Internet use, check the "Allow Mathematica to use the Interne"
               box in ohe Help > Internet Connectivity dialog., HoldPattern [General: : oldversion] :-> 
            Connections to kernls older than Version 2.2 are not supported. This kernel is version '1'.,
        HoldPattern [General::partw] : -> Part '1' of '2'   does not exist., 
        HoldPattern[General::pclt]: -> '1' does not refer to a known paclet.,
        HoldPattern[General::pcltn] : -> No appropriate paclet with name '1' was found.,
        HoldPattern[General::pcltni] : -> No appropriate paclet with name '1' is installed.,
        HoldPattern[General::pcltnv]: -> No appropriate paclet with name '1' and version '2' was found.,
        HoldPattern[General::pcltnvi] : -> No appropriate paclet with name '1' and version '2' is installed.,
        HoldPattern[General::plnr]: -> $off[],
        HoldPatern[General::pp3tr] : -> $off[], HoldPattern[General::pptr]: -> $off[],
        HoldPattern[General::prefdir]: -> The preferences directory '1' cannot be created.,
        HoldPattern[General::shdw]: -> Symbol '1' appears in multiple contexts '2'; definitions in
                Context '3' may shadow or be shadowed by other definitions., HoldPatern[General::shdwcor]: ->
            Symbol '1' defined in '2' already exists in '3'. Select the version you want to use: '4'.,
        HoldPattern[General::spell]: -> $Off[], HoldPattern[General::spell]: -> $Off[],
        HoldPattern[General::stop]: -> Further output of '1' will be suppressed during this calculation.,
        HoldPattern[General::string]: -> String expected at position '1' in '2'.,
        HoldPattern [General::stringopt]: -> '1' in '2' is not a string. All options to '3' must be strings.,
        HoldPattern [General::sysmain]: -> Error loaning the main binary file '1'.
               Get["sysmake.m"] must be run before continuing., HoldPattern[General::write]: 
               -> Tag '1' in '2' is Protected.,
        HoldPattern[General::writewarn] : -> Defining rule for '1'.)
    Страницы:

    Выражения - универсальный конструктор в Mathematica

    Напомним, что f[x,y,...] - универсальный (канонический) вид выражения, где x, y,... могут быть выражениями или атомарными объектами (числами, символами, строками).

    Последовательность аргументов x, y, ... называется Sequence.

    In[1] :=f [Sequence [x,у,z] ]
    Out[1]=f[x,y,z]
    In[2]:=f [x, Sequence [y,z],w]
    Out[2] = f [x,y,z,w]

    f называется заголовком ( Head ) выражения f[x, y, ...]. Заголовок f может быть как символом, так и более сложным выражением (в приведенных ниже примерах заголовки - это f[2] и (a+b) ):

    In[3]:=f [2][х,у] 
          (а + Ь)[х]
    Out[3] =f[2][х, у]
    Out[4] =(а+b)[х]

    Еще пример: заголовком является InterpolatingFunction[{{0.,3.}},<>] (команда First - взятие первого элемента списка):

    In[5]:=
         у/.First[NDSolve[{y''[х] == -у[х], у[0] == у'[0]==2} , 
          y,{х,0,3}]] 
         f[x] 
         f[2.3] 
         Plot[f[x],{x,0,3}]
    Out[5] =InterpolatingFunction [{{0.,3.}}, <>]
    Out[6] =InterpolatinqFunction [{f0.,3.}}, <>][х]
    Out[7] =0.158858
    In[9] := Clear [f]

    Команда FullForm позволяет представить выражение в каноническом виде:

    $$In[10]:=FullForm [\frac{x+y-zw)}{a+(b-c)^{\frac12}}] $$
    Out[10] =
         Times[Power[
           Plus[a,Power[Plus [b, Times[-1, c]],Rational[1, 2]]],
             -1],Plus[x,y,Times[-1,w,z]]]

    Выражения имеют структуру дерева:

    $$In[11]:= TreeForm[\frac{x+y-zw}{a+(b-c))^{\frac12}}] $$

    Список, как частный случай выражения, тоже имеет структуру дерева:

    In[12]:=TreeForm[{a,{b,с},d}]

    Если в одной скобке стоит последовательность выражений $$expr_1; expr_2; \dots$$, разделенных точкой с запятой, то на самом деле там имеется одно выражение $$CompoundExpression[expr_1; expr_2; \dots ] $$ . Например, последовательность выражений

    In[13]:=х=2; у=х2;
            y
    0ut[14]=4

    представляет собой одно выражение

    In[15]:=CompoundExpression[х=2,у=х2,у]
    Out[15]=4
    In[16]:=Clear[x,у]

    Уровни выражения expr

    Каждое выражение разбито на уровни. Посмотреть на них можно с помощью команды Level[expr,levelspec], где levelspec описывает интересующие уровни:

    $$In[17]:=TreeForm [\frac{x+y-zw}{a+(b-c)^{\frac12}}] $$$$In[18]:= Table [Level \left [ \frac{x+y-zw}{a+(b-c)^{\frac 12}} , \{i\}\right ], \{i, 0, 7\}]\\ Out[18] =\\ \left \{ \left \{ \frac{x+y-wz}{a+\sqrt{b-c}}\right \},\left \{ \frac{1}{a+\sqrt{b-c}}, x+y-wz \right \}, \{a+\sqrt{b-c}, -1 x, y, -wz\},\\ \begim{matrix} \{a, \sqrt{b-c}, -1, w,z\}, \{b-c, \frac 12\}, \{b, -c\}, \{-1, c\}, \{\}\} \end{matrix}$$

    levelspec ={n} - только n -й уровень (нулевой уровень - само выражение):

    $$In[l9]: = Level \left [ \frac{x+y-zw}{a+(b-c)^{\frac 12}}, \{3\} \right]\\ Out[l9]=\{a, \sqrt{b - с} , -1, w, z\}$$

    levelspec = n - все уровни от 1-го до n -го (нулевой уровень не включен):

    $$In[20]: = Level \left [ \frac{x+y-zw}{a+(b-c)^{\frac 12}}, 3\right]\\ Out[20] = \{a, \sqrt{b - с} , а + \sqrt{b - с} , -1,\\ \begin{matrix} \frac{1}{a+\sqrt{b-c}^{\frac 12}}, х, у, -1, w, z, -w z, x+y-wz\} \end{matrix}$$

    levelspec = {n, m} - уровни с номерами между n и m:

    $$In[21]:= Level \left [\frac{x+y-zw}{a+(b-c)^{\frac 12}}, \{3, 5\}] $$ $$Out[21] = \{а, b, -с, b - с, \frac 12, \sqrt{b - с} , -1, w, z\} $$

    levelspec = {n, Infinity} - уровни с номерами, не меньшими, чем n:

    $$In[22]: = Level \left [ \frac{x+y-zw}{a+(b-c)^{\frac 12}} , \{0, Infinity\} \right]\\ Out[22] =\{a, b, -1, с, -с, b - с, \frac 12, \sqrt{b - с} , a + \sqrt{b - с} , -1,\\ \begin{matrix} \frac{1}{a+\sqrt{b-c}}, x, у, -1, w, z, -wz, x + y-wz, \frac{x+y-wz}{a+\sqrt{b-c}}\} \end{matrix}$$

    Заголовок выражения

    Заголовок выражения f[x, y, ...] - это f, заголовки атомарных объектов называются их типами.

    In[23]:=Head[f [х, у] ]
    Out[23] = f
    In[24]: = Head[x + у]
    Out[24] = Plus

    Типы атомарных объектов:

  • целые числа - Integer ;
  • рациональные числа - Rational ;
  • вещественные числа - Real ;
  • комплексные числа - Complex ;
  • символы - Symbol ;
  • строки - String.
  • In[25]:= {Head[l] ,  FullFormfl]}
             {Head[l/2], FullForm[l / 2] } 
             {Head[l.l],  FullForm[l.l] } 
             {Head[l + i], FullForm[l+ i]} 
             {Head[x],  FullForm[x]} 
             {Head["abc"],  FullForm["abc"]}
    Out[25]= {Integer,   1}
    Out[26]= {Rational,  Rational [1,  2]}
    Out[27]= {Real,   1.1'}
    Out[28] = {Complex,  Complex[l,   1]}
    Out[29] = {Symbol,  x}
    Out[30]= {String,   "abc"}

    Интересный пример. Сравните:

    In[31] : = {Head [x + i] ,  FullForm [x + u] } 
    Out[31]= {Plus,  Plus [Complex [0,   1],  x] }

    Замена заголовка. Осуществляется командой Apply или @@:

    In[32]: = Apply[g, f[x,у]]
    Out[32] = g[x, у]
    In[33]: = Head[{a,b,с,d}]
    Out[33] = List
    In[34]: = Apply[Plus,{a,b,c,d}] 
    Out[34] =a+b+c+d 
    In[35]:=Plus@@{a,b,c,d}
    Out[35] = a + b + с + d

    Команда Apply не действует на атомарных объектах:

    In[36]: = х = Apply [List,  l]
    Out[36] = 1
    In[37]: = Head[x]
    Out[37] = Integer
    In[38]: = х = Apply [List,  1/2]
    Out[38] = 1/2
    In[39]:=Head[x] 
    Out[39]= Rational 
    In[40]: = x = . 
    In[41]:=Head[x]
    Out[41] = Symbol

    Преобразование типов атомарных объектов

    Важно уметь переходить от одного типа к другому.

    Команда IntegerString[integer] преобразует целое число integer в строку (знак игнорируется):

    In[42]:= IntegerString [25 361]  // InputForm
    Out[42] = "25361"

    Команда FromDigits[str] преобразует строку цифр в целое число, а также список цифр в целое число. Чтобы преобразовать число в список цифр, можно использовать команду IntegerDigits:

    In[43] :=FromDigits ["43476"]
             FromDigits[{5,  2,  3,  8}] 
             IntegerDigits[374 632]
    Out[43] = 43476
    Out[44] = 52 3 8
    Out[45]={3, 7, 4, 6, 3, 2}

    Команда ToString[expr] преобразует выражение expr в строку. При этом форму вывода form можно указать в качестве второго аргумента: ToString[expr,form]:

    In[46] := ToString [x2]
              ToString[x2]  // InputForm
    Out[46] = 2
    Out[47] = "2\nx"
    In[48]:=ToString [x2 , InputForm]
            ToString[x2, InputForm] // InputForm
    Out[48]=x^2 
    Out[49] ="х^2"

    Команда ToExpression[str] преобразует строку в соответствующее выражение. Модифицированная команда ToExpression[str,form] преобразует строку в выражение, используя при этом правило вывода form:

    In[50] := ToExpression [ "Sin [x] "]
    Out[50]= Sin [x]
    In[51] := ToExpression [ "sin (x) " ,  TraditionalForm]
    Out[51] = Sin [x]
    In[52] := ToExpression [ "\sin (x) ", TeXForm]
    Out[52] = Sin [x]

    Команда Symbol[str] превращает строку в символ:

    In[53]:= Symbol ["х"]
    Out[53]=x

    Строка из 10 символов:

    In[54] := Table [Symbol ["x" <> ToStringfi]] , {i, 10}]
    Out[54]={xl,  х2,  хЗ,  х4,  х5,  хб,  х7,  х8,  х9,  х10}
    In[55] := Table [ToExpression ["х" <> ToString[i] ] , {i, 10}]
    Out[55]={xl,  x2,  хЗ,  х4,  х5,  хб,  x7,  x8,  x9,  x10}

    Команда SymbolName[symbol] превращает символ symbol в строку - имя этого символа:

    In[56] := SymbolName [х]  // InputForm
    Out[56] = "x"

    Доступ к фрагментам выражения

    Доступ к фрагментам выражения осуществляется как к элементам списка (заголовок Head - нулевой элемент):

    $$In[57]:= TreeForm [\frac{x+y-zw}{a+(b-c)^{\frac12}}] $$$$In[58]:=\left \{ \left ( \frac{x+y-zw}{a+(b-c)^{\frac 12}} \right ) [[0]], \left ( \frac{x+y-zw}{a+(b-c)^\frac12 \right )[[1]], \left ( \frac{x+y-zw}{a+(b-c)^\frac 12}\right ) [[2]],$$ $$\begin{matrix} \left ( \frac{x+y-zw}{a+(b-c)^ \frac 12} \right ) [[3]] \right \} \end{matrix}\\ Part::partw: Part\; 3\; of \frac{x+y-wz}{a+ \sqrt{b-c}} does\; not\; exist. >>\\$$ $$Out[58] = \left \{Times, \frac{1}{a+ \sqrt{b-c}}, x+y-zw, \frac{x+y-zw}{a+ \sqrt{b-c}} [[3]] \right \}$$ $$In[59]:=TreeForm \left [ \left ( \frac{x+y-zw}{a+(b-c)^{\frac 12}} \right ) [[2]] \right ]$$ $$In[60]:=\left \{ \left ( \frac{x+y-zw}{a+(b-c)^{ \frac 12} \right ) [[2,1]], \left ( \frac{x+y-zw}{a+(b-c)^{\frac 12}} \right )[[2,2]], \left ( \frac{x+y-zw}{a+(b-c)^{\frac 12}} \right ) [[2,3]],\\ \begin{matrix} \left ( \frac {x+y-zw}{a+(b-c)^{\frac 12}} \right ) [[2,4]] \right \}\\ \end{matrix} $$
    Patt::partw: Part 4 of x + y-wz does not exist. >>
    $$Out[60]=\left \{x, y, -wz, \frac{x+y-zw}{a+\sqrt {b-c}} [[2, 4]] \right \}$$

    Символы и контексты (Contexts)

    Полное имя каждого объекта состоит из двух частей: контекста ( context ) и короткого имени ( short name ). Полное имя объекта пишется в следующем виде: context'short name. Обратная кавычка ' называется меткой контекста ( context mark ).

    In[61] : = abc'x
               abc'x =10 
               abc'х2
    Out[6l]=abc'x 
    Out[62]=10 
    Out[63]=100

    Символы с одинаковым именем, но разными контекстами - различны:

    In[64]: = х == х
              а'х==b'х
              а'х==а'у
    Out[64] =True
    Out[65] =а'х==b'х
    Out[66] =а'х==а'у

    В каждый момент времени фиксирован так называемый текущий контекст, имя которого находится в переменной $Context:

    In[67]:=$Context
    Out[67]=Global'

    Объекты текущего контекста можно называть их короткими именами:

    In[68]:=х==Global'х
    Out[68]=True

    Контексты аналогичны директориям (папкам) с файлами:

  • текущий контекст - текущая папка, к файлам которой можно обращаться по их именам, не указывая полный путь;
  • подобно тому как папки могут содержать другие папки, контексты могут быть сложными:
  • In[69]:=a'b'x==а'с'х 
    Out[69]=а'b'х==а'с'х

    Отметим, что в момент запуска Mathematica устанавливается контекст Global'. Пользовательские символы относятся именно к этому контексту. Однако, скажем, Pi имеет контекст System'. Чтобы в этом убедиться, примените к Pi команду Context[]:

    In[70]:= Context [x] 
             Context[Pi]
    Out[70] = Global'
    Out[71] = System'

    В Mathematica реализована возможность пользоваться краткими именами объектов, относящихся к разным основным контекстам. Все такие контексты перечислены в списке $ContextPath. Полный список имеющихся контекстов можно получить, выполнив команду Contexts[]:

    In[72]:=$ContextPath // InputForm
    Out[72] =
       {"PacletManager'", "WebServices'" , "System'", "Global'"}

    Если в $ContextPath встречаются два контекста, содержащих один и тот же символ, скажем x, то при обращении к x он интерпретируется в соответствии с тем контекстом, который встречается первым в списке $ContextPath (все остальные одноименные символы "затеняются"):

    In[73]:=$ContextPath={"а'","b'"}≈Join≈ $ContextPath 
             {а"х, b"х} 
             Context[x]
    Out[73]=
        {a", b', PacletManager', WebServices', System', Global'}
    Out[74]={x,b'x] 
    Out[75]=a'

    Таким образом, здесь x воспринимается как $$a'x$$. Если такой x больше не нужен, можно выполнить команду $$Remove[x] $$, и символ a'x будет уничтожен. Теперь x будет восприниматься как $$b'x$$:

    In [76]:=Remove [x] 
             Context[x]
    Out[77]=b'
    In[78]:=Remove [x] 
            Context[x]
    Out[79]=Global'
    In[80]:=$ContextPath=Drop[$ContextPath,2]
    Out[80]={PacletManager',WebServices',System',Global'}

    Пакеты (Packages)

    Пакеты - расширения Mathematica, написанные на языке Mathematica и содержащие определения, которые "учат" Mathematica работать в соответствующих областях. Загрузить такой пакет можно командой <<package или Needs[package], где package имеет такой же формат, как context:

    In[81]:=<< VectorAnalysis'

    Одной из функций, реализованных в этом пакете, является вычисление дивергенции $$Div[\xi] $$ (в заданной координатной системе) или в координатной системе coorsystem с помощью команды $$Div[\xi, coorsystem] $$:

    In[82] :=SetCoordinates [Cartesian [x, y, z] ]
                 (* задает  текущую  систему координат*)
                Div[{x2,y2,  z2}]
    Out[82] = Cartesian [x,  y,   z]
    Out[83] =2x+2y+2 z
    In[84] :=SetCoordinates [Spherical [r, θ, ϕ] ] 
             Div[{r2, θ2, ϕ2}]
    Out[84] = Spherical [r, θ, ϕ]
    $$Out[85]=\frac{Csc[\theta] (2 r \varphi + r \theta^2 Cos [\theta] +4 r^3 Sin [\theta] +2 r \theta Sin [\theta]}{r^2} $$
    In[86]: = CoordinateSystem
               (*выдает название текущей системы координат *) 
              Div [{r2, ϕ2, z2},Cylindrical [r,ϕ, z] ]
    Out[86] = Spherical
    $$Out[87]=\frac{3r^2+2rz+2 \varphi}{r} $$

    Текущий список загруженных пакетов присвоен переменной $Packages:

    In[88]:=$Packages
    Out[88] = {VectorAnalysis ',  JLink',
               PacletManager',  WebServices',  System',  Global'}

    Типичная ошибка при использовании пакета - попытка выполнить до его загрузки некоторую функцию f, короткое имя которой имеется у одной из функций пакета. Если такое произошло, то выполняемой функции автоматически присваивается контекст Global'. После загрузки пакета одноименная функция из этого пакета начинает затенять функцию Global 'f, о чем сообщается в диагностике. Если вам не нужна функция из пакета, а нужна определенная вами, выполните команду Remove[f] (см. выше).

    Отличие << (или Get ) от Needs: команда Needs загружает пакет только если он еще не был загружен, что определяется по тому, есть ли его имя в списке $Packages или нет.

    Просмотр определений. Разница между Unset и Clear

    Команда Definition[x] или ?x выводит определения для x (команда ?x дает больше информации), заданные с помощью команд = и :=:

    In[89]:=х=а-2;
            x
    Out|90]=-2+а
    In[91]:=Definition [x]
    Out[91] =
       х=-2+а
    In[92]:=?x
    х=-2+а
    In[93]:=Clear[x]
            Definition[x]
    Out[94]=Null

    Продемонстрируем разницу между Unset ( =. ) и Clear (команда Unset работает только для выражения, точно соответствующего тому, которому присваивали; Clear работает для всех ассоциированных выражений):

    In[95]:=f[x_]:=x2 ;
            f[x_,y_]=x+y; 
            Definition[f ]
    Out[97]= 
          f[x_]:=x2
          f[x_,y_]=x+у
    In[98]:=f=.
            Definition[f ]
    Out[99]=
           f[x_]:=x2
           f[x_,y_]=x+у
    In[100]:=f[y_]=.
             Definition[f]
    Out[101]=
         f[x_,y_]=x+y
    In[102]:=f [x_]:=x2 ;
             Definition[f ]
    Out[103]=
            f[x_,y_]=x+у
            f[x_]:=x2
    In[104]:=Clear[f ]
             Definition[f]
    Out[105]=Null

    Шаблоны (Pattern)

    Шаблоны используются как для описания возможного вида аргументов функций, так и для выбора объекта из списка.

    Шаблоны для описания аргументов функций

    Шаблон "_" (Blank[]) указывает на любой объект. Шаблон "x_" - на любой объект, которому, для обращения к нему, присвоено имя x:

    In[106]:=f [x_]:=х2

    Шаблон "_h " - любой объект, имеющий заголовок h:

    In[107]:=fint[x_Integer]:=х2
             {fint[2],fint[l/2],fint[x]}
    Out[108]={4,fint[1/2],fint[x]}

    Шаблон "s:obj" - объекты вида obj, которым приписано имя s:

    In[109]:=fobj[x:{-,-}]:=x[[l]]+x[[2]]
              {fobj[{l,2}],fobj[{l,2,3}],fobj[x]}
    Out[110]={3,fobj[{l,2,3}],fobj[x]}

    Шаблон "_ _" ( BlankSequence[] ) - любая последовательность, состоящая из одного или более выражений:

    In[111]:=fseq[x_]:={x}2
             fseq[3] 
             fseq[3, 5]
    Out[112]={9}
    Out[113]= fseq[3, 5]
    In[114]:=Clear [fseq]
             fseq[x__]:={x}2
             fseq[3] 
             fseq[3,5]
    Out[116]={9}
    Out[117]={9,25}

    Шаблон "_ _ _" ( BlankNullSequence[] ) - любая последовательность, состоящая из нуля или более выражений (в приведенном ниже примере <> обозначает объединение (конкатенацию) строк, а ToString[expr] превращает выражение expr в соответствующую строку):

    In[118]:=fnulseq[x___]:="число аргументов равно "<>
              ToString[Length[{х}]] 
             fnulseq[] 
             fnulseq[3] 
             fnulseq[3,5]
    Out[119] = число аргументов равно 0
    Out[200] = число аргументов равно 1
    Out[l2l] = число аргументов равно 2

    Шаблон Repeated[p] или "p.." обозначает так называемую последовательность ( Sequence ) из одного или более аргументов, каждый из которых соответствует шаблону (Pattern) p. Шаблон RepeatedNull[p] или "p..." обозначает последовательность ( Sequence ) из нуля или более аргументов, каждый из которых соответствует шаблону (Pattern) p.

    In[122]:=fpat[x:{_,_}..]:=Plus@@{х}
    In[123]:=fpat[{xl,х2},{yl,у2},{zl,z2}]
    Out[123]={xl+yl+zl,x2+y2+z2}
    In[124]:=fpat[{xl,x2},y,{zl,z2}]
    Out[124]=fpat[{xl,x2},y,{zl,z2}] 
    In[125]:=fpat[{xl,x2},{yl,y2},{{zll,zl2},z2}]
    Out[125]={{xl+yl+zll,xl+yl+zl2},x2+y2+z2}

    Аргументы, которые могут быть пропущены

    С помощью шаблона можно также описать, что делать, если аргумент функции отсутствует.

    Шаблон "x_:v" - если аргумент пропущен, то его значение по умолчанию ( Default ) равно v. Шаблон "x_h:v" - то же с указанием типа.

    Шаблон "x_." - если аргумент пропущен, то его значение по умолчанию ассоциировано с определяемой функцией, а именно, если имя этой функции f, то умолчание хранится в Default[f] (отметим, что Default[f] нужно задавать до определения функции):

    In[126]:=f[x_; 10] := x2;
             f[5] 
             f[5,  7] 
             f[]
    Out[127] = 25
    Out[128] = f [5, 7]
    Out[129] = l00
    In[130]:= Clear [f ]
              Default[f] =  9;
              f[x_.]  : = x2;
              f[5]
              f[5,  7]
              f[]
    Out[133] = 25
    Out[134] = f [5, 7]
    Out[135] = 81

    Команда Clear не очищает значение Default. Чтобы очистить его, воспользуйтесь либо Default[f] =., либо ClearAll[f] :

    In[136]:=Clear[f]
             Definition[f]
    Out[137] =
         Default[f]=9
    In[138]:=Default[f] =. 
             Definition[f]
    Out[139]=Null
    In[140]:=Default[f]=9; 
             f[x_]:=x2 ;
             Definition[f] 
             ClearAll[f]; 
             Definition[f]
    Out[142] =
         f[x_]:=x2
         Default[f]=9 
    Out[144]=Null

    Выбор объектов по шаблону

    Выбор из списка объектов {e1,e2,...} по шаблону pattern можно осуществить с помощью команды Cases[{e1,e2,...},pattern]:

    In[145]:=Cases [{l, {2, x2}, y3 , 2}, _^_]
    Out[145]={y3}

    Выбор из объектов {e1,e2,...} по шаблону pattern на уровнях, заданных levelspec, - командой Cases[{e1,e2,...},pattern,levelspec]:

    In[146]:=Cases [{l, {2, x2}, у3, 2}, _^_, {2}] 
    Out[146]={x2}

    Команда Cases[expr,pattern,levelspec] применима к произвольным выражениям expr:

    In[147]:= Cases [fexp[l, {2, x2} , y3 , 2, g[y, z1/2]], _^_,
              {0,  Infinity}]
    Out[147]={x2, y3, √z }
    In[148] :=Clear [f, tint, fobj ,  fexp,  fseq, fnulseq]

    Опции

    С опциями мы сталкивались выше, настраивая вид графики. Здесь мы разберемся с тем, как они устроены.

    Каждому объекту s можно приписать опции rhs, выполнив команду Options[s] = rhs:

    In[l49]:=Options[s]={a, b, c}
    Out[149]={a, b, c}

    Меняя Options, можно управлять процессом вычисления выражения. В приведенном ниже примере команда MemberQ[Options[s], a] проверяет, входит ли объект a в список Options[s] :

    In[150]:=s[x_]:=If[MemberQ [Options [s], a] , 
               Print["a входит в Options"], 
               Print["a HE входит в Options"]]
             s[2]
           а входит в Options
    In[152]:= Options[s]={b,с}; 
              s[2]
            a HE входит в Options

    У многих встроенных функций и констант имеются заранее заданные опции. Обычно они имеют вид правил $$lhs \to rhs$$. Чтобы посмотреть опции у объекта s, выполните команду Options[s]:

    In[154]:=Options[Plot]
    Out[154] =
         {AlignmentPoint -> Center, AspectRatio -> 1/(GoldenRatio),
         Axes  -> True, AxesLabel  -> None, AxesOrigin  -> Automatic,
         AxesStyle  -> {}, Background  -> None, 
         BaselinePosition  -> Automatic, BaseStyle  -> {},
         ClippingStyle  -> None, ColorFunction  -> Automatic, 
         ColorFunctionScaling  ->True, ColorOutput  ->Automatic, 
         ContentSelectable -> Automatic, 
         CoordinatesToolOptions -> Automatic, 
         DisplayFunction : -> $DisplayFunction, Epilogs {}, 
         Evaluated  -> Automatic, EvaluationMonitor  -> None,
         Exclusions  -> Automatic, ExclusionsStyle -> None, 
         Filling  -> None, FillingStyle  -> Automatic, 
         FormatType : -> TraditionalForm, Frame  -> False, 
         FrameLabel  -> None, FrameStyle  -> {},
         FrameTicks -> Automatic, FrameTicksStyle  -> {}, 
         GridLines  -> None, GridLinesStyle  -> {}, ImageMargins  -> 0.,
         ImagePadding ->  All, ImageSize -> Automatic,
         ImageSizeRaw  -> Automatic, LabelStyle  -> {}, 
         MaxRecursion  -> Automatic, Mesh  -> None, 
         MeshFunctions  -> {Bl }, MeshShading -> None, 
         MeshStyle  -> Automatic, Method  -> Automatic, 
         PerformanceGoal : -> $PerformanceGoal, PlotLabel -> None, 
         PlotPoints -> Automatic, PlotRange  -> {Full, Automatic}, 
         PlotRangeClipping -> True, PlotRangePadding  -> Automatic, 
         PlotRegion  -> Automatic, PlotStyle  -> Automatic, 
         PreservelmageOptions  -> Automatic, Prologs -> {}, 
         RegionFunction  -> (True s) , RotateLabel  -> True, 
         Ticks  -> Automatic, TicksStyle  -> {}, 
         WorkingPrecision -> MachinePrecision}

    Чтобы посмотреть значение конкретной опции объекта s, выполните команду Options[s,name], где name - имя требуемой опции:

    In[155]:=Options[Plot,Plotstyle]
    Out[155]={PlotStyle -> Automatic}
    In[156]:=Plot[{Sin[x],Cos[x]},{x,0,1}]

    Чтобы изменить опции объекта s с именами name1, name2,..., выполните команду $$SetOptions[s, \{name1 \to values1, name2 \to value2, \dots \}]$$:

    In[157]:=SetOptions [Plot,  PlotStyle -> Dashing [{. 05 ,   .01}]]; 
             Options[Plot, PlotStyle]
    Out[158]={PlotStyle ->Dashing[{0.05,0.01}] }
    In[159]:=Plot[{Sin[x], Cos[x]}, {x,0,1}]
    In[160]:=SetOptions [Plot, PlotStyle -> abc] ; 
             Options[Plot, PlotStyle] 
             Plot[{Sin [x] , Cos[x]}, {x,  0, 1}]
    Out[l6l]={PlotStyle -> abc}
    Graphics: :gprim: 
                    abc was encountered where a Graphics primitive or directive was expected. >>
    
    
                 Graphics: :gprim: 
                    abc was encountered where a Graphics primitive or directive was expected. >>

    Для опций, определенных в виде правил замены, имеются удобные способы их использования и изменения в пользовательских функциях. Выражение OptionsPattern[] используется в качестве последовательности опций определяемого выражения. Выражение OptionValue[name] - значение опции name (правая часть выражения $$name \to Rhs$$ ) из списка опций OptionsPattern[]:

    In[16З]:=Clear[s]
             Options[s]={u ->u0,v->v0}; 
             s[x_,OptionsPattern[]]:=
             {x,OptionValue[u],OptionValue[v]} 
             s[l]
             s[l,u->4]
             s[1,u->4,v->7]
             s[l]
    Out[166]={1, u0, v0}
    Out[167]={1, 4, v0}
    Out[168]={1, 4, 7}
    Out[169]={1, u0, v0}

    Список OptionsPattern[s] позволяет использовать в качестве аргумента выражения f опции другого выражения s, не меняя при этом опции самого выражения f:

    In[l70]:=f [x_, OptionsPattern[s]]:=
               {х, OptionValue[u], OptionValue[v]} 
             Options[f]
    Out[171]={}
    In[172]:=f [1]
             f [1,  u -> 4]
             f[l, u -> 4, v -> 7]
             f[l]
    Out[172]= {1, u0,  v0}
    Out[173]= {1, 4, v0}
    Out[174]= {l, 4, 7}
    Out[175]= {1, u0, v0}

    Правила в опциях могут быть как в виде Rule (или $$lhs \to rhs$$ ), так и в виде RuleDelayed (или lhs :> rhs ). В этом примере значение опции с именем u равно 10 и не меняется при изменении х:

    In[176]: = х = 10;
               Options [s]  = {u -> x, v -> v0}; 
               s[l]
    Out[179]= {1, 10, v0}
    In[179]: = x = 8; 
               s[l]
    Out[180]= {1, 10, v0}

    А в этом примере значение опции с именем u равно текущему значению выражения x:

    In[181]: = х = 12;
               Options [s]  = {u: -> x, v -> v0}; 
               s[l]
    Out[183] = {1, 12, v0}
    In[184]:=x = 9; 
             s[l]
    Out[185]= {1, 9, v0}

    В этом примере значение опции с именем u также равно текущему значению выражения x:

    In[186] := Clear [s, x]
               Options [s] = {u -> x} ;
               s[OptionsPattern[]] : = OptionValue[u]
               s[]
               s[u -> 1]
    Out[189] = x
    Out[190] = 1
    In[191]:=x = 5; 
             s[]
    Out[192] = 5
    In[193]: = x = 7; 
               s[]
    Out[194] = 7

    Команда Clear[s] не очищает опции для s. Чтобы очистить s полностью, вместе с опциями (и еще некоторыми связанными с s объектами), воспользуйтесь командой ClearAll[s]:

    In[195] := Clear [s,  f]
               Definition[s]
    Out[196] =
        Options [s]  = {u -> 9}
    In[197]:=ClearAll [s]
             Definition[s]
    Out[198]=Null

    Атрибуты

    Атрибуты служат для задания некоторых специальных неявных свойств функций, таких как коммутативность ( Orderless ), ассоциативность ( Flat ) и другие. Имеется 19 типов возможных атрибутов (см. Help ). Посмотреть атрибуты объекта можно командой Attributes[x]:

    In[199] : = Attributes [Plus]
    Out[199]= {Flat,  bistable, NumericFunction,
               Oneldentity, Orderless,  Protected}

    Задать атрибуты для x можно так: Attributes[x] ={attr1, attr2, ...}:

    In[200]:=С1еагА11 [f, x] 
    In[201]:=f [{1,  2,  3}]
    Out[201] = f [{1,   2,   3}]
    In[202]:=Attributes [f] = {Listable} 
             f [{1, 2,  3}]
    Out[202]= {Listable}
    Out[203] = { f [ 1 ] , f [2],  f [3]}

    Добавить атрибут attr для x можно командой SetAttributes[x,attr]:

    In[204]:=f [f [x, y] , z]
    Out[204] = f [f [x,  y] , z]
    In[205]:=SetAttributes[f,  Flat] 
             f[f[x, y],z]
    Out[206] = f [x, y, z]

    Удалить атрибут attr из списка атрибутов объекта x можно командой ClearAttributes[x, attr]:

    In[207]:=ClearAttributes [f, Flat] 
             f[f[x, y], z]
    Out[208] = f [f [x, y] , z]

    Полный список атрибутов символов в пакете Mathematica:

  • Orderless - коммутативность функции:

    In[209]:=f [х, у]  == f [у,  х]
    Out[209] = f [x, у] ==f[y, x]
    In[210] := SetAttributes [f, Orderless] 
               f [х, у]  == f[y, x]
    Out[211] = True 
    In[212]:=f [f [x, y] , z]
    Out[212] = f [z, f [x, y] ]
  • Flat - "обобщенная" ассоциативность функции (обобщенная в том смысле, что f[f[...[x]]] отождествляется с f[x] ):

    In[213]:=f [f [х, у] ,  z] 
             f[f[f[x]]]
    Out[213] = f [z,   f [x,   y] ]
    Out[214] = f [f [f [x] ] ]
    In[215] := SetAttributes [f,  Flat] 
               f[f[f[x]]] 
               f[f[x, y],  z]
    Out[216] = f [x]
    Out[217] = f [x,   y,   z]
    In[2l8]:= {f [f [a, a, a] , a] , f [f [f [a] , f [a] , f [a]] , a]}
    Out[218] = {f [a,  a,  a,  a],  f[a,  a,  a,  a]}

    Проиллюстрируем особенности взаимодействия функции с атрибутами Flat и Orderless и замены:

    In[219]:= f [a, b, с, d, e] /. f[b, с, d] -> х
    Out[219] = f[a,  e,  x]

    Здесь сначала f[a, b, c, d, e] отождествляется с f[a, f[b, c, d], e] и после делается замена. Аргументы x и e в результирующем выражении переставлены в силу коммутативности.

    Еще пример:

    In[220]:= f [а, Ь,  с, d,  e]  /. f[b,  с, d] -> f[x, у] 
    Out[220] = f [a,  e,  х,  у]

    Здесь после замены f[a, b, c, d, e] на f[a, f[x, y], e] последнее выражение отождествляется с f[a, x, y, e].

  • OneIdentity - наличие этого атрибута приводит к тому что выражение f[f[...f[a]]] заменяется на a внутри другой функции. Работает обычно совместно с атрибутом Flat.

    In[221]:= SetAttributes[f,  Flat]
              f [a, a, a, a]  /. f[x_, x_, x_] ->  g[x]
    Out[222] = f [a,  g[f [a] ] ]
    In[223]:= f [a, b, c, d] /. f [x_, y_, z_] -> g[z]
    Out[223] = g[f [c,  d] ]
    In[224] : = Attributes [f ]
    Out[224]= {Flat, bistable,  Orderless}

    В предыдущем примере атрибут Flat позволяет отождествить выражение f[a, a, a, a] с обоими выражениями: как с f[f[a, a, a], a], так и с f[f[f[a], f[a], f[a]], a]. Если нет атрибута OneIdentity, то происходит отождествление с f[f[f[a], f[a], f[a]], a], таким образом, внутренняя функция f[f[a], f[a], f[a]] заменяется, в итоге, по правилу f[x_, x_, x_] \to g[x] на g[f[a]]:

    In[225] := SetAttributes [f, Oneldentity]\\
               f [a, a, a, a]  /. f[x_, x_, x_] ->  g[x]
    Out[226] = f [ a,  g [ a ] ]

    Теперь установлен атрибут OneIdentity, поэтому выбирается отождествление с f[f[a, a, a], a], что приводит к замене f[a, a, a] на g[a].

  • Listable - функция, примененная к списку, автоматически применяется к каждому аргументу списка:

    In[227]:=f [{1,  2,  3}]
    Out[227]= { f [ 1 ] , f [2], f [3]}
    In[228] := SetAttributes [f, bistable] 
               f [{1, 2,  3}]
    Out[229] ={ f [ 1 ] , f [ 2 ] , f [ 3 ] }
  • Constant - все производные функции равны нулю:

    In[230]:=Dt[f]
    Out[230] = Dt [f ]
    In[231]:= SetAttributes [f, Constant] 
              Dt[f] 
              Dt[f g]
    Out[232] = 0
    Out[233] = f Dt [g]
    In[234] : = Attributes [π]
                Dt[π]
    Out[234]= {Constant,  Protected, ReadProtected}
    Out[235] = 0
  • NumericFunction - предполагается, что функция принимает числовые значения при условии, что ее аргументы - числа. В приводимом ниже примере NumericQ[expr] дает True, если выражение expr числовое, и False в противном случае:

    In[236]: = NumericQ[f [x] ]
               NumericQ[f[2]]
    Out[236] = False
    Out[237] = False
    In[238] := SetAttributes [f, NumericFunction] 
               NumericQ[f[x]] 
               NumericQff[2]]
    Out|239] = False
    Out[240] = True
  • Protected - определения функции не могут изменяться:

    In[241]:=f [х_] := х2
             f[2] SetAttributes [f, Protected]
    Out[242] = 4
    In[244]:=f [x_] : = x3
             f[2]
    SetDelayed::write: Tag f in f[x_] is Protected. >>
    Out[244] = $ Failed
    Out[245] = 4
    In[246]:=ClearAttributes [f, Protected] ; 
             f [x_] : = x3 
             f[2]
    Out[248] = 8
  • Locked - атрибуты функции не могут изменяться до конца текущей сессии Mathematica. Использование одновременно Protected и Locked запрещает менять функцию до конца сессии:

    In[249] := SetAttributes [f, Locked]
               ClearAttributes[f, Locked]
    Attributes::locked: Symbol f is locked. >>
  • ReadProtected - определение функции скрыто:

    In[251]:=g[x_]   := x2
             ?g
    g g[x_]   := x2
    In[253]:=g[x_] := x2
             SetAttributes[g, ReadProtected] 
             ?g
    Attributes[g] = {ReadProtected}
    In[256]:=g[x_] := x3
             ?g
    Attributes[g] = {ReadProtected}
    In[258]:= ClearAttributes [g, ReadProtected] 
             ?g
    g[x_] := x3
  • HoldFirst - первый аргумент функции не вычисляется:

    In[260]:= SetAttributes [h, HoldFirst] 
              h[l + 1, 2+2,  3 + 3]
    Out[261] =h[l + 1,   4,   6]

    В следующем примере ошибка возникает из-за того, что аргумент х сначала вычисляется, а потом уже обрабатывается функцией g. Поэтому происходит попытка присвоить числу 17 значение 25. Этой ошибки можно избежать с помощью атрибута HoldFirst:

    In[262]:=g[sym_, val_] :=  (sym=val^2) 
             x = 17; 
             g[x,  5]
             x
    Set::setraw: Cannot assign to raw object 17.<<
    Out|264] = 25
    Out[265] = 17
    In[266]:=SetAttributes [g,   HoldFirst] ; 
             g[x,  5]
             x
    Out[267] = 25 
    Out[268] = 25

    Аргумент все-таки можно вычислить, если применить к нему функцию Evaluate:

    In[269] :=h [Evaluate [1 + 1] ,  2 + 2,  3 + 3]
    Out[269] = h [ 2 ,   4,   6 ]
  • HoldRest - все аргументы функции, кроме первого, не вычисляются.
  • HoldAll - все аргументы функции не вычисляются.
  • HoldAllComplete - все аргументы функции не вычисляются ни при каких обстоятельствах, например, даже при применении функции Evaluate:

    In[270] := SetAttributes [h,  HoldAllComplete] 
               h[l + 1, 2 + 2,  3 + 3] 
               h [Evaluate [1 + 1] , 2 + 2 , 3 + 3]
    Out[271] = h[l + 1,   2 + 2,   3 + 3]
    Out[272] = h [Evaluate [1 + 1],   2 + 2,   3 + 3]
  • NHoldFirst - первый аргумент функции не подвергается обработке функцией N, переводящей числа в их приближенные десятичные записи.

    В следующем примере вычисляется разложение в ряд Тейлора длины k для функции cos[x] в точке $$x_0$$, являющейся решением уравнения cos[x] = x. Решение этого уравнения находится с помощью функции FixedPoint[f,x], которая вычисляет значение f(f(… f(x))) до тех пор, пока оно не перестает меняться. Начальное значение x в рассматриваемом случае приходится задавать в виде десятичной дроби, иначе FixedPoint пытается все вычислять точно и не срабатывает. Тест ?InexactNumberQ как раз возвращает True, если его аргумент - десятичная дробь:

    In[273] :=ff [k_Integer, х_?InexactNumberQ]   : =
                    Module[{x0},  x0 = FixedPoint[Cos, х] ; 
                       Series [Cos [t] , {t, x0 , k}] ] ;
                gg[k_Integer, x_?InexactNumberQ] :=
                    Module[{x0}, x0 = FixedPoint[Cos, x] ; 
                       Series[Cos[t] ,  {t, x0 , k} ] ] ;
                SetAttributes[ff, NHoldFirst];
    In[276]:={ff [2,  1.] , gg[2,  1.],  ff[2,  1] ,  gg[2,  1]}
    Out[276] =
              {0.739085-0.673612  (t - 0 . 739085)  -
                 0.369543  (t-0.739085)2+O[t-0.739085]3,   0.739085-
                 0.673612  (t - 0.739085) -0.369543  (t - 0.739085)2 + 
                 0[t - 0.739085]3, ff[2,   1], gg[2, 1]}

    Мы видим, что обе функции ff и gg работают, если их аргументы имеют правильный тип, и не работают, если второй аргумент - целое число. Можно попробовать исправить последнее, применив функцию N. Но тогда первый аргумент функции gg перестанет быть целым и она снова не сработает, а функция ff сработает, так как ее первый аргумент не обрабатывается функцией N благодаря установленному атрибуту NHoldFirst.

    In[277]: = N@{ff [2, 1] , gg[2, 1]}
    Out[277] =
        {0.739085-0.673612  (t-0.739085)  -
         0.369543  (t - 0.739085) 2 + 0[t - 0.739085] 3, gg[2., 1 .] }
  • NHoldRest - все аргументы функции, кроме первого, не подвергаются обработке функцией N.
  • NHoldAll - все аргументы функции не подвергаются обработке функцией N.
  • SequenceHold - объекты типа "последовательность" ( Sequence ) не встраиваются в функцию.

    In[278]:= hh[a,  Sequence [b,  с]]
    Out[278] = hh [ a,  b,  с ]
    In[279] := SetAttributes [hh, SequenceHold] 
               hh[a, Sequence[b, c] ]
    Out[280]=hh [a,  Sequence [b,  c] ]
  • Temporary - локальная переменная уничтожается, как только перестает использоваться:

    In[281]: = Module[{x} ,  Print [х] ; Attributes [x] ]
               x$866
    Out[281]= {Temporary}
  • Stub - признак того, что символ закреплен за некоторым пакетом Package, который автоматически загружается при явном использовании этого символа.
  • Символы с атрибутом Stub создаются с помощью команды DeclarePackage[<пакет>,<имя или список имен>] >:

    In[282] :=DeclarePaakage ["ErrorBarPlots' ",  "ErrorListPlot"]
    Out[282] = ErrorBarPlots'

    В результате символ ErrorListPlot получает контекст ErrorBarPlots, который становится первым в списке контекстов. Кроме того, если теперь будет выполнена функция с именем ErrorListPlot, то до ее вычисления с помощью функции Needs будет загружен пакет ErrorBarPlots:

    In[283] : = Attributes ["ErrorListPlot"]
    Out[283]= {Stub}
    In[284] : = 
       ErrorListPlot[Table [ {i, RandomReal [0.5]} , {i, 10}]]

    Можно также определить свою функцию, использующую функции из какого-нибудь (одного) пакета:

    In[285]:=DeclarePackage["Combinatorica ' ",  "tc"] ;
    In[286] := tc [x_]: = ToCycles [x] ;
    In[287]:=tc[{l,  2,   3,  4,  5,   6,   7,   8,   9,   10}]
    Out[287] = { {1} , {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}} 
    In[288]:=ClearAll[ff, gg, g, h, hh, tc]

    Сообщения

    В пакете Mathematica предусмотрен механизм выведения сообщений при выполнении вычислений. Обычно это сообщения об ошибках и предупреждения. Имеется возможность приписывать сообщения любым символам. Чтобы приписать сообщение с именем tag символу symbol, выполните команду symbol::tag = "сообщение".

    In[289]:=g: :lt = " Аргумент  меньше  нуля"
    Out[289] = Аргумент меньше  нуля

    Чтобы вывести сообщение, выполните команду Message[symbol::tag]:

    In[290]:=Message[g: :lt]
    g::lt: Аргумент меньше нуля

    Теперь в определении функции можно задать вывод сообщения при выполнении некоторых условий:

    In[291]: = g[x_] /; If[x < 0, Message [g: : lt] ; False,  True]   : = √x 
    In[292]:=g[l]
    Out[292] = 1 
    In[293]:=g[-l]
    g::lt: Аргумент меньше нуля
    Out[293] = g [ - 1 ]

    В сообщение можно вставить значение выражений expr1,expr2,..., выполнив команду Message[symbol::tag, expr1,expr2,...] , при этом ссылка на выражение expri внутри текста сообщения должна иметь вид 'i':

    In[294] : =
           gg[х_]  / ; If [x < 0 , Message [gg: : It, х] ; False,  True]   := √x 
           gg::lt = "Аргумент   '1'   меньше  нуля";
           gg[-2]
    gg::lt: Аргумент -2 меньше нуля
    Out[296] = gg [-2]

    Отключить сообщение можно командой Off[symbol : tag]:

    In[297]:=Off [gg: :lt]
             gg[-i]
    Out[298]=gg [-1]

    Включить сообщение можно командой On[symbol : tag]:

    In[299]:=On[gg: :lt]
             gg[-i]
    gg::lt: Аргумент -1 меньше нуля
    Out[300] = gg [-1]

    Вывести список всех сообщений, приписанных символу symbol, можно выполнив команду Messages[symbol]:

    In[301] :=Messages [gg]
    Out[30l] = {HoldPattern[gg::It]: -> Аргумент '1' меньше нуля}

    Встроенные функции, как правило, снабжены сообщениями о возможных ошибках. Например,

    In[302]:=Sin[l,2,3]
    Sin::argx: Sin called with 3 arguments; 1 argument is expected.>>
    Out[302]= Sin[l, 2, 3]

    Эти сообщения можно отключить командой Quiet, хотя правильней от этого программа не становится:

    In[303]:=Quiet@Sin[l, 2,  3]
    Out[303] = Sin[l,   2,   3]

    Список сообщений для встроенных функций загружается в Mathematica по мере необходимости. При этом сначала Mathematica ищет сообщение с указанным именем среди сообщений, приписанных обрабатываемой функции. Если его там нет, программа переходит к просмотру списка сообщений для встроенного символа General. Так, в нашем примере сообщение Sin::argx получено именно из списка General. У самой функции Sin список сообщений пуст.

    In[304] :=Messages [Sin]
    Out[304]={ }
    In[305] := Style [Messages [General] ,  FontSize ->  6]
    Out[305] =
       {HoldPattern[General::appname]: -> The name '1' is not valid for the
               application. A valid name smarts with a letter and is followed by lexers and digits., 
        HoldPattern [General::argx]: -> '1' called with '2' arguments; 1 argument is expected.,
        HoldPattern [Generall::bktwrn]: -> " '1' " represents multiplication; use " '2' " 
        to represent a function. '4',
        HoldPattern[General:: catname]: -> The name  '1' is not valid for the
               category. A valid name starts with a letter and is followed by letters and digits.,
        HoldPattern[General::file] : -> ' 2 ' was encountered where a '1'  primitive or directive was expected., 
        HoldPattern[General: :meprec] : -> Internal precision limit $MaxExtraPrecision = '1'  
        reached while evaluating '2'.,
        HoldPattern [General: :multedge] : -> The input graph has multiple edges between some  vertices. These
               will be collapsed into single edges with weight equal to the sum of the individual edges.,
        HoldPattern[General::newsym] : -> $off[], HoldPattern[General::nfunfail] : -> $off[],
        HoldPattern[General: :nosite] :-> Site '1' is not an existing Paclet site.,
        HoldPattern[General: :obsppkgfn]: -> $Off [] ,
        HoldPattern[General::offline]: -> Mathematica is currently configured not to use the
               Internet. To allow Internet use, check the "Allow Mathematica to use the Interne"
               box in ohe Help > Internet Connectivity dialog., HoldPattern [General: : oldversion] :-> 
            Connections to kernls older than Version 2.2 are not supported. This kernel is version '1'.,
        HoldPattern [General::partw] : -> Part '1' of '2'   does not exist., 
        HoldPattern[General::pclt]: -> '1' does not refer to a known paclet.,
        HoldPattern[General::pcltn] : -> No appropriate paclet with name '1' was found.,
        HoldPattern[General::pcltni] : -> No appropriate paclet with name '1' is installed.,
        HoldPattern[General::pcltnv]: -> No appropriate paclet with name '1' and version '2' was found.,
        HoldPattern[General::pcltnvi] : -> No appropriate paclet with name '1' and version '2' is installed.,
        HoldPattern[General::plnr]: -> $off[],
        HoldPatern[General::pp3tr] : -> $off[], HoldPattern[General::pptr]: -> $off[],
        HoldPattern[General::prefdir]: -> The preferences directory '1' cannot be created.,
        HoldPattern[General::shdw]: -> Symbol '1' appears in multiple contexts '2'; definitions in
                Context '3' may shadow or be shadowed by other definitions., HoldPatern[General::shdwcor]: ->
            Symbol '1' defined in '2' already exists in '3'. Select the version you want to use: '4'.,
        HoldPattern[General::spell]: -> $Off[], HoldPattern[General::spell]: -> $Off[],
        HoldPattern[General::stop]: -> Further output of '1' will be suppressed during this calculation.,
        HoldPattern[General::string]: -> String expected at position '1' in '2'.,
        HoldPattern [General::stringopt]: -> '1' in '2' is not a string. All options to '3' must be strings.,
        HoldPattern [General::sysmain]: -> Error loaning the main binary file '1'.
               Get["sysmake.m"] must be run before continuing., HoldPattern[General::write]: 
               -> Tag '1' in '2' is Protected.,
        HoldPattern[General::writewarn] : -> Defining rule for '1'.)
    Вернуться к учебному плану