# L-10 MCS 507 Wed 13 Sep 2023 : polyroots.jl # This script computes the roots of a polynomial # via the eigenvalues of its companion matrix. import LinearAlgebra struct Polynomial{R} cff::Vector{R} end """ function ( p::Polynomial )(x) Evaluates the polynomial at x. """ function ( p::Polynomial )(x) v = p.cff[end] for i = (length(p.cff)-1):-1:1 v = v*x + p.cff[i] end return v end """ roots(p::Polynomial) returns the roots as the eigenvalues of the companion matrix of p. """ function roots(p::Polynomial) deg = length(p.cff)-1 mat = zeros(deg, deg) for i = 2:deg mat[i,i-1] = 1.0 end for i = 1:deg mat[i,deg] = -p.cff[i]/p.cff[deg+1] end eigvals, eigvecs = LinearAlgebra.eigen(mat) return eigvals end """ test(deg::Int) Generates a polynomial of degree deg with random coefficients and computes its roots. """ function test(deg::Int) c = [rand() for i=1:(deg+1)] p = Polynomial(c) println("the coefficients : $(p.cff)") x = rand() y = p(x) println("value at a random point : $y") r = roots(p) for i=1:length(r) y = p(r[i]) println("the root $i : $(r[i])") println("its residual : $y") end end """ read(deg::Int,verbose::Bool=true) Reads deg+1 complex coefficients of a polynomial. Displays a prompt is verbose. Returns the polynomial. """ function read(deg::Int,verbose::Bool=true) cffs = [] for i=1:deg+1 if verbose print("cff[$i] : ") end line = readline() cnbr = parse(Complex{Float64}, line) append!(cffs, cnbr) end return Polynomial(cffs) end """ function interactive(degree::Int=0, verbose::Bool=true) Prompts the user for the degree (if not provided) and the coefficients of the polynomial. Returns the roots of the polynomial. """ function interactive(degree::Int=0, verbose::Bool=true) if degree > 0 deg = degree else if verbose print("Give the degree : ") end line = readline() deg = parse(Int, line) end if verbose println("degree : $deg") println("reading $(deg+1) coefficients ...") end p = read(deg,verbose) if verbose println("the coefficients : $(p.cff)") end r = roots(p) if verbose println("the roots : $r") end return r end """ main() Runs a random or interactive test """ function main() test(4) # roots = interactive(0, false) # for i=1:length(roots) # println(roots[i]) # end end main()