2016-04-21 78 views
1

我希望能够转换字符串表达式,例如“2.0 * x * log(x)”,转换为Julia中的函数。通常的方式做通“X”的值是通过全局变量:在Julia中,是否可以在不使用全局变量的情况下将值传递给Expr对象?

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

不过,我想知道如果我能避免使用全局变量。我尝试了以下两种方法,但没有成功:

方法1

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

方法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

怎么样字符串宏和一个匿名函数。 '宏p_str(X) ESC(分析(X)) 端 FUNC = X - > P “2.0 * X *日志(X)” FUNC(1.0)' –

+1

或者,假设'funcstring =“2.0 * x * log(x)“',然后''eval(parse(”func1(x)= $ funcstring“))''将用'func1(1.0)== 0.0'定义'func1' –

+0

感谢您的投入 - 这些工作,以及下面的答案。我也意识到也可以使用“@generated”。 – nathanielng

回答

4

如何这样做:

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

当我插入你的字符串和数字1返回0,2返回2.772588依此类推。

0

随着func2,由于您不是在该函数内插入x,该表达式正在使用符号x构建。这正在回落到您在编写func1时设置的全球x

试试这个:

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

julia> eval(func2(1.0)) 
0.0 

,或者,

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

julia> func2(1.0) 
0.0 
0

看来它也可以使用@generated做到这一点:

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

输出示例:

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 

这个进一步的思考,也许它会一直最好使用点符号乘法:

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

我不知道如何解释为什么这样滥用'@ generated'这样一个可怕的想法,但你这里的例子并没有做你认为它正在做的事情。 – user1712368

相关问题