2017-08-15 2 views
0

Je voudrais former des expressions commeUne simple interpolation en utilisant des expressions dans julia

julia> ex = :(a[$i,$j] + b[$i,$j]) 

parce que je suis intéressé par writting un programme qu'il est capable d'écrire un système d'équations dans lequel l'utilisateur ne donne que la structure d'entre eux et ensuite que Julia écrit explicitement le morceau de code impliqué. De manière plus générale, je voudrais intégrer des fonctions dans une expression, quelque chose comme

julia> ex = :(a[$myfunc(i,j),$j] + b[$i,$j]) 

Lors de l'évaluation de la première ligne de code, je reçois

ERROR: UndefVarError: i not defined 
in eval(::Module, ::Any) at ./boot.jl:226 

D'autre part, si j'écris

julia> ex = :(a[i,j] + b[i,j]) 
:(a[i,j] + b[i,j]) 

julia> for i in 1:2 
      for j in 1:2 
       println(eval(ex)) 
      end 
     end 
ERROR: UndefVarError: i not defined 
in eval(::Module, ::Any) at ./boot.jl:226 
[inlined code] from ./boot.jl:225 
in anonymous at ./<no file>:4294967295 
in eval(::Module, ::Any) at ./boot.jl:226 

Comment l'interpolation est-elle effectuée dans ce cas?

Répondre

3

eval fonctionne à portée globale, il ne peut donc faire référence à aucune variable locale. Ce que vous pouvez faire, cependant, est interpoler cette expression dans un plus grand morceau de code qui est destiné à être exécuté à la portée mondiale:

julia> a = [1 2; 3 4] 
     b = [5 6; 7 8] 
     ex = :(a[i,j] + b[i,j]); 

julia> @eval for i in 1:2 
        for j in 1:2 
         println($ex) 
        end 
       end 
6 
8 
10 
12 

La macro @eval est un raccourci simple pour citer la syntaxe passé et le passage le long à la fonction eval(). Il serait probablement encore mieux de définir une fonction personnalisée:

julia> @eval function f() 
       for i in 1:2 
        for j in 1:2 
         println($ex) 
        end 
       end 
     end 
f (generic function with 1 method) 

julia> f() 
6 
8 
10 
12 

Les mises en garde habituelles sur eval sont applicables: tout code passé peut être construit de manière malveillante de faire des choses infâmes ou surprenants. Ou juste planter le programme.

+0

C'est presque ce que je cherche. Je voudrais obtenir, par exemple. de 'a [i] + b [j]' à 'a [1] + b [4]', comme un morceau de code, plutôt que d'évaluer le contenu à une certaine valeur. Oui, il s'agit plus d'une manipulation algébrique, que d'une simple substitution. La raison en est que plus tard je veux que le programme décide d'écrire des choses comme 'a [1] + a [4] + b [3]' qui peuvent être déterminées par l'utilisateur. – user2820579

+0

En d'autres termes, je veux convertir une expression comme «sum_i = 1, na [i] + b [i]» sous forme de code, c'est-à-dire 'a [1] + b [1]', si 'n = 1' , ou 'a [1] + b [1] + a [2] + b [2]' si 'n = 2'. – user2820579