Python

Материал из theor
Перейти к: навигация, поиск

TODO

  • просьба разделить основные темы по страницам
  • пример работы с матрицами (определитель, перемножение,...)
  • пример решения уравнений различного типа, и описание того, что умеет делать python (для чего он оптимизирован)
  • список наиболее важных пакетов, для чего они нужны, ссылки на их описание на сайтах help'а python
  • желательно чтобы появились задания/упражнения
  • первый пункт должен быть о том, как поставить python и его дополнения, со ссылками.

Содержание

Сначала - полезные ссылки

http://www.wag.caltech.edu/home/rpm/python_course/

Встроенные функции в Питоне

Введение

Python — высокоуровневый язык программирования общего назначения с акцентом на производительность разработчика и читаемость кода. Синтаксис ядра Python минималистичен. В то же время стандартная библиотека включает большой объём полезных функций. Python поддерживает несколько парадигм программирования, в том числе структурное, объектно-ориентированное, функциональное, императивное и аспектно-ориентированное. Основные архитектурные черты — динамическая типизация, автоматическое управление памятью, полная интроспекция, механизм обработки исключений, поддержка многопоточных вычислений и удобные высокоуровневые структуры данных. Код в Питоне организовывается в функции и классы, которые могут объединяться в модули (которые в свою очередь могут быть объединены в пакеты). Python — активно развивающийся язык программирования, новые версии (с добавлением/изменением языковых свойств) выходят примерно раз в два с половиной года.

См. также


Установка и начало работы с Python


В соответствии с операционной системой, которою вы используете, инсталлятор для Python можно скачать здесь: http://www.python.org/download/ Перед выбором версии Python, стоит проверить, существуют ли аналогичные версии для пакетов NumPy и Matplotlib, чтобы впоследствии избежать проблем с импортированием пакетов, так как мы будем в дальнейшем обращаться к ним.

Установка на Microsoft Windows.

Установка Python не должна вызвать особых трудностей, так как процедура является стандартной и аналогична любой другой установки нового софта. Надо просто скачать и запустить инсталляционный исполняемый файл, который произведёт установку Python на ваш компьютер. Для этого нужно дважды щёлкнуть на инсталляционный файл и на все вопросы отвечать "Yes" или "Next".

С подробной инструкцией можно ознакомится здесь: установка Python.

Пакет Python(x,y)

Пользователям Windows также можно порекомендовать сборку Python(x,y), представляющий собой набор библиотек для численных расчётов и визуализации на основе Python. Включает в себя собственно интерпретатор Python, основные для нас библиотеки SciPy, NumPy, Mathplotlib, а также IDE Spyder, много средств визуализации и быстрого создания GUI, и ещё что-то (подробнее см. Хабр). Скачать пакет можно здесь: Python(x,y) download page (~510 Мб)

Установка на другие операционные системы.

Установка на другие операционные системы несколько отличается от установки на Windows. В Linux или в Mac OS вполне возможно, что Python уже установлен и готов к использованию, поскольку он является стандартным компонентом этих операционных систем. В отдельных версиях Linux и Mac OS (а также в большинстве версий UNIX) Python может собираться из исходных текстов. Процедура установки на других платформах зависит от этих платформ. Например, Python присутствует также в сотовых телефонах, игровых консолях и в проигрывателе iPod, но процедуры установки Python на эти устройства слишком отличаются, чтобы описывать их здесь. Дистрибутив Python можно получить на странице загрузок сайта проекта. Его можно также получить по другим каналам распространения программного обеспечения. Но стоит иметь в виду, что прежде чем приступать к установке, следует убедиться, что Python не был ранее установлен на ваш компьютер. Если вы пользуетесь операционной системой Windows, обычно Python можно найти в меню «Start» (Пуск). В операционных системах Linux и UNIX Python обычно находится в дереве каталогов /usr. Описание более детальной установки Python на Mac OS и Linux можно найти здесь: http://ru.wikisource.org (Погружение в Python 3 (Пилгрим)/Установка Python).


Установка на LINUX без прав root & sudo.

1. Скачать дистрибутив к себе в директорию.

2.

./configure --prefix=/home/username/usr/

3.

make

4.

make install

5.

export PATH=$PATH:/home/username/usr/bin/

6. Переименовать исполняемый файл, чтобы не путать его с установленным питоном на сервере

7. Скачать get-pip.py с http://pip.readthedocs.org/en/latest/installing.html

8. Запустить своим питоном

9. Переименовать, чтобы не путать с установленным pip на сервере pip -> pip_my

9. Установить все нужные пакеты через pip: pip_my install "имя_пакета".


Начало работы с Python.

Python - интерпретируемый язык программирования.Это означает, что исходный код программы не преобразовывается в машинный код для непосредственного выполнения центральным процессором (как в компилируемых языках), а исполняется с помощью специальной программы-интерпретатора. В общем случае, любой язык может быть компилируемым и интерпретируемым, так что данное разделение относится к практике применения языка, а не является его свойством. При этом для многих языков существует различие в производительности между компилируемой и интерпретируемой реализацией. Большое количество языков, включая BASIC, C, Lisp, Pascal и Python, имеют обе реализации.

Поэтому существует несколько способов написания программ и их отладки. Рассмотрим несколько возможных способов.

При установки Python автоматически устанавливается Python (command line) и IDLE (Python GUI). Так что можно использовать их, особенно если надо отладить небольшую программу.

Также можно писать программы в блокноте или любом другом текстовом редакторе (в Notepad++, в частности, есть подсветка синтаксиса), а запускать через консоль (Far или Cmd). Рассмотрим этот пример, запуск программ Python через консоль.

Ещё один способ - это использование поддерживающих Python редакторов (здесь приведён их список: http://wiki.python.org/moin/PythonEditors), либо интегрированных сред разработки (http://wiki.python.org/moin/IntegratedDevelopmentEnvironments).

Занятия по Python

Лекция: Введение в Python Файл:Python intro.pdf

Задания

Задание 1: см. в лекции

Задание 2: Файл:Problem set 2.pdf

Стиль кода в языке Python: Файл:Python code styleguide.pdf

Задание 3: Файл:Python problem set 3.pdf

Задание 4: Файл:Python problem set 4.pdf

Задание 5: Файл:Python problem set 5.pdf

Примеры работы на Python'е

Числа

Python может использоваться как простой калькулятор: Вы можете набирать выражения, и будет выводиться результат. Синтаксис операторов прост: операторы +, -, * и / работают, как и в большинстве других языков (например, в Pascal и C). Для группировки можно использовать скобки. Рассмотрим примеры (будем использовать оболочку Spyder).

  In [1]: 2+2
  Out[1]: 4
  In [2]: (50-5*6)/4
  Out[2]: 5

При целочисленном делении результат округляется в меньшую сторону.

  In [3]: 7/3
  Out[3]: 2
  In [4]: 7/-3
  Out[4]: -3
  In [5]: 7.0/3.0
  Out[5]: 2.3333333333333335

Знак равенства («=») используется для присваивания значения переменной. Присвоенное значение при этом не выводится.

  In [6]: x=20
  In [7]: y=5*9
  In [8]: x*y
  Out[6]: 900

Значение можно присваивать одновременно нескольким переменным.

  In [9]: x=y=z=0
  In [10]: x
  Out[7]: 0
  In [11]: y
  Out[8]: 0
  In [12]: z
  Out[9]: 0

Имеется полная поддержка чисел с плавающей точкой. Операторы со смешанными типами операндов преобразуют целый операнд в число с плавающей точкой.

  In [13]: 4*2.5/3.3
  Out[10]: 3.0303030303030303
  In [14]: 7.0/2
  Out[11]: 3.5

Также поддерживаются и комплексные числа. Мнимая часть записывается с суффиксом j или J. Комплексные числа записываются как (real+imagj) или могут быть созданы функцией complex(real, image).

  In [15]: 1j*1J
  Out[12]: (-1+0j)
  In [16]: 1j*complex(0,1)
  Out[13]: (-1+0j)
  In [17]: 3+1j*3
  Out[14]: (3+3j)
  In [18]: (3+1j)+3
  Out[15]: (6+1j)
  In [19]: (3+1j)*3
  Out[16]: (9+3j)
  In [20]: (1+2j)/(1+1j)
  Out[17]: (1.5+0.5j)

Комплексные числа представляются двумя числами с плавающей точкой – действительной и мнимой частью. Чтобы извлечь эти части из комплексного числа z, используйте z.real и z.imag.

  In [21]: z=1.5+0.5j
  In [22]: z.real
  Out[18]: 1.5
  In [23]: z.imag
  Out[19]: 0.5

Используйте abs(z) для получения абсолютного значения.

  In [32]: z
  Out[20]: (1.5+0.5j)
  In [33]: abs(z)
  Out[21]: 1.5811388300841898

Списки

Python позволяет использовать списки. Рассмотрим примеры (будем использовать оболочку Spyder). Список задается следующим образом:

  In [1]: a=[66.6, 333, 333, 1, 1234.5]
  In [2]: a
  Out[2]: [66.6, 333, 333, 1, 1234.5]

Метод append() позволяет добавить элемент в конец списка:

  In [3]: a.append(333)
  In [4]: a
  Out[4]: [66.6, 333, 333, 1, 1234.5, 333]

Однако иногда необходимо вставить элемент в начало или другую позицию. Это позволяет сделать метод insert – Вы указываете индекс элемента, перед которым новый элемент будет добавлен:

  In [5]: a.insert(2, -1)
  In [6]: a
  Out[6]: [66.6, 333, -1, 333, 1, 1234.5, 333]

Кроме того, для списков определены методы, позволяющие анализировать его содержимое: найти, в каком положении находится (первый) элемент с определенным значением (метод index), или подсчитать количество таких элементов (метод count):

  In [7]: a.index(333)
  Out[7]: 1
  In [8]: a.count(333)
  Out[8]: 3

Метод remove() позволяет удалить из списка (первый) элемент, имеющий заданное значение:

  In [9]: a.remove(333)
  In [10]: a
  Out[10]: [66.6, -1, 333, 1, 1234.5, 333]

Элементы списка можно отсортировать (метод sort()) и изменить порядок следования элементов на противоположный (метод reverse()):

  In [11]: a.sort()
  In [12]: a
  Out[12]: [-1, 1, 66.6, 333, 333, 1234.5]
  In [13]: a.reverse()
  In [14]: a
  Out[14]: [1234.5, 333, 333, 66.6, 1, -1]

Стеки

Методы, определенные для списков, позволяют использовать список в качестве стека, где последний добавленный элемент извлекается первым (LIFO, “last-in, first-out”). Рассмотрим примеры (будем использовать оболочку Spyder). Для добавления элемента в стек используйте метод append(), для извлечения элемента с вершины стека – метод pop() без явного указания индекса:

  In [1]: stack=[3, 4, 5]
  In [2]: stack.append(6)
  In [3]: stack.append(7)
  In [4]: stack
  Out[1]: [3, 4, 5, 6, 7]
  In [5]: stack.pop()
  Out[2]: 7
  In [6]: stack
  Out[3]: [3, 4, 5, 6]
  In [7]: stack.pop()
  Out[4]: 6
  In [8]: stack.pop()
  Out[5]: 5
  In [9]: stack
  Out[6]: [3, 4]

Очереди

Еще одно применение списков – очереди, где элементы извлекаются в том же порядке, в котором они добавлялись (FIFO, “first-in, first-out). Рассмотрим примеры (будем использовать оболочку Spyder). Для добавления элемента используйте метод append(), для извлечения «очередного» элемента – метод pop() с индексом 0:

  In [1]: queue=[3, 4, 5]
  In [2]: queue
  Out[2]: [3, 4, 5]
  In [3]: queue.append(6)
  In [4]: queue.append(7)
  In [5]: queue.pop(0)
  Out[5]: 3
  In [6]: queue.pop(0)
  Out[6]: 4
  In [7]: queue
  Out[7]: [5, 6, 7]

Пакет NumPy

NumPy Пакет (библиотека) языка Python [NumPy] предоставляет программисту средства для высокоэффективной работы с огромными многомерными массивами данных. Как составная часть и основа, пакет [NumPy] входит в большинство проектов, использующих язык Python и требующих громоздких вычислений. Python интерпретируемый язык программирования, как следствие, математические алгоритмы, написанные на Python'е, часто работают заметно медленнее по сравнению с теми же алгоритмами, реализованными на компилируемых языках. Авторы [NumPy] постарались разрешить эту проблему в части обработки массивов, предложив модуль, включающий набор функций для создания многомерных массивов и работы с ними, причем исполняемый код функций реализован на языках C и Fortran. Кроме того, в пакете определены функции линейной алгебры, преобразования Фурье и генерации случайных чисел. Модуль [NumPy] предназначен для работы с массивами, соответственно основной тип данных определенных в модуле - массив (nump.ndarray). Массив - контейнер, содержащий элементы одного типа (и одной длинны, если элементы вложенные массивы), организованные в упорядоченную многомерную таблицу. Доступ к элементам осуществляется по индексу - кортежу целых чисел. Создать массив можно несколькими способами.

Способы создания массивов

Массив может быть создан на основе имеющегося списка (будем использовать оболочку Spyder):

  In [1]: import numpy as np
  In [2]: a=np.array([1, 2, 3, 4, 5])
  In [3]: a
  Out[3]: array([1, 2, 3, 4, 5])
  In [4]: type(a)
  Out[4]: <type 'numpy.ndarray'>

Имя класса numpy.ndarray выбрано специально, чтобы не было путаницы со стандартным классом Python array. Аналогично можно создать многомерный массив:

  In [6]: b
  Out[6]: 
  array([[[ 1,  2],
          [ 3,  4],
          [ 5,  6]],
         [[ 7,  8],
          [ 9, 10],
          [11, 12]]])
  In [7]: type(b)
  Out[7]: <type 'numpy.ndarray'>

Массивы [NumPy] во многом аналогичны стандартным спискам Python. Доступ к элементам массива получают по индексу (разумеется, индекс первого элемента 0):

  In [8]: a[1]
  Out[8]: 2
  In [9]: a[0]
  Out[9]: 1

Для индексации многомерных массивов используют кортежи (индексы перечисляют через запятую):

  In [10]: b[1]
  Out[10]: 
  array([[ 7,  8],
         [ 9, 10],
         [11, 12]])
  In [11]: b[1,1]
  Out[11]: array([ 9, 10])
  In [12]: b[1,1,1]
  Out[12]: 10

От массивов можно брать срезы:

  In [13]: a[2:4]
  Out[13]: array([3, 4])
  In [14]: b[0,1:]
  Out[14]: 
  array([[3, 4],
         [5, 6]])

Каждый объект numpy.ndarray имеет атрибут shape - кортеж целых чисел, который определяет шаблон массива. Здесь под шаблоном подразумевается количество элементов каждой размерности массива, так для матрицы с n строк и m столбцов шаблон (n, m).

  In [15]: a.shape
  Out[15]: (5,)
  In [16]: b.shape
  Out[16]: (2, 3, 2)

Изменяя атрибут shape, можно изменять размерность и структуру массива, но при этом число элементов массива должно оставаться неизменным:

  In [17]: b.shape=(6, 2)
  In [18]: b
  Out[18]: 
  array([[ 1,  2],
         [ 3,  4],
         [ 5,  6],
         [ 7,  8],
         [ 9, 10],
         [11, 12]])
  In [19]: b.shape=(12)
  In [20]: b
  Out[20]: array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])
  In [21]: b.shape=(3, 3)
  Traceback (most recent call last):
    File "<ipython console>", line 1, in <module>
  ValueError: total size of new array must be unchanged

Массив может быть создан с помощью функции numpy.arange(). Функция arange() в самом простом варианте вызова принимает в качестве аргумента целое положительное число n, возвращает массив из n элементов от 0 до n-1:

  In [22]: c=np.arange(5)
  In [23]: c
  Out[23]: array([0, 1, 2, 3, 4])
  In [24]: type(c)
  Out[24]: <type 'numpy.ndarray'>

Полный формат вызова функции: numpy.arange([start,] stop[, step,], dtype = None), где: start - опциональный аргумент, начальное значение интервала, по умолчанию равен 0; stop - обязательный аргумент, конечное значение интервала, не входящее в сам интервал, интервал замыкает значение stop - step; step - опциональный аргумент, шаг итерации, разность между каждым последующим и предыдущим значениями интервала, по умолчанию равен 1; "" - тип элементов массива, по умолчанию None, в этом случае тип элементов определяется по типу переданных функции аргуметов start, stop. Массив может быть создан с помощью функции numpy.linspace(). Функция linspace() в простейшем случае принимает три аргумента - числа: начальный элемент массива, конечный элемент массива, количество элементов массива. Возвращает массив чисел равномерно распределенных от начального до конечного значения.

  In [25]: d=np.linspace(-3.0, 3.0, 7)
  In [26]: d
  Out[26]: array([-3., -2., -1.,  0.,  1.,  2.,  3.])
  In [27]: type(d)
  Out[27]: <type 'numpy.ndarray'>

Полный формат вызова функции: numpy.linspace(start, stop, num = 50, endpoint = True, retstep = False), где: start - обязательный аргумент, первый член последовательности элементов массива; stop - обязательный аргумент, последний член последовательности элементов массива; num - опциональный аргумент, количество элементов массива, по умолчанию равен 50; endpoint - опциональный аргумент, логическое значение, по умолчанию True. Если передано True, stop, последний элемент массива. Если установлено в False, последовательность элементов формируется от start до stop для num + 1 элементов, при этом в возвращаемый массив последний элемент не входит;

  In [28]: e=np.linspace(1.0, 6.0, 5, endpoint=False)
  In [29]: e
  Out[29]: array([ 1.,  2.,  3.,  4.,  5.])

retstep - опциональный аргумент, логическое значение, по умолчанию False. Если передано True, функция возвращает кортеж из двух членов, первый - массив, последовательность элементов, второй - число, приращение между элементами последовательности.

  In [30]: f=np.linspace(0.5, -0.5, 5, retstep=True)
  In [31]: f
  Out[31]: (array([ 0.5 ,  0.25,  0.  , -0.25, -0.5 ]), -0.25)

Массив может быть создан с помощью функций numpy.zeros(), numpy.ones(), numpy.empty(). Функции принимают один обязательный аргумент - кортеж, размерность массива и возвращают массив затребованной структуры содержащий: нули (функция numpy.zeros()), единицы numpy.ones(), произвольный мусор (неинициализированный массив, функция numpy.empty()):

  In [32]: z=np.zeros((3, 3))
  In [33]: z
  Out[33]: 
  array([[ 0.,  0.,  0.],
         [ 0.,  0.,  0.],
         [ 0.,  0.,  0.]])
  In [34]: o=np.ones((3, 3))
  In [35]: o
  Out[35]: 
  array([[ 1.,  1.,  1.],
         [ 1.,  1.,  1.],
         [ 1.,  1.,  1.]])
  In [36]: e=np.empty((3, 3))
  In [37]: e
  Out[37]: 
  array([[  1.55282637e-276,   1.55310182e-276,   1.55257847e-276],
         [  1.55299164e-276,   1.55301919e-276,   1.00000002e+000],
         [  1.00000000e+000,   1.00000000e+000,   1.00000000e+000]])

Полный формат вызова функций: numpy.zeros(shape, dtype = float, order = 'C') numpy.ones(shape, dtype = float, order = 'C') numpy.empty(shape, dtype = float, order = 'C') где: shape - обязательный аргумент, кортеж, требуемая размерность массива; dtype - опциональный аргумент, тип элементов массива, по умолчанию float; order - опциональный аргумент, строка, способ представления данных массива в памяти, два возможных значения 'C' и 'F', пока я не сталкивался с необходимостью изменять умолчальное значение. Последний из рассматриваемых способов с помощью функций numpy.zeros_like(), numpy.ones_like(), numpy.empty_like(). Обязательный аргумент, принимаемый функциями - массив, функции возвращают массив такой же структуры, содержащий, соответственно, нули, единицы и то, что оказалось в памяти на момент создания массива.

  In [38]: d=np.array([1.0, 2.0, 3.0, 4.0, 5.0])
  In [39]: d
  Out[39]: array([ 1.,  2.,  3.,  4.,  5.])
  In [40]: dz=np.zeros_like(d)
  In [41]: dz
  Out[41]: array([ 0.,  0.,  0.,  0.,  0.])
  In [42]: do=np.ones_like(d)
  In [43]: do
  Out[43]: array([ 1.,  1.,  1.,  1.,  1.])
  In [44]: de=np.empty_like(d)
  In [45]: de
  Out[45]: 
  array([  1.91002321e+189,   5.48291880e-316,   0.00000000e+000,
           1.92141081e+189,   6.35862486e-321])

Полный формат вызова функций: numpy.zeros_like(a) numpy.ones_like(a) numpy.empty_like(a) где: a - обязательный аргумент, массив, структуру которого необходимо повторить.

Операции над массивами

Цель создания пакета [NumPy] - предоставить пользователю Python инструменты для "быстрой" работы с большими наборами данных. Объекты класса numpy.ndarray можно использовать как операнды в выражениях, при этом все операции с массивами будут выполняться поэлементно, то есть итогом операции будет новый массив, содержащий результаты применения операции к каждому элементу исходного массива (будем использовать оболочку Spyder):

  In [1]: import numpy as np
  In [2]: a=np.arange(6)
  In [3]: print a
  [0 1 2 3 4 5]
  In [4]: print a+1
  [1 2 3 4 5 6]
  In [5]: print a*3
  [ 0  3  6  9 12 15]
  In [6]: print a**3
  [  0   1   8  27  64 125]
  In [7]: print a<3
  [ True  True  True False False False]
  In [8]: a+=2
  In [9]: print a
  [2 3 4 5 6 7]

В пакете [NumPy] определены основные математические функции, так же позволяющие проводить поэлементные вычисления:

  In [10]: t=np.linspace(0.0, 2*np.pi, 4)
  In [11]: print t
  [ 0.          2.0943951   4.1887902   6.28318531]
  In [12]: print np.cos(t)
  [ 1.  -0.5 -0.5  1. ]
  In [13]: print np.sin(t)
  [  0.00000000e+00   8.66025404e-01  -8.66025404e-01  -2.44929360e-16]
  In [14]: print np.tan(t)
  [  0.00000000e+00  -1.73205081e+00   1.73205081e+00  -2.44929360e-16]
  In [15]: s=np.linspace(2.0, 6.0, 5)
  In [16]: print s
  [ 2.  3.  4.  5.  6.]
  In [17]: s=np.exp(s)
  In [18]: print s
  [   7.3890561    20.08553692   54.59815003  148.4131591   403.42879349]
  In [19]: s=np.log(s)
  In [20]: print s
  [ 2.  3.  4.  5.  6.]
  In [21]: print np.sqrt(s**2)
  [ 2.  3.  4.  5.  6.]

Список самых полезных математических функций пакета NumPy

Во всех определениях ниже a массив или скаляр.

numpy.abs(a) - абсолютное значение a; numpy.around(a, decimals = 0, out = None) - округляет a до заданного количества десятичных разрядов, по умолчанию до целого. Придерживается следующего правила округления. Если значение a находиться точно по середине между двумя целыми, округление производиться до ближайшего четного целого. Так если a равно 1.5 или 2.5 будет возвращено 2, если a равно -0.5 или 0.5 будет возвращено 0.0. Аргумент decimals - целое, десятичный разряд после запятой, до которого производиться округление, если decimals отрицательное, разряд отсчитывается влево от запятой.

  In [22]: print np.around(np.array([0.5, 1.8, 2.5, 3.5]))
  [ 0.  2.  2.  4.]
  In [23]: print np.around(np.array([1, 5, 15, 45]), decimals = 1)
  [ 1  5 15 45]
  In [24]: print np.around(np.array([1, 5, 15, 45]), decimals = -1)
  [ 0  0 20 40]

Аргумент out - массив, в который будет передан результат, структура массива out, должна совпадать со структурой возвращаемого массива. Если None (по умолчанию) будет создан новый массив. numpy.fix(a, out = None) - отбрасывает дробную часть a; numpy.ceil(a, out = None) - округляет a до меньшего из целых больших или равных a;

  In [25]: print np.ceil(np.array([-2.7, -1.2, -0.5, 1.8, 2.4, 3.6]))
  [-2. -1. -0.  2.  3.  4.]

numpy.floor(a, out = None) - округляет a до большего из целых меньших или равных a;

  In [26]: print np.floor(np.array([-2.7, -1.2, -0.5, 1.8, 2.4, 3.6]))
  [-3. -2. -1.  1.  2.  3.]

numpy.sign(a) - возвращает -1 если a < 0, 0 если a == 0, 1 если a > 0; numpy.degrees(a) - конвертирует a из радиан в градусы; numpy.radians(a) - конвертирует a из градусов в радианы; numpy.cos(a), numpy.sin(a), numpy.tan(a) - возвращает косинус, синус, тангенс a. a в радианах; numpy.cosh(a), numpy.sinh(a), numpy.tanh(a) - возвращает гиперболические косинус, синус, тангенс a. a в радианах; numpy.arccos(a), numpy.arcsin(a), numpy.arctan(a) - возвращает арккосинус, арксинус, арктангенс a в радианах. Для арккосинуса в диапазоне [0, nump.pi], для арксинуса [-numpy.pi/2, numpy.pi/2], для арктангенса [-numpy.pi/2, numpy.pi/2]; numpy.arccosh(a), numpy.arcsinh(a), numpy.arctanh(a) - возвращает гиперболические косинус, синус, тангенс a. a в радианах; numpy.exp(a) - возвращает основание натурального логарифма (число e) в степени a; numpy.log(a), numpy.log10(a), numpy.log2(a) - возвращает натуральный логарифм a, логарифм a по основанию 10, логарифм a по основанию 2; numpy.log1p(a) - возвращает натуральный логарифм a + 1; numpy.sqrt(a) - возвращает положительный квадратный корень a; numpy.square(a) - возвращает квадрат a. В выражения можно включать несколько массивов. В случае если атрибуты ndarray.shape этих массивов совпадают, результат очевиден - действия над массивами будут производиться поэлементно:

  In [27]: a1 = np.array([ [1.0, 2.0], [3.0, 4.0] ])
  In [28]: a2 = np.array([ [5.0, 6.0], [7.0, 8.0] ])
  In [29]: a3 = np.array([ [9.0, 10.0], [11.0, 12.0] ])
  In [30]: print a1 + a2 + a3
  [[ 15.  18.]
   [ 21.  24.]]
  In [31]: print a1 * a2
  [[  5.  12.]
   [ 21.  32.]]
  In [32]: print a3 / a1
  [[ 9.          5.        ]
   [ 3.66666667  3.        ]]
  In [33]: print (a3 - a1) * a2
  [[ 40.  48.]
   [ 56.  64.]]

Если атрибуты ndarray.shape не совпадают - действия над массивами производятся в соответствии с концепцией транслирования (broadcasting). Операция транслирования - расширение одного или обоих массивов операндов до массивов с равной размерностью. Для начала несколько примеров:

  In [34]: a2 = np.array([1, 2])
  In [35]: print a2
  [1 2]
  In [36]: print a2.shape
  (2,)
  In [37]: a22 = np.array([ [1, 2], [3, 4] ])
  In [38]: print a22
  [[1 2]
  [3 4]]
  In [39]: print a22.shape
  (2, 2)
  In [40]: a32 = np.array([ [1, 2], [3, 4], [5, 6] ])
  In [41]: print a32
  [[1 2]
   [3 4]
   [5 6]]
  In [42]: print a32.shape
  (3, 2)
  In [43]: a222 = np.array([ [ [1, 2], [3, 4] ], [ [5, 6], [7, 8] ] ])
  In [44]: print a222
  [[[1 2]
    [3 4]]
   [[5 6]
    [7 8]]]
  In [45]: print a222.shape
  (2, 2, 2)
  In [46]: print a22 + a2
  [[2 4]
   [4 6]]
  In [47]: print a32 + a2
  [[2 4]
   [4 6]
   [6 8]]
  In [48]: print a222 + a2
  [[[ 2  4]
    [ 4  6]]
   [[ 6  8]
    [ 8 10]]]
  In [49]: print a32 + a22
  Traceback (most recent call last):
    File "<ipython console>", line 1, in <module>
  ValueError: operands could not be broadcast together with shapes (3,2) (2,2) 
  In [50]: print a222 + a32
  Traceback (most recent call last):
    File "<ipython console>", line 1, in <module>
  ValueError: operands could not be broadcast together with shapes (2,2,2) (3,2)

И так правило. Если длины осей массивов, начиная с замыкающей, попарно равны или в каждой из сравниваемых пар длин хотя бы одна равна единице, то к таким массивам может быть применена операция транслирования. Длина замыкающей оси - длина массива вложенного наиболее глубоко.

  In [51]: a = np.ones((7, 3, 4, 9, 8))
  In [52]: b = np.ones((4, 9, 8))
  In [53]: c = np.ones((4, 3, 8))
  In [54]: print (a + b).shape
  (7, 3, 4, 9, 8)
  In [55]: print (a + c).shape
  Traceback (most recent call last):
    File "<ipython console>", line 1, in <module>
  ValueError: operands could not be broadcast together with shapes (7,3,4,9,8) (4,3,8) 
  In [56]: d = np.ones((9, 7, 1, 6, 1))
  In [57]: e = np.ones((7, 2, 1, 4))
  In [58]: print (d + e).shape
  (9, 7, 2, 6, 4)

В случае если в массивах присутствуют оси единичной длины, расширяться могут оба массива.

  In [59]: f = np.array([1, 2])
  In [60]: print f
  [1 2]
  In [61]: print f.shape
  (2,)
  In [62]: g = np.array([ [3], [4], [5] ])
  In [63]: print g
  [[3]
   [4]
   [5]]
  In [64]: print g.shape
  (3, 1)
  In [65]: h = f + g
  In [66]: print h
  [[4 5]
   [5 6]
   [6 7]]
  In [67]: print h.shape
  (3, 2)

Трансляция массивов происходит и при вызове некоторых функций.

Например, функция numpy.power(a1, a2), где a1, a2 массив или скаляр, возвращает a1 в степени a2:

  In [68]: print np.power(np.array([-2.0, -1.0, 0.0, 2.0, 3.0, 4.0]), 4)
  [  16.    1.    0.   16.   81.  256.]
  In [69]: print np.power(np.array([-2.0, -1.0, 0.0, 2.0, 3.0, 4.0]), -4)
  [ 0.0625      1.                 inf  0.0625      0.01234568  0.00390625]

В случае если у переданных массивов не совпадает структура, проводит трансляцию.

  In [70]: print np.power(np.array([3, 7]), np.array([ [1], [2], [3] ]))
  [[  3   7]
   [  9  49]
   [ 27 343]]

Некоторые полезные функции:

numpy.min(a, axis = None, out = None), numpy.max(a, axis = None, out = None) - возвращает минимальное, максимальное значение элементов массива соответственно:

  In [1]: import numpy as np
  In [2]: print np.min(np.array([ [1.0, -0.5, 3.0], [4.0, 3.0, -0.5] ]))
  -0.5

axis - опциональный аргумент, индекс оси (измерения) массива по которому проводится поиск минимального, максимального значения. Под индексом оси понимается индекс в кортеже ndarray.shape.

  In [3]: a = np.array([ [ [1.0, 2.0, 3.0], [4.0, 5.0, 6.0] ], [ [7.0, 8.0, 9.0], [11, 12, 13] ] ])
  In [4]: print a
  [[[  1.   2.   3.]
    [  4.   5.   6.]]
   [[  7.   8.   9.]
    [ 11.  12.  13.]]]
  In [5]: print a.shape
  (2, 2, 3)
  In [6]: print np.min(a, axis = 0)
  [[ 1.  2.  3.]
   [ 4.  5.  6.]]
  In [7]: print np.min(a, axis = 1)
  [[ 1.  2.  3.]
   [ 7.  8.  9.]]
  In [8]: print np.min(a, axis = 2)
  [[  1.   4.]
   [  7.  11.]]

out - опциональный аргумент, массив, в который будет помещен результат. Структура массива out должна соответствовать структуре массива результата. Если out = None (по умолчанию) будет создан новый массив. numpy.argmin(a, axis = None), numpy.argmax(a, axis = None) - возвращает индекс минимального, максимального значения элементов массива соответственно:

  In [9]: print np.argmin(np.array([ [1.0, -0.5, 3.0], [4.0, 3.0, -0.5] ]))
  1
  In [10]: print np.argmin(a, axis = 0)
  [[0 0 0]
  [0 0 0]]
  In [11]: print np.argmin(a, axis = 1)
  [[0 0 0]
   [0 0 0]]
  In [12]: print np.argmin(a, axis = 2)
  [[0 0]
   [0 0]]

numpy.sum(a, axis = None, dtype = None, out = None), numpy.prod(a, axis = None, dtype = None, out = None) - возвращает сумму, произведение элементов массива соответственно:

  In [13]: print np.sum(np.array([ [1.0, -0.5, 3.0], [4.0, 3.0, -0.5] ]))
  10.0
  In [14]: print np.sum(a, axis = 0)
  [[  8.  10.  12.]
   [ 15.  17.  19.]]
  In [15]: print np.sum(a, axis = 1)
  [[  5.   7.   9.]
   [ 18.  20.  22.]]
  In [16]: print np.sum(a, axis = 2)
  [[  6.  15.]
   [ 24.  36.]]

Пакет Matplotlib

Matplotlib - набор дополнительных модулей (библиотек) языка Python. Предоставляет средства для построения самых разнообразных 2D графиков и диаграмм данных высокого качества. Отличается простотой использования - для построения весьма мудреных и красочно оформленных диаграмм достаточно нескольких строк кода. Она сделана с таким расчетом, чтобы переход на неё доставил минимальные затруднения опытным пользователям матлаба. Как говориться на сайте библиотеки, matplotlib старается сделать простые вещи простыми а сложные вещи возможными.

Построение простого графика при помощи команды plot()

Каждая функция совершает различные изменения с изображением, например создаёт изображение, создаёт область построения на изображении, рисует линии в области построения, добавляет подписи и так далее. При этом matplotlib.pyplot отслеживает состояние текущего изображения, и области построения, так что отрисовывающие функции применяются к текущим осям.

  # Импортируем один из пакетов Matplotlib
  import matplotlib.pyplot as plt
  # Нарисуем одномерный график
  plt.plot([1,2,3])
  # добавляем подпись оси ординат
  plt.ylabel('some numbers')
  # Покажем окно с нарисованным графиком
  plt.show()

В итоге мы получили, что по оси x у нас значения изменятся от 0 до 2, а по 'y' от 1 до 3. Это связано с тем фактом, что если мы передаем один список или массив команде plot(), то matplotlib воспринимает его как последовательность значений переменной y и автоматически генерирует значения x. А поскольку питон начинает считать с 0, то по умолчанию вектор x имеет такую же длину как y, но отсчет начинается с нуля. Таким образом, данные x будут [0,1,2]. plot() универсальная команда и в неё можно передавать произвольное 5.48291880e-316, 0.00000000e+000,

           1.92141081e+189,   6.35862486e-321])

Полный формат вызова функций: numpy.zeros_like(a) numpy.ones_like(a) numpy.empty_like(a) где: a - обязательный аргумент, массив, структуру которого необходимо повторить.

Операции над массивами

Цель создания пакета [NumPy] - предоставить пользователю Python инструменты для "быстрой" работы с большими наборами данных. Объекты класса numpy.ndarray можно использовать как операнды в выражениях, при этом все операции с массивами будут выполняться поэлементно, то есть итогом операции будет новый массив, содержащий результаты применения операции к каждому элементу исходного массива (будем использовать оболочку Spyder):

  In [1]: import numpy as np
  In [2]: a=np.arange(6)
  In [3]: print a
  [0 1 2 3 4 5]
  In [4]: print a+1
  [1 2 3 4 5 6]
  In [5]: print a*3
  [ 0  3  6  9 12 15]
  In [6]: print a**3
  [  0   1   8  27  64 125]
  In [7]: print a количество аргументов. Например для того чтобы отобразить y в зависимости от x, можно выполнить команду: 
  plt.plot([1,2,3,4], [1,4,9,16])

Для каждой пары аргументов (x,y), существует необязательный третий аргумент, строка форматирования, которая определяет цвет и тип линии. Буквы и символы строки форматирования такие же как в матлабе и также как там вы объединяете буквы и символы определяющие цвет и тип линии. По умолчанию строка форматирования выглядит как ‘b-‘, что значит - непрерывная синяя линия. Для того чтобы отобразить данные из предыдущего примера, например, красными кружками, нужно ввести

  import matplotlib.pyplot as plt
  plt.plot([1,2,3,4], [1,4,9,16], 'ro')
  plt.axis([0, 6, 0, 20])

Функция axis() задает свойства осей графика. В частности с её помощью можно установить масштаб осей. Для этого функции необходимо передать одни аргумент - список из четырех значений. Функция рассматривает такой список как [xmin, xmax, ymin, ymax], где данные величины устанавливают минимальные и максимальные границы осей X и Y соответственно. Функция axis() может принимать в качестве одного аргумента и строку. Возможные значения такого аргумента и оказываемые ими действия представлены в таблице.

Аргумент Действие
'off' Выключает отображение осей (вместе с подписями)
'equal' Изменяет масштаб по осям так, чтобы равному изменению x или y соответствовала одинаковая длина на графике. как сказано в документации "круг превращается в круг".
'scaled' Тот же эффект, что у 'equal' достигается изменением соотношения сторон графика.
'tight' Масштаб по осям изменяется так, что бы отображались все данные. Если все данные уже находятся в поле графика, масштаб изменяется так, чтобы линии располагались в центре графика.

Свойства линии

У линий есть множество параметров, которые вы можете установить: толщина, стиль, антиалиасинг и так далее. Приведем список наиболее используемых параметров:

  • color или c - задает цвет линии.
  • marker - задает вид маркера.
  • linestyle - стиль линии.
  • markerfacecolor – задает цвет маркеров.
  • markersize - размер маркера.
  • linewidth или lw - толщина линии.

Покажем несколько способов, как установить необходимые свойства линии:

  • Использовать ключевые слова, то есть вы пишете свойство и присваиваете ему значение:
  plt.plot(x, y, linewidth=2.0)
  • Использовать команду setp(). Пример ниже использует синтаксис похожий на матлабовский для того чтобы установить несколько свойств для списка линий. setp() работает как со списком объектов, так и с одиночным объектом. Вы можете использовать либо аргументы - ключевые слова:
  line = plt.plot([1,2,3,4], [1,4,9,16])
  plt.setp(line, color='r', linewidth=2.0)

либо матлабовский стиль - строка/значение:

  line = plt.plot([1,2,3,4], [1,4,9,16])
  plt.setp(line, 'color', 'r', 'linewidth', 2.0)
  • Третий способ основан на том, что plot() возвращает кортеж объектов, т.е можно сделать так:
  line, = plt.plot([1,2,3,4], [1,4,9,16])

а потом обращаться к свойствам объекта с помощью вызова его методов:

  # отключить сглаживаение 
  line.set_antialiased(False)

Запятая после line, необходима чтобы присвоить переменной именно объект а не кортеж из одного объекта. Могут использоваться различные типы линий, обозначаемые символами: '-', '--', '-.', ':', '.', ',', 'o', 'v', '^', '<', '>', '2', '3', '4', 's', 'p', '*', 'h', 'H', '+', x', 'D', 'd', '|', '_'. Два стиля маркера указывать нельзя, в этом случае мы получим ошибку. Кроме обозначения стиля в строке может содержаться символ, описывающий цвет графика. В следующей таблице показаны символы, обозначающие возможные цвета графика:

символ цвет color
'b' синий blue
'g' зелёный green
'r' красный red
'c' голубой cyan
'm' пурпурный magenta
'y' желтый yellow
'k' черный black
'w' белый white

Как отобразить легенду

Легендой называют табличку, в которой показано, какой график какой линией нарисован. Чтобы показать легенду, нужно вызвать функцию legend() из пакета pylab. Есть несколько способов для добавления легенды. Первый способ В качестве параметра функции legend() нужно передать список или кортеж, содержащий столько элементов, сколько графиков нарисовано в рабочем окне. Элементов может быть и меньше, но в этом случае последние графики, на которых не хватит элементов кортежа или списка, останутся без подписей. Следующий пример рисует два графика и к каждому из них добавляет описание в виде легенды.

  # Импортируем один пакет Numpy
  import numpy as np
  # Импортируем один из пакетов Matplotlib
  import matplotlib as mpl
  import matplotlib.pyplot as plt
  # Cоздаем массив X из 15 элементов, равномерно распределенных в интервале [0, 2.0]
  X = np.linspace(0.0, 2.0, 15)
  # Будем рисовать графики этих функций 
  Y_01 = X
  Y_02 = X * 3
  # Задаем размер (длина, ширина) графика в дюймах 
  mpl.rcParams['figure.figsize'] = (6.0, 8.0)
  # Нарисуем два одномерных графика
  plt.plot(X, Y_01)
  plt.plot(X, Y_02)
  # !!! Добавим легенду и укажем ее размещение.
  # Первому графику будет соответствовать надпись "y = x",
  # Второму графику будет соответствовать надпись "y = 3*x"
  plt.legend (("y = x", "y = 3*x"), loc='best')
  # Задаем заголовок графика
  plt.title('title')
  # Задаем подписи к осям X и Y
  plt.xlabel('X')
  plt.ylabel('Y')
  # Покажем окно с нарисованными графиками
  plt.show()
  # Cтроим сетку координатных осей
  plt.grid()

В результате получим вот такое изображение:

  # Сохраняем построенный график в файл
  # Задаем имя файла, путь к файлу и тип файла
  plt.savefig('c:\\matplotlib\\picture.png', format = 'png')

Функция savefig() сохраняет диаграмму в файл. Первый аргумент - строка, путь к файлу. Именованный аргумент format - строка, задает формат файла, может принимать значения 'png', 'pdf', 'ps', 'eps', 'svg'. Функция legend() задает свойства и расположения легенды диаграммы. В примере использован вызов функции принимающей в качестве первого аргумента подписи для каждой из двух построенных прямых. Именованный аргумент loc задает расположение легенды, может быть или строкой или числом. Возможные варианты значений аргумента loc представлены в таблице.

Значения аргумента loc
Строка Число Расположение легенды
'best' 0 Оптимальное расположение легенды определяется автоматически. Значение по умолчанию
'upper right' 1 сверху справа
'upper left' 2 сверху слева
'lower left' 3 снизу слева
'lower right' 4 снизу справа
'right' 5 справа
'center left' 6 в центре слева
'center right' 7 в центре справа, не отличается от 'right'
'lower center' 8 в центре снизу
'upper center' 9 в центре сверху
'center' 10 в центре диаграммы

Второй способ

Того же самого результата мы можем добиться, если при рисовании графиков будем использовать дополнительный параметр label, а затем вызовем функцию legend() без параметров. Этот способ более удобен тем, что каждому графику сразу приписывается какая-то метка. В этом случае код программы запишется в виде:

  # Импортируем один пакет Numpy
  import numpy as np
  # Импортируем один из пакетов Matplotlib
  import matplotlib as mpl
  import matplotlib.pyplot as plt
  # Cоздаем массив X из 15 элементов, равномерно распределенных в интервале [0, 2.0]
  X = np.linspace(0.0, 2.0, 15)
  # Будем рисовать графики этих функций 
  Y_01 = X
  Y_02 = X * 3
  # Задаем размер (длина, ширина) графика в дюймах 
  mpl.rcParams['figure.figsize'] = (6.0, 8.0)
  # Нарисуем два одномерных графика и сразу зададим их описание.
  # Первому графику будет соответствовать надпись "y = x",
  # Второму графику будет соответствовать надпись "y = 3*x"
  plt.plot(X, Y_01, label = "y = x")
  plt.plot(X, Y_02, label = "y = 3*x")
  # !!! Добавим легенду без параметров и укажем ее размещение
  plt.legend (loc='best')
  # Задаем заголовок графика
  plt.title('title')
  # Задаем подписи к осям X и Y
  plt.xlabel('X')
  plt.ylabel('Y')
  # Покажем окно с нарисованными графиками
  plt.show()
  # Cтроим сетку координатных осей
  plt.grid() 

В легенду можно добавить заголовок, для этого в функцию legend() надо передать дополнительный строковый параметр title со строкой заголовка, т.е. заменить в последней программе строку:

  plt.legend (loc='best')

следующей строкой:

  plt.legend (title = "title of legend", loc='best')

Как нарисовать несколько графиков в одном окне

Часто бывает удобно отобразить несколько независимых графиков в одном окне. Для этого предназначена функция subplot() из пакета pylab. У этой функции есть несколько вариантов ее использования, которые отличаются только лишь способом передачи параметров. Рассмотрим только один из них. Функция subplot() ожидает три параметра:

  • количество строк в графике;
  • количество столбцов в графике;
  • номер ячейки, куда будут выводиться графики, после вызова этой функции. Ячейки нумеруются построчно, начиная с 1. Проще всего сразу рассмотреть пример. В этом примере для простоты будут выводиться одинаковые графики в разные ячейки. Чтобы было более наглядно, в заголовок каждого графика будет добавлена цифра, обозначающая порядковый номер ячейки.
  import  numpy as np
  import  matplotlib.pyplot as plt
  # Импортируем один из пакетов Matplotlib
  import pylab
  # Будем рисовать график этой функции
  def f(x):
  return np.exp(-x) * np.cos(2*np.pi*x)
  # Интервал изменения переменной по оси X
  xmin = 0.0
  xmax = 5.0
  # Шаг между точками
  dx = 0.01
  # Создадим список координат по оиси X на отрезке [-xmin; xmax], включая концы
  xlist = np.arange(xmin, xmax, dx)
  # Вычислим значение функции в заданных точках
  # !!! Две строки, три столбца.
  # !!! Текущая ячейка - 1
  plt.subplot (2, 3, 1)
  plt.plot (xlist,f(xlist))
  plt.title ("1")
  # !!! Две строки, три столбца.
  # !!! Текущая ячейка - 2
  plt.subplot (2, 3, 2)
  plt.plot (xlist, f(xlist))
  plt.title ("2")
  # !!! Две строки, три столбца.
  # !!! Текущая ячейка - 3
  plt.subplot (2, 3, 3)
  plt.plot (xlist, f(xlist))
  plt.title ("3")
  # !!! Две строки, три столбца.
  # !!! Текущая ячейка - 4
  plt.subplot (2, 3, 4)
  plt.plot (xlist, f(xlist))
  plt.title ("4")
  # !!! Две строки, три столбца.
  # !!! Текущая ячейка - 5
  plt.subplot (2, 3, 5)
  plt.plot (xlist, f(xlist))
  plt.title ("5")
  # !!! Две строки, три столбца.
  # !!! Текущая ячейка - 6
  plt.subplot (2, 3, 6)
  plt.plot (xlist, f(xlist))
  plt.title ("6")
  # Покажем окно с нарисованным графиком
  plt.show()


Решение задач на собственные значение.

Рассмотрим стационарное одномерное уравнение Шредингера. Оно предоставляет из себя линейное обыкновенное дифференциальное уравнение второго порядка вида:

<math>-\frac{\hbar^2}{2m}\frac{d^2\psi(x)}{dx^2}+U(x)\psi(x)=E\psi(x), \qquad ( 1 )</math>

где <math>\hbar</math> — постоянная Планка, <math>\! m</math> — масса частицы, <math>\! U(x)</math> — потенциальная энергия, <math>\! E</math> — полная энергия, <math>\! \psi(x)</math> — волновая функция. Для полной постановки задачи о нахождении решения <math>\! ( 1 )</math> надо задать также граничные условия, которые представляются в общем виде для интервала <math>\! [a,b]</math>

<math>\alpha_1\psi(a)+\beta_1\frac{d\psi(a)}{dx}=\gamma_1, \qquad ( 2 )</math>
<math>\alpha_2\psi(b)+\beta_2\frac{d\psi(b)}{dx}=\gamma_2, \qquad ( 3 )</math>

где <math>\! \alpha_1, \alpha_2, \beta_1, \beta_2, \gamma_1, \gamma_2</math> — константы. Квантовая механика рассматривает решения уравнения <math>\! ( 1 )</math>, с граничными условиями <math>\! ( 2 )</math> и <math>\! ( 3 )</math>.

Численные решения

Сколько-нибудь сложный потенциал в уравнении <math>\! ( 1 )</math> уже не позволяет найти аналитическое решение (вернее, это решение можно найти лишь для задачи об одной частице, движущейся в поле другой), и поэтому требуется привлекать численные методы для решения уравнения Шрёдингера. Одним из самых простых и доступных из них является метод конечных разностей, в котором уравнение <math>\! ( 1 )</math> заменяется уравнением в конечных разностях на выбранной сетке с узлами в точках <math>\! x_n</math>, а именно, заменяя вторую производную по формуле
<math>\! \frac{d^2y(x)}{dx^2}=\frac{y_{n-1}-2y_n+y_{n+1}}{h^2}, \qquad ( 4 )</math>

где <math>\! h</math> — шаг дискретизации, <math>\! n</math> — номер узла сетки, получим

<math>\! -\frac{\hbar^2}{2m}\frac{y_{n-1}-2y_n+y_{n+1}}{h^2}+U_ny_n=Ey_n, \qquad ( 5 )</math>

где <math>\! U_n</math> — значение потенциальной энергии <math>\! U(x)</math> на узлах сетки. Пусть <math>\! a</math> некоторый характерных масштаб потенциала, тогда уравнение <math>\! ( 5 )</math> можно записать в безразмерном виде

<math>\! -y_{n-1}+(2+h^2\frac{2ma^2U_n}{\hbar^2})y_n-y_{n+1}=h^2\frac{2ma^2E}{\hbar^2}y_n. \qquad ( 6 )</math>

Если обозначить безразмерные величины потенциальной энергии <math>\! v_n=\frac{2ma^2U_n}{\hbar^2}</math> и собственные значения <math>\! e=h^2\frac{2ma^2E}{\hbar^2}</math>, то уравнение <math>\! ( 6 )</math> упростится

<math>\! -y_{n-1}+(2+h^2 v_n-e)y_n-y_{n+1}=0. </math>

Под последним выражением надо понимать систему уравнений для всех возможных индексов <math>\! n</math>.

Пример простой программы на Python.

Решение задачи на собственные значения.

Задание: выбрать из списка задач одну, решить её, построить энергетические уровни. Список задач, для самостоятельной работы на Python.

Маятник Капицы

Формулировка задачи

Рассчитать численно движение маятника с подвижным основанием, проверить случай устойчивого "перевёрнутого" положения.

  • Общее описание

→ Система представляет собой точечный груз, соединённый с основанием невесомым абсолютно твёрдым стержнем. При этом, основание маятника совершает периодическое колебательное движение.
→ Рассмотрим случай, когда основание маятника колеблется вдоль вертикальной оси по закону z=a*sin(wt).

  • Параметры и переменные

g - ускорение свободного падения
m a - амплитуда колебаний основания
l - длина стержня
w - частота колебаний основания
t - время
φ - угол поворота стержня, отсчитываемый от направления g

  • Используемые библиотеки

пакет NumPy - для работы с массивами.
модуль Math - для вычисления тригонометрических функций.
интерфейс PyLab (библиотека Matplotlib) - для рисования графика.

Аналитическая часть решения

  • Запишем лагранжиан системы <math>\begin{matrix} L = T + U \end{matrix}</math>, где
<math>\begin{matrix}

T = \frac{m l^2 }{2} \dot \varphi^2 + m a l w ~\sin(w t) \sin(\varphi)~\dot\varphi + \frac{m a^2 w^2}{2} \sin^2(w t)

\end{matrix}</math>
- кинетическая энергия маятника,
<math>\begin{matrix}

U = -m g (l cos(\varphi) + a cos(w t))

\end{matrix}</math>
- его потенциальная энергия.
  • Отсюда, записав уравнение Лагранжа, получаем:
<math>\begin{matrix}

\ddot \varphi = - (a~w^2\cos w t~ +g) \frac{\sin \varphi}{l}\;,

\end{matrix}</math>

Это уравнение и будем решать численно. В результате получим зависимость угла φ от времени.

Текст программы

 import  math 
 import numpy
 import pylab
 g=10
 l=1
 w=250
 a=0.1
 #Начальное положение маятника:
 fi=3.1415/2+1
 #Начальная скорость маятника:
 fit=0
 t=0
 dt=0.001
 n=0
 nmax=1000
 # Готовим векторы для графиков:
 tt=import numpy.zeros(nmax+1)
 fifi=import numpy.zeros(nmax+1)
 zz=import numpy.zeros(nmax+1)
 xx=import numpy.zeros(nmax+1)
 while n<nmax+1:
 ::	F=-1*math.sin(fi)*(1/l)*(g+a*w*w*math.sin(w*t))
 ::	fit=fit+F*dt
 ::	fi=fi+fit*dt
 ::	zz[n]=a*math.cos(w*t)-l*math.cos(fi)
 ::	xx[n]=l*math.sin(fi)
 ::	fifi[n]=fi
 ::	tt[n]=t
 ::	t=t+dt
 ::	n=n+1
 
 pylab.plot(xx,zz)
 pylab.show()


Шаг по времени dt должен удовлетворять условию: <math>\begin{matrix} wdt<<2\pi \end{matrix}</math>, где w - максимальная частота процессов в системе.

Результаты деятельности

Траектория маятника в плоскости x,y

Рассчитав через полученную φ(t) зависимость координаты z от времени (как более наглядную величину), забиваем в программу разные условия. При достаточно больших значениях частоты колебаний основания и амплитуде a << l, приходим к задаче, сформулированной П.Л. Капицей для иллюстрации придуманного им метода эффективного потенциала.
Если теперь начальное значение φ положить близким к π, то получим колебания относительно "перевёрнутого" положения равновесия.
Следует отметить, что мы не накладывали никаких ограничений на амплитуду и частоту колебаний основания.

Дополнительные задания

  • Рассчитать аналогичную задачу для случайных колебаний основания (случайная сила). Будет ли в этом случае существовать устойчивое положение равновесия в "перевёрнутом" состоянии?

Список задач, для самостоятельной работы на Python.