@@ -324,181 +324,4 @@ function set_node!(tree::AbstractExpressionNode, new_tree::AbstractExpressionNod
324324 return nothing
325325end
326326
327- const OP_NAMES = Base. ImmutableDict (
328- " safe_log" => " log" ,
329- " safe_log2" => " log2" ,
330- " safe_log10" => " log10" ,
331- " safe_log1p" => " log1p" ,
332- " safe_acosh" => " acosh" ,
333- " safe_sqrt" => " sqrt" ,
334- " safe_pow" => " ^" ,
335- )
336-
337- function dispatch_op_name (:: Val{2} , :: Nothing , idx):: Vector{Char}
338- return vcat (collect (" binary_operator[" ), collect (string (idx)), [' ]' ])
339- end
340- function dispatch_op_name (:: Val{1} , :: Nothing , idx):: Vector{Char}
341- return vcat (collect (" unary_operator[" ), collect (string (idx)), [' ]' ])
342- end
343- function dispatch_op_name (:: Val{2} , operators:: AbstractOperatorEnum , idx):: Vector{Char}
344- return get_op_name (operators. binops[idx])
345- end
346- function dispatch_op_name (:: Val{1} , operators:: AbstractOperatorEnum , idx):: Vector{Char}
347- return get_op_name (operators. unaops[idx])
348- end
349-
350- @generated function get_op_name (op:: F ):: Vector{Char} where {F}
351- try
352- # Bit faster to just cache the name of the operator:
353- op_s = string (F. instance)
354- out = collect (get (OP_NAMES, op_s, op_s))
355- return :($ out)
356- catch
357- end
358- return quote
359- op_s = string (op)
360- out = collect (get (OP_NAMES, op_s, op_s))
361- return out
362- end
363- end
364-
365- @inline function strip_brackets (s:: Vector{Char} ):: Vector{Char}
366- if first (s) == ' (' && last (s) == ' )'
367- return s[(begin + 1 ): (end - 1 )]
368- else
369- return s
370- end
371- end
372-
373- # Can overload these for custom behavior:
374- needs_brackets (val:: Real ) = false
375- needs_brackets (val:: AbstractArray ) = false
376- needs_brackets (val:: Complex ) = true
377- needs_brackets (val) = true
378-
379- function string_constant (val)
380- if needs_brackets (val)
381- ' (' * string (val) * ' )'
382- else
383- string (val)
384- end
385- end
386-
387- function string_variable (feature, variable_names)
388- if variable_names === nothing || feature > lastindex (variable_names)
389- return ' x' * string (feature)
390- else
391- return variable_names[feature]
392- end
393- end
394-
395- # Vector of chars is faster than strings, so we use that.
396- function combine_op_with_inputs (op, l, r):: Vector{Char}
397- if first (op) in (' +' , ' -' , ' *' , ' /' , ' ^' )
398- # "(l op r)"
399- out = [' (' ]
400- append! (out, l)
401- push! (out, ' ' )
402- append! (out, op)
403- push! (out, ' ' )
404- append! (out, r)
405- push! (out, ' )' )
406- else
407- # "op(l, r)"
408- out = copy (op)
409- push! (out, ' (' )
410- append! (out, strip_brackets (l))
411- push! (out, ' ,' )
412- push! (out, ' ' )
413- append! (out, strip_brackets (r))
414- push! (out, ' )' )
415- return out
416- end
417- end
418- function combine_op_with_inputs (op, l)
419- # "op(l)"
420- out = copy (op)
421- push! (out, ' (' )
422- append! (out, strip_brackets (l))
423- push! (out, ' )' )
424- return out
425- end
426-
427- """
428- string_tree(
429- tree::AbstractExpressionNode{T},
430- operators::Union{AbstractOperatorEnum,Nothing}=nothing;
431- f_variable::F1=string_variable,
432- f_constant::F2=string_constant,
433- variable_names::Union{Array{String,1},Nothing}=nothing,
434- # Deprecated
435- varMap=nothing,
436- )::String where {T,F1<:Function,F2<:Function}
437-
438- Convert an equation to a string.
439-
440- # Arguments
441- - `tree`: the tree to convert to a string
442- - `operators`: the operators used to define the tree
443-
444- # Keyword Arguments
445- - `f_variable`: (optional) function to convert a variable to a string, with arguments `(feature::UInt8, variable_names)`.
446- - `f_constant`: (optional) function to convert a constant to a string, with arguments `(val,)`
447- - `variable_names::Union{Array{String, 1}, Nothing}=nothing`: (optional) what variables to print for each feature.
448- """
449- function string_tree (
450- tree:: AbstractExpressionNode{T} ,
451- operators:: Union{AbstractOperatorEnum,Nothing} = nothing ;
452- f_variable:: F1 = string_variable,
453- f_constant:: F2 = string_constant,
454- variable_names:: Union{Array{String,1},Nothing} = nothing ,
455- # Deprecated
456- varMap= nothing ,
457- ):: String where {T,F1<: Function ,F2<: Function }
458- variable_names = deprecate_varmap (variable_names, varMap, :string_tree )
459- raw_output = tree_mapreduce (
460- leaf -> if leaf. constant
461- collect (f_constant (leaf. val:: T ))
462- else
463- collect (f_variable (leaf. feature, variable_names))
464- end ,
465- branch -> if branch. degree == 1
466- dispatch_op_name (Val (1 ), operators, branch. op)
467- else
468- dispatch_op_name (Val (2 ), operators, branch. op)
469- end ,
470- combine_op_with_inputs,
471- tree,
472- Vector{Char};
473- f_on_shared= (c, is_shared) -> if is_shared
474- out = [' {' ]
475- append! (out, c)
476- push! (out, ' }' )
477- out
478- else
479- c
480- end ,
481- )
482- return String (strip_brackets (raw_output))
483- end
484-
485- # Print an equation
486- for io in ((), (:(io:: IO ),))
487- @eval function print_tree (
488- $ (io... ),
489- tree:: AbstractExpressionNode ,
490- operators:: Union{AbstractOperatorEnum,Nothing} = nothing ;
491- f_variable:: F1 = string_variable,
492- f_constant:: F2 = string_constant,
493- variable_names:: Union{Array{String,1},Nothing} = nothing ,
494- # Deprecated
495- varMap= nothing ,
496- ) where {F1<: Function ,F2<: Function }
497- variable_names = deprecate_varmap (variable_names, varMap, :print_tree )
498- return println (
499- $ (io... ), string_tree (tree, operators; f_variable, f_constant, variable_names)
500- )
501- end
502- end
503-
504327end
0 commit comments