#Dynamicly parse coefficients

1 messages · Page 1 of 1 (latest)

steel stream
#

Is there a way to parse coefficients from generic function like f(x) = 3x^2 - 5x + 4
a = 3, b = -5, c = 5
But i couldn't find a way other than string.

odd maple
#
expr = "f(x) = 3x^2 - 5x + 4"
ex1 = Meta.parse(expr)
dump(ex1)

And you get a syntax tree that you can visit to get the answer

#

Maybe it's not simpler than string though

#
julia> ex1.args[2].args[2].args[2].args[2]
:(3 * x ^ 2)

going down in the tree you can get to individual elements

steel stream
#

Oh that's literally what i need

odd maple
#
julia> dump( ex1.args[2].args[2].args[2].args[2])
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol *
    2: Int64 3
    3: Expr
      head: Symbol call
      args: Array{Any}((3,))
        1: Symbol ^
        2: Symbol x
        3: Int64 2

for a single element you can extract the value here

#

But you need to be careful on how you actually process the tree

steel stream
#

Oh now i realized it's kind of hard

#

if a is negative etc

#
using Plots

f(x) = 3x^2 + 4x - 5

a = 3
b = 4
c = -5

vertex_x = -b / (2a)
vertex_y = f(vertex_x)

x_vals = -20:1:20
y_vals = f.(x_vals)

points = [(x_vals[1], y_vals[1], "f(-20) = $(y_vals[1])", :green), (x_vals[end], y_vals[end], "f(20) = $(y_vals[end])", :orange), (vertex_x, vertex_y, "f($vertex_x) = $vertex_y", :blue)]

p = x_vals |> x -> plot(x, y_vals, xlabel="x", ylabel="f(x)", title="f(x)", label="f(x)", size=(800, 600), legend=:topleft)

for (x, y, label, color) in points
    p |> p -> scatter!(p, [x], [y], markersize=5, markercolor=color, label=label)
end

display(p)
languid path
#

It'd be a lot easier to go the other way around, coefficients to the function

#

But either could work

steel stream
#

Yeah i figured that out too but i need to change 3 parameters everytime instead of single generic function

#

I came from C# so it affects on me too probably

#

Like this it works fine

#

I just don't like it

odd maple
#

I think with a careful tree algo you could make this work. Like 2x - 3x^2 gives you a expressions that's -, 2x, 3x^2, parse the right children first (last element), then when it's done apply the - to the value you've just obtained and then go on with the left children ...

#

But yeah, there's a lot of helper functions to represent polynomials in vector form and evaluate them otherwise

steel stream
#
using Plots

(a, b, c) = (-5, 10, 9)

f(x) = a*x^2 + b*x + c

vertex_x = -b / (2a)
vertex_y = f(vertex_x)

x_vals = -20:1:20
y_vals = f.(x_vals)

points = [(x_vals[1], y_vals[1], "f(-20) = $(y_vals[1])", :green), (x_vals[end], y_vals[end], "f(20) = $(y_vals[end])", :orange), (vertex_x, vertex_y, "f($vertex_x) = $vertex_y", :blue)]

p = x_vals |> x -> plot(x, y_vals, xlabel="x", ylabel="f(x)", title="f(x)", label="f(x)", size=(800, 600), legend=:topleft)

for (x, y, label, color) in points
    p |> p -> scatter!(p, [x], [y], markersize=5, markercolor=color, label=label)
end

display(p)

I'll keep it like this

#

Thanks btw for quick response

#

I'm still learning so i don't bother with it (im kinda lazy)

odd maple
#

Having a polynomial as a vector [c,b,a] and a package that can evaluate it (it's a very common representation for polynomials, though maybe more complex to do that in that case)

steel stream
#

Oh i never taught reversed order

#

okay i'll try to use polynomials package

#

btw it's not reversed

#

damn im blind