Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Математические операции над векторами

Поиск

С тех пор, как векторы были введены как массивы чисел имеющие длину и направление, они тут же оказались очень удобны в геометрии и физике. У скорости машины есть значение и направление, есть ускорение и позиция машины также есть точка, которую, как показано выше, можно представить в виде вектора. Грань треугольника также может быть рассмотрена как линия (стрелка), имеющая направление и длину.

В физике и геометрии, использующей векторы, очень важны применяемые математические операции. Давайте рассмотрим наиболее часто встречаемые операции и действующие математические правила. Для этого возьмем два вектора, (u1,u2) и (v1,v2) и для начала сложим их:

(u1,u2)+(v1,v2)=(u1+v1,u2+v2)

Для вычитания применяется такое же правило:

(u1,u2)−(v1,v2)=(u1−v1,u2−v2)

Вектор может быть умножен на число:

a∗(u1,u2)=(a∗u1,a∗u2)

и скалярно на вектор, что даст число:

(u1,u2)∗(v1,v2)=u1∗v1+u2∗v2)

Также возможно и векторное произведение, но рассматривать его здесь будет долго. Длина вектора определяется:

∥(v1,v2)∥=(v1,v2)∗(v1,v2)−−−−−−−−−−−−−√=v21+v22−−−−−−√

Все эти операции можно по аналогии продолжить и на n-мерное пространство.

ВЕКТОРНЫЕ ФУНКЦИИ

Кроме операций, о которых мы напомнили себе выше, существуют и другие, играющие существенную роль в математических приложениях и особенно в таких средах как Matlab, Octave, Python и R. Эти операции вы вряд ли найдете в книгах посвященных математике, они относятся исключительно к потребностям, возникающим при программировании массивов. Для каждого элемента вектора, его компоненты, мы можем сопоставить функцию одной переменной f, тогда мы можем получить и некоторую векторную функцию, в которой компонентами служат функции компонент. Например, у нас есть вектор v=(v0,…,vn−1). Тогда его векторная функция будет выглядеть как f(v)=(f(v0),…,f(vn−1)). Например, синус от v будет записан: sin(v)=(sin(v0),…,sin(vn−1)).

Векторное возведение в степень может означать: vb=(vb0,…,vbn−1). Особое векторное произведение ("asterix" multiplication) определяется как ′u∗v′=(u0v0,u1v1,…,un−1vn−1. В компьютерных вычислениях возможна и операция прибавления скаляра к вектору — число прибавляется к каждому элементу вектора. Возможны и сложные выражения, с которыми мы столкнемся далее.

Снова отметим, что эти функции чаще всего мало имеют отношения к обычной математике векторов, в которой то же складывание вектора и скаляра невозможно, а возведение вектора в квадрат даст число, его длину в квадрате. Эти функции работают поочередно с каждым элементом и результатом функции является уже вектор таких элементов. Такие функции позволяют значительно ускорить работу с массивами, производя одновременно одни и те же действия над всеми элементами.

ИСПОЛЬЗОВАНИЕ СПИСКОВ

Представим, у нас есть функция f(x) и мы хотим применить ее к n числам x1,x2,…,xn−1,xn. Мы можем составить n пар (xi,f(xi)), а можем создать два списка — один со значениями переменной, а другой с соответствующими значениями функции:

>>> def f(x): … return x**3 … >>> n = 5 # number of points along the x axis >>> dx = 1.0/(n-1) # spacing between x points in [0,1] >>> xlist = [i*dx for i in range(n)] >>> ylist = [f(x) for x in xlist] >>> pairs = [[x, y] for x, y in zip(xlist, ylist)]

Здесь для решения задачи мы использовали два приема: генерацию списков и двойной zip-проход по спискам. В списке pairs все элементы представляют собой списки из двух float чисел, в списках xlist и ylist все объекты float. Но список это довольно гибкий объект, и он может содержать объекты любых типов:

mylist = [2, 6.0, 'tmp.ps', [0,1]]

Также мы можем легко изменять, добавлять и удалять новые элементы из любого места списка. Эта гибкость списков делает их очень удобной для программистов, но в случае когда элементы однотипны и их число фиксировано, вместо списков используются массивы. Преимущества массивов в быстроте вычислений, меньшей занимаемой памяти и исключительно обширной математической поддержке таких данных. Поэтому массивы, как вы увидите в этом курсе, на практике (и в крупных математических пакетах) находят такое широкое применение. Списки отныне мы будем применять по назначению — когда нам будет нужно удалять и добавлять элементы и использовать в данных объекты различных типов.

Основы Numerical Python

Объект array может быть рассмотрен как вариант списка, но с учетом следующих допущений и возможностей:

· Все элементы массива представлены одним типом объектов, например целыми, действительными или комплексными числами, что делает их хранение и обработку наиболее эффективным.

· В тот момент, когда создается массив, число его элементов должно быть известно.

· Массивы не являются стандартной частью Python — они требуют специального дополнительного пакета, которым пользуются практически все, кто занимаются научными проектами на Python. Этот пакет называется Numerical Python или еще чаще NumPy, поскольку после его установки вызов осуществляется с помощью обычной инструкции импорта модуля: import numpy. Для того, чтобы установить NumPy, загрузите его с официального сайта проекта. На этой же странице вы обнаружите еще один пакет, который нам понадобится в дальнейшем — SciPy.

· С numpy широкий круг математических операций может быть решен непосредственно с помощью массивов, таким образом исключается потребность в циклах, проходящих по элементам массива. Это свойство носит названия векторизации (vectorization) или прорисовки.

· Массивы с одним индексом также называют векторами. Массивы с двумя индексами используются для создания матриц и представления табличной информации. Массив может содержать практически любое количество индексов, то есть быть n-мерным.

Как уже было сказано, после установки пакета, работа с модулем происходит обычным образом:

from numpy import *

Конвертирование списка r в массив a происходит привычным способом, но с помощью импортированной из numpy функции:

a = array(r)

Для того, чтобы создать массив из n нулевых элементов используем функцию zeros:

a = zeros(n)

Элементы по умолчанию являются float-объектами, второй аргумент функции позволяет изменить тип объектов, например, на int. Часто бывает нужно создать массив из элементов, равномерно распределенных в интервале [p, q]. Для этого в numpy есть функция linspace:

a = linspace(p, q, n)

Вообще говоря в numpy имеется огромное количество функций и внутренних модулей.
Доступ к элементу осуществляется так же как в списках, например, a[1 ]. Срезы тоже здесь работают, например срез a[1:-1], извлекает список всех элементов, кроме первого и последнего. Но в отличие от списка, здесь это не копия. Например:

b = a[1:-1]
b[2] = 0.1

изменится и массив a, его элемент a[3]=0.1.

К СЛОВУ, О СРЕЗАХ

Срез в формате a[i:j:s] выбирает все элементы, начиная с i, заканчивая, но не включая, j с шагом s. Например, срез a[0:-1:2] выбирает каждый второй элемент, кроме последнего. Как и ранее, возможны пропуски аргументов, например a[::4] выберет каждый четвертый элемент. Можно взять и отрицательный шаг, тогда элементы будут идти в обратном порядке.

ЗАДАНИЕ КООРДИНАТ И ЗНАЧЕНИЙ ФУНКЦИЙ

Теперь, когда у нас есть эти простейшие операции, мы можем продолжить пример, в котором мы использовали списки:

>>> from numpy import *
>>> x2 = array(xlist)
>>> y2 = array(ylist)
>>> x2
array([ 0.,0.25, 0.5, 0.75, 1.])
>>> y2
array([ 0., 0.015625, 0.125, 0.421875, 1. ])

Вместо того, чтобы сначала создавать список, а потом конвертировать его в массив будет естественным сразу же создавать массив. Координаты, что мы задавали в xlist легко получить в виде массива с помощью функции linspace. Массив для значений мы создадим с помощью zeros, чтобы ему изначально была правильно отведена длина, в соответствии с числом элементов в xlist. Далее мы заполняем его с помощью цикла:

>>> from numpy import *
>>> n = len(xlist)
>>> x2 = linspace(0, 1, n)
>>> y2 = zeros(n)
>>> for i in xrange(n):
… y2[i] = f(x2[i])

>>> y2
array([ 0., 0.015625, 0.125, 0.421875, 1. ])

Заметьте, что в цикле мы используем вместо range другую функцию — xrange. Она является более предпочтительной для (обычно больших) массивов. Также отметим, что для y мы использовали генерацию списка, а для y2 — цикл for, поскольку массив это не список. Из положения можно выйти с помощью конвертирования:

>>> x2 = linspace(0, 1, n)

>>> y2 = array([f(xi) for xi in x2])

Тем не менее, есть лучший вариант, который объясняется далее.

ВЕКТОРИЗАЦИЯ

Великолепным преимуществом массивов является то, что они могут обходиться без циклов и функция может применяться, как мы объясняли выше, к самому массиву и производить действия над всеми элементами:

>>> y2 = f(x2)
>>> y2 array([ 0., 0.015625, 0.125, 0.421875, 1. ])

И даже сложные составные выражения

r = sin(x)*cos(x)*exp(-x**2) + 2 + x**2

подвластны волшебству массивов:

r = zeros(len(x))
for i in xrange(len(x)):
r[i] = sin(x[i])*cos(x[i])*exp(-x[i]**2) + 2 + x[i]**2

Это свойство и называется векторизацией. Существенный выигрыш в скорости по сравнению со списками происходит из-за того что в генерации списков используется относительно медленные циклы самого Python, в то время как векторизация их никак явно не использует, а задействует «быстрые циклы» внутри numpy. Кроме того, что векторизация существенно повышает скорость обработки, она делает код более понятным и ясным для чтения.

Но приведенный выше код не является “чистой векторизацией”, в нем используется цикл for, без которого можно обойтись, если использовать тригонометрические функции из пакета numpy (которые поддаются векторизации):

from numpy import *
x = linspace(-pi,pi,11)
r = sin(x)*cos(x)*exp(-x**2) + 2 + x**2



Поделиться:


Последнее изменение этой страницы: 2017-02-19; просмотров: 327; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.137.200.56 (0.006 с.)