Evolutionary.jl icon indicating copy to clipboard operation
Evolutionary.jl copied to clipboard

no method matching NLSolversBase.NonDifferentiable

Open aadimator opened this issue 3 years ago • 3 comments

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
[email protected]: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

aadimator avatar Oct 12 '20 10:10 aadimator

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: https://github.com/wildart/Evolutionary.jl/blob/30d677fcfc19d517f2a974a00bafda34656c468c/src/api/types.jl#L113-L120

wildart avatar Oct 14 '20 05:10 wildart

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.

aadimator avatar Oct 16 '20 06:10 aadimator

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.

wildart avatar Oct 17 '20 03:10 wildart