2016-04-21 8 views
1

Ich möchte in der Lage sein, einen String-Ausdruck, z. "2.0 * x * log (x)", zu einer Funktion in Julia. Der üblicher Weg, um den Wert von „x“ passieren zu tun, würde durch globale Variablen sein:In Julia, ist es möglich, Werte für die Auswertung in einem Expr-Objekt ohne globale Variablen zu übergeben?

julia> func1 = parse("2.0*x*log(x)"); 
julia> x = 2.718281828459; 
julia> eval(func1)/2.0 
2.7182818284589545 

Allerdings würde Ich mag wissen, ob ich globale Variablen vermeiden kann. Ich habe die folgenden zwei Methoden versucht, war aber nicht erfolgreich:

Methode 1

julia> func2(x) = parse("2.0*x*log(x)"); 
julia> eval(func2(1.0))/2.0 # should return zero 
2.7182818284589545 

Methode 2

julia> function new_func1(input_value) 
      x = input_value 
      eval(func1) 
     end 
new_func1 (generic function with 1 method) 

julia> new_func1(1.0)/2.0 # should return zero 
2.7182818284589545 
+1

Wie wärs mit einem String-Makro und einer anonymen Funktion. 'Makro z_str (x) esc (Parse (x)) Ende func = x -> p "2,0 * x * log (x)" func (1.0)' –

+1

Oder nehme 'funcstring =" 2.0 * x * log (x) "', dann 'eval (parse (" func1 (x) = $ funcstring "))' wird 'func1' definieren mit' func1 (1.0) == 0.0' –

+0

Danke für die Eingaben - all von diesen Arbeiten, wie die Antworten unten tun. Ich erkannte auch, dass es auch möglich ist, "@generated" zu verwenden. – nathanielng

Antwort

4

Wie wäre es, dies zu tun:

ex = parse(string) 
    @eval f(x) = $ex 

Als ich Ihren angeschlossen habe Zeichenkette und die Zahl 1, die es zurückgab 0, 2 gab 2.772588 und so weiter zurück.

0

Mit func2, da Sie x innerhalb der Funktion nicht interpolieren, wird der Ausdruck nur mit dem Symbol x erstellt. Dies fällt zurück auf Ihr globales x, das Sie beim Schreiben von func1 festgelegt haben.

Versuchen Sie folgendes:

julia> func2(x) = parse("2.0*$x*log($x)"); 

julia> eval(func2(1.0)) 
0.0 

Oder alternativ

julia> func2(x) = eval(parse("2.0*$x*log($x)")); 

julia> func2(1.0) 
0.0 
0

Es scheint, es auch möglich ist @generated zu verwenden, um dies zu tun:

string = "2.0*x*log(x)" 
@generated function my_func(x) 
    return parse(string) 
end 

Beispielausgabe:

julia> println(my_func(1.0)) 
0.0 

julia> println(my_func(exp(1.0))/2.0) 
2.718281828459045 

julia> println(my_func(0.5)) 
-0.6931471805599453 

über dieses Denken weiter, vielleicht wäre es besser gewesen, die Punktnotation für die Multiplikation zu verwenden:

string = "2.0.*x.*log(x)" 
@generated function my_func(x) 
    return parse(string) 
end 

julia> x = [1.0 0.5 exp(1.0)] 
1x3 Array{Float64,2}: 
1.0 0.5 2.71828 

julia> my_func(x) 
1x3 Array{Float64,2}: 
0.0 -0.693147 5.43656 
+0

Ich bin mir nicht ganz sicher, wie ich erklären soll, warum es so eine schreckliche Idee ist, '@ generated' auf diese Weise zu missbrauchen, aber Ihr Beispiel hier tut nicht das, was Sie zu tun scheinen. – user1712368