TypeError: невозможно преобразовать выражение в floatv - PullRequest
0 голосов
/ 30 ноября 2018

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

"dydt = odeint (model, [0,0], t) # (модель, начальные условия, t)" , возвращается следующееошибка:

«Ошибка типа: невозможно преобразовать выражение в число с плавающей точкой»

Кто-нибудь знает, как это решить?Большое спасибо!Вот мой код:

import matplotlib.pyplot as plt
import numpy as np
from math import *
from scipy.integrate import odeint
from sympy import Symbol

vas= Symbol("vas")
ZL_r= Symbol("ZL_r")
ias= Symbol("ias")
iar_r= Symbol("iar_r")
global A
A = np.array([[1.58730158730159*iar_r*(ZL_r + 1.0) - 1.74603174603175*ias + 1.74603174603175*vas],
         [-1.74603174603175*iar_r*(ZL_r + 1.0) + 1.58730158730159*ias - 1.58730158730159*vas]])

def model(y, t):

    ias = y[0]
    iar_r = y[1]

    alpha = 480.0 / 208
    vas = (480.0/sqrt(3))*sqrt(2)*cos(377*t-30*3.14/180)
    ZL_r = 10*alpha**2

    dydt = [[], []]
    dydt[0] = A[0][0]
    dydt[1] = A[1][0]

    return dydt

t = np.linspace(0,19,50000)
dydt = odeint(model,[0,0],t) #(model, initial conditions, t)

plt.plot(dydt[:, 0])
plt.grid()
plt.show()

1 Ответ

0 голосов
/ 30 ноября 2018

Проблема заключается в том, что dydt, который вы создаете, все еще содержит выражения sympy со свободными символами.Я предполагаю, что ваше намерение с предыдущими назначениями в функции состоит в том, чтобы установить символы во всех выражениях sympy, используя их.Однако назначение в Python является привязкой имени.На самом деле вы просто привязываете вычисленные значения к именам, которые (кстати, в другой функции) были привязаны к символам sympy.

Вам нужно фактически подставить значения в выражение sympy.Быстро и грязно:

dydt = [x[0].subs(locals()) for x in p_I_matrix]

Замените locals() на словарь, составленный из всех заданий, которые вы сделали ранее, чтобы сделать это чище.

Вот функция model с быстрым решением:

def model(y, t):

    ias = y[0]
    ibs = y[1]
    ics = y[2]
    iar_r = y[3]
    ibr_r = y[4]
    icr_r = y[5]

    alpha = 480.0 / 208

    vas = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-30*m.pi/180)
    vbs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-150*m.pi/180)
    vcs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-270*m.pi/180)

    ZL1_r = 10.0 * alpha ** 2
    ZL2_r = 10.0 * alpha ** 2
    ZL3_r = 10.0 * alpha ** 2

    return [x[0].subs(locals()) for x in p_I_matrix]

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

Можно сказать, что использование locals() таким способом не очень чисто, поскольку может заменить любой символв выражении sympy, если случается несвязанное использование локальной переменной с тем же именем.Поэтому лучше явно указать список символов для замены:

def model(y, t):

    ias = y[0]
    ibs = y[1]
    ics = y[2]
    iar_r = y[3]
    ibr_r = y[4]
    icr_r = y[5]

    alpha = 480.0 / 208

    vas = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-30*m.pi/180)
    vbs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-150*m.pi/180)
    vcs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-270*m.pi/180)

    ZL1_r = 10.0 * alpha ** 2
    ZL2_r = 10.0 * alpha ** 2
    ZL3_r = 10.0 * alpha ** 2

    subs_dict = {
        'ias': ias,
        'ibs': ibs,
        'ics': ics,
        'iar_r': iar_r,
        'ibr_r': ibr_r,
        'icr_r': icr_r,
        'vas': vas,
        'vbs': vbs,
        'vcs': vcs,
        'ZL1_r': ZL1_r,
        'ZL2_r': ZL2_r,
        'ZL3_r': ZL3_r
    }

    return [x[0].subs(subs_dict) for x in p_I_matrix]

Версия без симпита, потому что она намного эффективнее:

def make_model(Lls=0.3,Lms=3.0,Llr_r=0.3,rp=1.0,rs=1.0):        

    alpha = 480.0 / 208

    L = np.array([[Lls+Lms, -0.5*Lms, -0.5*Lms, Lms, -0.5*Lms, -0.5*Lms],
              [-0.5*Lms, Lls+Lms, -0.5*Lms, -0.5*Lms, Lms, -0.5*Lms],
              [-0.5*Lms, -0.5*Lms, Lls+Lms, -0.5*Lms, -0.5*Lms, Lms],
              [Lms, -0.5*Lms, -0.5*Lms, Llr_r+Lms, -0.5*Lms, -0.5*Lms],
              [-0.5*Lms, Lms, -0.5*Lms, -0.5*Lms, Llr_r+Lms, -0.5*Lms],
              [-0.5*Lms, -0.5*Lms, Lms, -0.5*Lms, -0.5*Lms, Llr_r+Lms]])

    def model(y, t):

        ias = y[0]
        ibs = y[1]
        ics = y[2]
        iar_r = y[3]
        ibr_r = y[4]
        icr_r = y[5]

        vas = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-30*m.pi/180)
        vbs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-150*m.pi/180)
        vcs = (480.0/m.sqrt(3))*m.sqrt(2)*m.cos(377*t-270*m.pi/180)

        ZL1_r = 10.0 * alpha ** 2
        ZL2_r = 10.0 * alpha ** 2
        ZL3_r = 10.0 * alpha ** 2

        r = np.array([[rp, 0, 0, 0, 0, 0],
              [0, rp, 0, 0, 0, 0],
              [0, 0, rp, 0, 0, 0],
              [0, 0, 0, rs+ZL1_r, 0, 0],
              [0, 0, 0, 0, rs+ZL2_r, 0],
              [0, 0, 0, 0, 0, rs+ZL3_r]])

        v = np.array([[vas],
              [vbs],
              [vcs],
              [0],
              [0],
              [0]])

        i = np.array([[ias],
              [ibs],
              [ics],
              [iar_r],
              [ibr_r],
              [icr_r]])

        inverse_L = np.linalg.inv(L)
        p_I_matrix = np.dot(inverse_L,(v - np.dot(r,i)))
        return [x[0] for x in p_I_matrix]

    return model

t = np.linspace(139.5,140,1000000)
dydt = odeint(make_model(),[0,0,0,0,0,0],t) #(model, initial conditions, t)

Есть также возможности для улучшенияв этой модели функция, но она должна быть намного быстрее и легче писать / читать.

...