Sympy и агрегаты для электрических систем

Есть ли способ заставить Sympy печатать вольты как вольты вместо того, чтобы возвращать их как состав единиц СИ?

MWE:

>>> import sympy.physics.units as u
>>> V = 5 * u.V
>>> print(V)
5*kg*m**2/(A*s**3)

Редактировать

Как указал @rfkortekaas, я могу определить новые единицы измерения, используя

V = u.Unit('V','V')

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

>>> I = 0.5 * u.A
>>> R = 100 * u.ohm
>>> V_R = I * R
>>> V_R
50.0*kg*m**2/(A*s**3)

Мне еще нужно чтобы V_R распознавалось как "V" (напряжение)

Редактировать 2

Благодаря @rfkortekaas, который до сих пор помогает мне с проблемой, теперь у меня есть:

>>> V = u.Unit('V', 'V')
>>> ohm = u.Unit('ohm = V/u.A', '\Omega')
>>> R = (10 * V) / (0.5 * u.A)
>>> R
20.0*V/A
>>> V_R = (0.5 * u.A) * (10 * ohm)
>>> V_R
5.0*A*\Omega

то есть V/A и A*\Omega распознаются как ohm и 'V' соответственно.


person tcpaiva    schedule 09.08.2015    source источник
comment
Смотрите мое изменение в ответе. К сожалению, вы не можете выполнить последнее редактирование вместе с другими. Это связано с составом уравнения в виде базовых единиц. Таким образом, ом должен быть базовой единицей, чтобы достичь этого, но тогда ни вольт, ни ампер не могут быть базовой единицей и затем будут составлены как другие базовые единицы.   -  person rfkortekaas    schedule 09.08.2015
comment
Спасибо @rfkortekaas. Не возражаете ли вы включить свой последний комментарий в ответ?   -  person tcpaiva    schedule 09.08.2015
comment
Я добавил это в ответ.   -  person rfkortekaas    schedule 09.08.2015


Ответы (2)


Все sympy единицы будут сформированы как базовые единицы SI. Таким образом, все производные единицы будут выражаться как уплотнение основных единиц по С.И.

Базовые единицы формируются классом единиц: sympy.physics.units.Unit('ампер', 'A').

Все производные единицы будут сформированы математической операцией над базовыми (или производными) единицами.

Чтобы определить это по-своему, вы можете сделать это следующим образом: Ампер уже является базовой единицей, поэтому ее можно использовать. Определите вольт как Unit('volt','V'). И определите ом как деление вольта на ампер.

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

person rfkortekaas    schedule 09.08.2015
comment
Я проверил это и увидел, что вы можете создать подкласс класса Unit со своим собственным определением: volt=Unit('volt','V'). Таким образом, вы можете распечатать его с единицей измерения, отличной от СИ. - person rfkortekaas; 09.08.2015
comment
@rfkortekass спасибо, очень полезно. Это решает проблему с одной стороны. Однако мне также нужно, чтобы ohm * ampere распознавалось как напряжение. Я обновлю вопрос. - person tcpaiva; 09.08.2015
comment
Ампер является базовой единицей и может быть использован. Вам также необходимо переопределить ом, чтобы он был сформирован как «Ом = В / мкА», где V — ваше определение вольта, а мкА — базовая единица ампер. - person rfkortekaas; 09.08.2015
comment
Еще раз спасибо, @rfkortekaas. Мы приближаемся! Я сделал вам последнее предложение, и оно работает для одного случая, но не для другого. Я снова отредактирую вопрос, так как его трудно написать здесь. - person tcpaiva; 09.08.2015
comment
Извините за задержку @rfkortekass, пожалуйста, взгляните на отредактированный вопрос, когда у вас будет время. - person tcpaiva; 09.08.2015

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

from sympy.physics import units as u

class Electric:
    units = {}
    units[u.V] = 'V'
    units[u.W] = 'W'
    units[u.A] = 'A' 
    units[u.Hz] = 'Hz'
    units[u.percent] = '\%'
    units[u.F] = 'F'
    units[u.s] = 's'
    units[u.ohm] = '\Omega'

    @classmethod
    def identify_unit(cls, value):
        for unit in cls.units.keys():
            aux = value.as_coefficient(unit)
            if aux:
                if aux.is_number:
                    return aux, cls.units[unit]
        return value

    @classmethod
    def change_factor(cls, value):
        aux = abs(value[0])
        if aux >= u.mega:
            return value[0] / (10 ** 6), "M" + value[1]
        elif aux >= u.kilo:
            return value[0] / (10 ** 3), "k" + value[1]
        elif aux >= 1:
            return value[0], value[1]
        elif aux >= u.milli:
            return value[0] * (10 ** 3), "m" + value[1]
        elif aux >= u.micro:
            return value[0] * (10 ** 6), "\mu{}" + value[1]
        else:
            return value

Пример использования:

>>> V_R = 2 * u.V
>>> print(V_R)
2*kg*m**2/(A*s**3)
>>> print(Electric.identify_unit(V_R))
(2, 'V')
>>> I_R = 1 * u.milli * u.A
>>> print(I_R)
A/1000
>>> print(Electric.identify_unit(I_R))
(1/1000, 'A')
>>> R = V_R / I_R
>>> print(R)
2000*kg*m**2/(A**2*s**3)
>>> a = Electric.identify_unit(R)
>>> print(a)
(2000, '\\Omega')
>>> b = Electric.change_factor(a)
>>> print(b)
(2.00000, 'k\\Omega')
person tcpaiva    schedule 18.08.2015