diff --git a/perf/runbenchmarks.jl b/perf/runbenchmarks.jl new file mode 100644 index 00000000..472cafff --- /dev/null +++ b/perf/runbenchmarks.jl @@ -0,0 +1,15 @@ +using MultivariatePolynomials +using BenchmarkTools + +let + @polyvar x y + p = x + y + 2x^2 + y^3 + + vars = [x, y] + vals = [1.0, 2.0] + + println(@benchmark(($p)($vals, $vars))) + + vars_out_of_order = [vars[2], vars[1]] + println(@benchmark(($p)($vals, $vars_out_of_order))) +end diff --git a/src/subs.jl b/src/subs.jl index 8596477f..bc759fdc 100644 --- a/src/subs.jl +++ b/src/subs.jl @@ -1,14 +1,21 @@ -function evalmap(vars, x::Vector, varorder::Vector{PolyVar}) - vals = Any[var for var in vars] - for (i, var) in enumerate(varorder) - j = findfirst(vars, var) - # If i == 0, that means that the variable is not present - # so it is ignored - if j > 0 - vals[j] = x[i] +function evalmap{T}(vars, x::Vector{T}, varorder::Vector{PolyVar}) + if vars == varorder + x + else + vals = Vector{T}(length(vars)) + for (i, var) in enumerate(varorder) + j = findfirst(vars, var) + # If i == 0, that means that the variable is not present + # so it is ignored + if j > 0 + vals[j] = x[i] + end end + for i in 1:length(vals) + @assert isdefined(vals, i) "Variable $(vars[i]) was not assigned a value" + end + vals end - vals end function monoeval(z::Vector{Int}, vals::Vector) @@ -39,11 +46,7 @@ end function (p::VecPolynomial)(x::Vector, varorder) vals = evalmap(vars(p), x, varorder) - q = zero(p) - for i in 1:length(p) - q += p.a[i] * monoeval(p.x.Z[i], vals) - end - q + sum(i -> p.a[i] * monoeval(p.x.Z[i], vals), 1:length(p)) end function (p::MatPolynomial)(x::Vector, varorder) diff --git a/test/REQUIRE b/test/REQUIRE index bc3e2340..2c328550 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -1 +1,2 @@ FactCheck +BenchmarkTools diff --git a/test/subs.jl b/test/subs.jl index 0bff322b..e2729c46 100644 --- a/test/subs.jl +++ b/test/subs.jl @@ -1,3 +1,5 @@ +import Base.Test: @inferred + facts("Substitution") do @polyvar x[1:3] @@ -23,4 +25,7 @@ facts("Substitution") do P = [1 2 3; 2 4 5; 3 5 6] p = MatPolynomial(P, x) @fact p(ones(3), x) --> 31 + + p = x[1] + x[2] + 2*x[1]^2 + 3*x[1]*x[2]^2 + @inferred p([1.0, 2.0], [x[1], x[2]]) end