[PYTHON] Ecriture du langage C avec Sympy (métaprogrammation)

introduction

Qu'est-ce que la ** métaprogrammation **?

** metaprogramming ** (metaprogramming) est un type de technique de programmation qui ne code pas directement la logique, mais plutôt un modèle. Comment programmer avec une logique de haut niveau qui génère une logique avec

Exposant: [wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF%E3%83%97%E3%83%AD%E3%82%B0%E3 % 83% A9% E3% 83% 9F% E3% 83% B3% E3% 82% B0)

En bref, ** Écrivez du code qui génère du code et écrivez du code complexe! ** Cela (je l'interprète. S'il vous plaît laissez-moi savoir si vous faites une erreur).

Aperçu

** Générez des formules en utilisant la bibliothèque de calcul de symboles de Python Sympy et convertissez-les en langage C. ** Sympy semble être souvent utilisé pour le traitement de formules comme Mathematica, mais il a également pour fonction de convertir des formules en différents langages. Je ne l'ai pas beaucoup utilisé, mais il a également la possibilité de générer une fonction avec un fichier d'en-tête.

Dans cet article, en guise d'introduction, nous allons méta-programmer le code de multiplication de la matrice ** n × n avec Sympy. ** ** La notation et l'utilisation de Sympy sont résumées ci-dessous, veuillez donc le lire si vous êtes intéressé.

Installation

Vous pouvez installer Sympy avec pip.

pip install sympy

Pour télécharger, cliquez ci-dessous.

importer

Tout d'abord, importez Sympy.

from sympy import *

Puisque je veux implémenter le calcul matriciel cette fois, je vais également importer Matrix.

from sympy import Matrix

Vous pouvez maintenant également déclarer Matrix.

Créer un symbole

Les variables utilisées dans les formules doivent être déclarées au préalable sous forme de symbole. Par exemple, pour déclarer x et y comme symboles

x = symbols('x')
y = symbols('y')

Si c'est le cas, tout va bien. Cette fois, pour le calcul matriciel, nous définirons le symbole comme un élément de n × n Matrix.

n = 3
A = Matrix([[symbols('a['+str(j)+']['+str(i)+']') for i in range(n)] for j in range(n)])
B = Matrix([[symbols('b['+str(j)+']['+str(i)+']') for i in range(n)] for j in range(n)])

Maintenant, les matrices A et B sont déclarées comme suit: Ici, n = 3.

⎡a[0][0]  a[0][1]  a[0][2]⎤
⎢                         ⎥
⎢a[1][0]  a[1][1]  a[1][2]⎥
⎢                         ⎥
⎣a[2][0]  a[2][1]  a[2][2]⎦

⎡b[0][0]  b[0][1]  b[0][2]⎤
⎢                         ⎥
⎢b[1][0]  b[1][1]  b[1][2]⎥
⎢                         ⎥
⎣b[2][0]  b[2][1]  b[2][2]⎦

La sortie de la matrice peut être comprise visuellement de cette manière en écrivant «pprint (A)».

Multiplication matricielle

Soit le produit des matrices précédentes A et B la matrice C. Il est facile de multiplier la matrice et ce qui suit est OK.

C = A*B

Maintenant, quand vous regardez le contenu avec print (C)

Matrix([[a[0][0]*b[0][0] + a[0][1]*b[1][0] + a[0][2]*b[2][0], a[0][0]*b[0][1] + a[0][1]*b[1][1] + a[0][2]*b[2][1], a[0][0]*b[0][2] + a[0][1]*b[1][2] + a[0][2]*b[2][2]], [a[1][0]*b[0][0] + a[1][1]*b[1][0] + a[1][2]*b[2][0], a[1][0]*b[0][1] + a[1][1]*b[1][1] + a[1][2]*b[2][1], a[1][0]*b[0][2] + a[1][1]*b[1][2] + a[1][2]*b[2][2]], [a[2][0]*b[0][0] + a[2][1]*b[1][0] + a[2][2]*b[2][0], a[2][0]*b[0][1] + a[2][1]*b[1][1] + a[2][2]*b[2][1], a[2][0]*b[0][2] + a[2][1]*b[1][2] + a[2][2]*b[2][2]]])

Vous pouvez voir que le calcul est fait correctement.

Convertir en langage C

Conversion en langage C

ccode(<Formule>, <Variable à attribuer>, standard='C99')

Il est décrit comme. Cette fois, je veux convertir et sortir tous les éléments de la matrice C, donc

for i in range(n):
	for j in range(n):
		idx = i*n+j
		code = ccode(C[idx],assign_to=('c['+str(i)+']['+str(j)+']'), standard='C89')
		print(code)

C'était fabriqué. ʻIdx = i * n + j` est une expression qui transforme i et j en une dimension. Lorsque le code ci-dessus est exécuté, ce qui suit est généré.

c[0][0] = a[0][0]*b[0][0] + a[0][1]*b[1][0] + a[0][2]*b[2][0];
c[0][1] = a[0][0]*b[0][1] + a[0][1]*b[1][1] + a[0][2]*b[2][1];
c[0][2] = a[0][0]*b[0][2] + a[0][1]*b[1][2] + a[0][2]*b[2][2];
c[1][0] = a[1][0]*b[0][0] + a[1][1]*b[1][0] + a[1][2]*b[2][0];
c[1][1] = a[1][0]*b[0][1] + a[1][1]*b[1][1] + a[1][2]*b[2][1];
c[1][2] = a[1][0]*b[0][2] + a[1][1]*b[1][2] + a[1][2]*b[2][2];
c[2][0] = a[2][0]*b[0][0] + a[2][1]*b[1][0] + a[2][2]*b[2][0];
c[2][1] = a[2][0]*b[0][1] + a[2][1]*b[1][1] + a[2][2]*b[2][1];
c[2][2] = a[2][0]*b[0][2] + a[2][1]*b[1][2] + a[2][2]*b[2][2];

Chaque élément de la matrice C a été calculé et produit sous forme de langage C. Correctement; est également joint. Tout ce que vous avez à faire est de coller ceci dans votre code.

Code source

Il s'agit du code de calcul matriciel créé cette fois.

from sympy import *
from sympy import Matrix
from sympy.utilities.codegen import codegen
n = 3
A = Matrix([[symbols('a['+str(j)+']['+str(i)+']') for i in range(n)] for j in range(n)])
B = Matrix([[symbols('b['+str(j)+']['+str(i)+']') for i in range(n)] for j in range(n)])
pprint(A)
pprint(B)
C = A*B
print(C)
for i in range(n):
	for j in range(n):
		idx = i*n+j
		code = ccode(C[idx],assign_to=('c['+str(i)+']['+str(j)+']'), standard='C89')
		print(code)

Résumé

J'ai métaprogrammé le code pour calculer la multiplication matricielle à l'aide de Sympy. Ce type de calcul peut être écrit sans méta-programmation, mais il est très utile lors de l'implémentation d'une formule compliquée telle que "Combien d'ordres de la formule originale sont partiellement différenciés par t". (Y a-t-il un mérite que la vitesse d'exécution de la multiplication de matrice augmente un peu parce qu'il n'y a pas d'instructions for?)

Nous espérons votre référence!

Recommended Posts

Ecriture du langage C avec Sympy (métaprogrammation)
Segfo avec 16 caractères en langage C
Créer un environnement de développement de langage C avec un conteneur
Écriture de journaux dans un fichier CSV (Python, langage C)
Débogage C / C ++ avec gdb
File d'attente ALDS1_3_B langage C
[Algorithme de langage C] Endianness
Superposer des graphiques avec sympy
Avec Sympy, ne t'inquiète pas
[Algorithme de langage C] bloquer le mouvement
[Python] Résoudre des équations avec sympy
Intégration du langage machine en langage C
Recherche binaire ALDS1_4_B langage C
Tri de tas fait en langage C
Equation de mouvement avec sympy
[Langage C] readdir () vs readdir_r ()
Formater la source du langage C avec pycparser
Recherche linéaire ALDS1_4_A en langage C
Utilisons le modèle de conception comme le langage C avec OSS design_pattern_for_c!