Reputation: 1725
I'd like to be able to convert a string expression, e.g. "2.0*x*log(x)", to a function in Julia. The usual way to do pass the value of "x" would be through global variables:
julia> func1 = parse("2.0*x*log(x)");
julia> x = 2.718281828459;
julia> eval(func1)/2.0
2.7182818284589545
However, I'd like to know if I can avoid using global variables. I've tried the following two methods, but was not successful:
Method 1
julia> func2(x) = parse("2.0*x*log(x)");
julia> eval(func2(1.0))/2.0 # should return zero
2.7182818284589545
Method 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
Upvotes: 1
Views: 493
Reputation: 1725
It appears it's also possible to use @generated
to do this:
string = "2.0*x*log(x)"
@generated function my_func(x)
return parse(string)
end
Sample output:
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
Thinking about this further, perhaps it would have been better to use the dot notation for multiplication:
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
Upvotes: 0
Reputation: 2543
With func2
, since you're not interpolating x
within the function, the expression is being built with just symbol x
. This is falling back to your global x
you set when writing func1
.
Try this:
julia> func2(x) = parse("2.0*$x*log($x)");
julia> eval(func2(1.0))
0.0
Or, alternatively,
julia> func2(x) = eval(parse("2.0*$x*log($x)"));
julia> func2(1.0)
0.0
Upvotes: 0
Reputation: 1332
How about doing this:
ex = parse(string)
@eval f(x) = $ex
When I plugged in your string and the number 1 it returned 0, 2 returned 2.772588 and so on.
Upvotes: 4