Reputation: 1603
In Julia 1.0.5, I have a function f(x::Vector{<:Real})
, defined as
f(x::Vector{<:Real}) = (x[1] - 2)^2 + ( x[2] - 1 )^2
The signature is like this, because I would like to use it with the ForwardDiff
package, and it works with it just fine. I give the function to ForwardDiff.gradient
, and everything works like a charm.
However, I would also like to do some visualizations with PyPlot
, using this same function f
. Namely, I would like to draw its contour with contourf
. For this purpose, I have constructed two vectors X::Vector{<:Real}
and Y::Vector{<:Real}
, and would like to call the same function f
with them to produce the contour.
However, making the call f.([X, Y])
is not broadcasting the vectors as I would like, as I get the error
LoadError: MethodError: no method matching (::getfield(Main, Symbol("#f#1044")))(::Int64)
Closest candidates are:
f(!Matched::Array{#s25,1} where #s25<:Real)
This of course prevents me from using the contourf
function, as it needs the values of f
on a 2D-grid.
Do I need to define an entirely different f(x::Vector{<:Real}, y::Vector{<:Real})
to be able to plot the contour as I would like, or is there an alternative where I can avoid this?
Upvotes: 1
Views: 68
Reputation: 1313
this problem can be resolved by the power of multiple dispatch:
f(x::Vector{<:Real}) = (x[1] - 2)^2 + ( x[2] - 1 )^2
f(x::Real,y::Real) = f([x,y])
nx = 10
ny = 20
X = rand(nx) #mesh of x points
Y = rand(ny) #mesh of y points
Z = f.(transpose(X),Y) #nx x ny matrix
for the two argument gradient:
two_point_gradient(f,x,y) = ForwardDiff.gradient(f,[x,y])
G = two_point_gradient.(f,transpose(X),Y) #returns a vector of gradients, where G[i..] = gradient(f,X[i..],Y[i...])
Upvotes: 2