2016-12-08 2 views
2

Полезно ли при работе с массивами символических выражений использовать массивы numpy?Использование массивов numpy симсимвых чисел

Что-то вроде

u0=numpy.array([Number(1.0), Number(1.0), Number(1.0)])

Я имею в виду, это быстрее использовать Numpy массивы вместо списков питона?

Если да, то некоторые операции с Numpy массивами, кажется, автоматически преобразовывать плавать символические как выражения, например:

u0=np.array([Number(1.0), Number(1.0), Number(1.0)]) u = np.zeros((10, 3)) u[0] = u0

Сейчас пока type(u0[0]) >> sympy.core.numbers.Float,

type(u[0][0]) >> numpy.float64

Как я могу избежать numpy для преобразования символических выражений, скопированных в float64?

+0

'u0' - это 1-й массив' dtype = object'. Это очень похоже на список. 'u' как созданный' float'. Его можно инициализировать как 'dtype = object'. Это тоже будет список, за исключением того, что он позволит индексировать 2d, например. 'И [0,0]'. – hpaulj

+0

Это действительно неясно, чего вы пытаетесь достичь здесь. Я попытался ответить на наиболее вероятные возможности в своем ответе, но, возможно, неправильно понял ваши цели. – asmeurer

ответ

2

Я думаю, что нормально работать с массивами numpy, если это необходимо. Вы должны иметь в виду, что массивы принципиально отличаются от списков. Самое главное: все элементы массива должны быть одного типа, и вы не можете изменить тип.

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

Я сам использую массивы numpy для размещения симплексных выражений. Прежде всего, в тех случаях, когда мне нужно более двух измерений и поэтому не могу использовать матрицы Sympy.

Если единственная причина использования массивов вместо списков - это скорость, возможно, это не рекомендуется. Особенно, поскольку вы должны быть немного осторожны с типами (как вы узнаете), и при использовании списков или, скорее, sympy.Matrix должно быть меньше сюрпризов.

В вашем примере, вы можете решить эту проблему, определив соответствующий тип данных:

u = np.zeros((10, 3), dtype=sp.Symbol) 
+0

Спасибо! Единственная причина - действительно скорость. Вопрос в том, увеличивается ли использование массивов numpy? – D1X

+0

Я думаю, что это зависит от вашей конкретной проблемы. Я тестировал добавление и умножение больших векторов. Там sympy.Matrix дает примерно ту же скорость, что и numpy.array. Я также считаю, что сокращение симплексных выражений является узким местом в большинстве случаев. Если вы расскажете больше о своем случае, возможно, можно дать лучший ответ – dnalow

+1

@dnalow FYI, у Sympy есть [Tensor module] (http://docs.sympy.org/dev/modules/tensor/index.html) , который может обрабатывать многомерные массивы. – Stelios

5

Я сомневаюсь, что есть большая разница скорости по сравнению с перечнем, так как с помощью любого не-NumPy типа данных (т.е. любого Тип данных SymPy) в массиве NumPy приводит к dtype=object, что означает, что массив представляет собой всего лишь массив указателей (что также является list).

Непонятно, почему вы хотите использовать массив NumPy?

Первый вопрос: почему вы не хотите использовать float64? Предположительно используется

  • Символические выражения (например, x**2 или pi),
  • рациональных чисел или
  • sympy.Float объекты с высокой точностью

Это единственные причины, я могу думать о что вы хотите предпочесть тип SymPy над NumPy.

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

Причина в том, что любая математическая функция NumPy не будет работать (или в лучшем случае преобразует массив в float64). Причина в том, что функции NumPy предназначены для работы с типами данных NumPy. Они не знают о вышеуказанных типах данных. Чтобы получить точные значения (символические выражения или рациональные числа) или значения с плавающей запятой более высокой точности (для случая sympy.Float), вам нужно использовать функции SymPy, которые не работают на массивах NumPy.

Если с другой стороны (опять же, неясно, что именно вы пытаетесь сделать), вы хотите выполнять вычисления в SymPy, а затем использовать функции NumPy для численной оценки выражений, вы должны использовать SymPy для создания ваших выражений , а затем lambdify (или ufuncify, если производительность становится проблемой), чтобы преобразовать выражения в эквивалентные функции NumPy, которые могут работать с массивами NumPy типов NumPy.