Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no method matching NLSolversBase.NonDifferentiable #69

Open
aadimator opened this issue Oct 12, 2020 · 3 comments
Open

no method matching NLSolversBase.NonDifferentiable #69

aadimator opened this issue Oct 12, 2020 · 3 comments

Comments

@aadimator
Copy link

I've been trying to run GA on my custom structure, Organism, but it's giving the following error:

result = Evolutionary.optimize(
        fitness,
        () -> init_organism("msa_data/temp.tfa"),
        GA(
            populationSize = 50,
        ))

Error

MethodError: no method matching NLSolversBase.NonDifferentiable(::typeof(Main.workspace3.fitness), ::Main.workspace3.Organism)

Closest candidates are:

NLSolversBase.NonDifferentiable(::Any, ::Any, !Matched::AbstractArray) at C:\Users\aadim\.julia\packages\NLSolversBase\QPnui\src\objective_types\nondifferentiable.jl:21

NLSolversBase.NonDifferentiable(::Any, ::TF, !Matched::TX, !Matched::Array{Int64,1}) where {TF, TX} at C:\Users\aadim\.julia\packages\NLSolversBase\QPnui\src\objective_types\nondifferentiable.jl:3

NLSolversBase.NonDifferentiable(::Any, ::Any, !Matched::AbstractArray, !Matched::Union{Real, AbstractArray}) at C:\Users\aadim\.julia\packages\NLSolversBase\QPnui\src\objective_types\nondifferentiable.jl:21

...

optimize(::Function, ::Evolutionary.NoConstraints, ::Function, ::Evolutionary.GA, ::Evolutionary.Options{Nothing})@optimize.jl:30
optimize@optimize.jl:13[inlined]
top-level scope@Local: 1

The init_organism function initializes an object of type Organism and returns it, while the fitness function takes an Organism as input and returns a Number as fitness value. I haven't defined the crossover and mutation functions for now, as I only want to see if the GA is being initialized well.

function fitness(organism::Organism)
	sum = 0
	if !ismissing(organism.alignment)
		alignments = collect(values(organism.alignment))
		for i=(1:length(alignments)-1), j=(i+1:length(alignments))
			a = alignments[i]
			b = alignments[j]
			sum += pairwise_score(
				a, b, 
				matrix=organism.scoring_matrix.matrix, 
				gop=organism.gop, gep=organism.gep)
		end
	end
	sum
end

After a thorough search, I'm unable to figure out the way to solve this problem/error. If anyone could give me some helpful pointers to solve this error message, I'd be grateful. Thanks

@wildart
Copy link
Owner

wildart commented Oct 14, 2020

You need to provide overriding for the NonDifferentiable with the type of your individual, i.e. Organism. Basically, it's a wrapper type that keeps fitness function with its parameter & result in one place.
Look how it is done for the BitVector:

# Constructor for nondifferentiable function over bit vector
NonDifferentiable(f, x::AbstractVector{T}) where {T<:Real}=
NonDifferentiable{T,typeof(x)}(f, zero(T), zeros(T, length(x)), [0,])
NonDifferentiable(f, x::AbstractVector{Bool}) = NonDifferentiable(f, BitVector(x))
function NonDifferentiable(f, x::BitArray)
xs = BitArray(zero(eltype(x)) for i = 1:length(x))
NonDifferentiable{Real,typeof(xs)}(f, f(xs), xs, [0,])
end

@aadimator
Copy link
Author

Thank you for replying. I've thought (and searched) about it long and hard, but I'm unable to figure out how I'm supposed to approach this, because of the lack of documentation for the JuliaNSolvers and mostly because of my inexperience. I'm quite new to the Julia environment and still trying to figure things out, although I'm hopeful and excited to learn about it more.

@wildart
Copy link
Owner

wildart commented Oct 17, 2020

I added an example of supervised learning problem by GA optimization of multi-layer perceptrons, see the notebook in examples/MLP.ipynb

It shows how to fill some missing functionality, when the individuals are custom types (not arrays). For starters, you need to create a NonDifferentiable constructor, and make sure that copy/copyto! functions are working on your individual object. Then, write genetic operations which support your object type. In my example, I reused existing operations by writing wrappers, which accept MLP object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants