[PYTHON] Pratique des extensions réactives

Essayez le calcul du diagramme suivant avec les extensions réactives (ce calcul lui-même n'a aucune signification).

fig.png

Préparation

Cette fois, je vais l'essayer avec Python. Tout d'abord, installez la version Python de Reactive Extensions.

Terminal


pip install Rx

Représenter le diagramme en JSON

Décrivez le module de placement et le câblage du diagramme en JSON.

test.json


{
    "modules": [
        {"name":"add1", "module_type":"add", "inputs":["sin1", "const1"]},
        {"name":"add2", "module_type":"add", "inputs":["mul1", "div1"]},
        {"name":"mul1", "module_type":"mul", "inputs":["sub1", "add1"]},
        {"name":"sub1", "module_type":"sub", "inputs":["sin1", "cos1"]},
        {"name":"div1", "module_type":"div", "inputs":["cos1", "const2"]},
        {"name":"sin1", "module_type":"sin", "inputs":["const1"]},
        {"name":"cos1", "module_type":"cos", "inputs":["add1"]},
        {"name":"out1", "module_type":"out", "inputs":["add2"]},
        {"name":"const1", "module_type":"const", "value":1.0},
        {"name":"const2", "module_type":"const", "value":2.0}
    ]
}

la mise en oeuvre

La création du module, le câblage du module, le réglage de la valeur constante et l'affichage des résultats du calcul sont tous effectués.

test.py


# -*- coding: utf-8 -*-
from rx.subjects import Subject
import json, operator, math

if __name__ == '__main__':
    #Lire JSON
    with open('test.json') as f:
        j = json.load(f)

    #Création de module
    modules = { m['name']:Subject() for m in j['modules'] }

    #Câblage du module
    for m in filter(lambda m: m['module_type'] != 'const', j['modules']):
        module_type = m['module_type'];
        self_name = m['name']
        input_names = m['inputs']
        if   module_type == 'add':
            modules[ input_names[0] ].zip(modules[ input_names[1] ], operator.add) \
                .subscribe(modules[ self_name ].on_next)
        elif module_type == 'sub':
            modules[ input_names[0] ].zip(modules[ input_names[1] ], operator.sub) \
                .subscribe(modules[ self_name ].on_next)
        elif module_type == 'mul':
            modules[ input_names[0] ].zip(modules[ input_names[1] ], operator.mul) \
                .subscribe(modules[ self_name ].on_next)
        elif module_type == 'div':
            modules[ input_names[0] ].zip(modules[ input_names[1] ], operator.truediv) \
                .subscribe(modules[ self_name ].on_next)
        elif module_type == 'sin':
            modules[ input_names[0] ].select(math.sin).subscribe(modules[ self_name ].on_next)
        elif module_type == 'cos':
            modules[ input_names[0] ].select(math.cos).subscribe(modules[ self_name ].on_next)
        elif module_type == 'tan':
            modules[ input_names[0] ].select(math.tan).subscribe(modules[ self_name ].on_next)
        elif module_type == 'out':
            modules[ input_names[0] ].subscribe(print) #Affichage des résultats des calculs

    #Définir une valeur constante
    for m in filter(lambda m: m['module_type'] == 'const', j['modules']):
        self_name = m['name']
        value = m['value']
        modules[ self_name ].on_next(value)

résultat


1.9082290502110406

Source

ReactiveExtensions J'expliquerai la classe et la méthode d'extension utilisée cette fois.

Subject Le sujet est une classe qui a à la fois Observer (observateur) et Observable (observateur). Utilisez le nom comme clé pour en faire un dictionnaire pour une utilisation ultérieure dans le câblage.

Extrait


#Création de module
modules = { m['name']:Subject() for m in j['modules'] }

Select Une opération à un seul terme reçoit (souscrit) la valeur calculée de select et l'envoie au module suivant (on_next).

Extrait


modules[ input_names[0] ].select(math.sin).subscribe(modules[ self_name ].on_next)

Zip Dans l'opération binomiale, la valeur calculée est reçue (abonnement) et envoyée au module suivant (on_next) après alignement des deux valeurs d'entrée.

Extrait


modules[ input_names[0] ].zip(modules[ input_names[1] ], operator.add) \
    .subscribe(modules[ self_name ].on_next)

Vérification

Je vais le vérifier au cas où.

test_check.py


# -*- coding: utf-8 -*-
import math
if __name__ == '__main__':
    sin1 = math.sin(1.0)
    add1 = sin1+1.0
    cos1 = math.cos(add1)
    sub1 = sin1-cos1
    mul1 = sub1*add1
    div1 = cos1/2.0
    add2 = mul1+div1
    out = add2
    print(out)

résultat


1.9082290502110406

je l'ai fait

Recommended Posts

Pratique des extensions réactives
[Python] Extensions réactives apprises avec RxPY (3.0.1) [Rx]
pratique numpy 1
Pratique Linux
Pratiquez Pytorch