# Equivalent Circuit Optimization

**URL:** <https://discourse.julialang.org/t/equivalent-circuit-optimization/93907>\
**Category:** Optimization (Mathematical)\
**Tags:** equivalent-circuit, eis\
**Created:** [February 2, 2023, 6:59am UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907 "2023-02-02T06:59:04Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)\
**Post date:** [February 2, 2023, 6:59am UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/1 "2023-02-02T06:59:04Z")

</div>

Hi,  
yesterday I worked on a script provided by [Maxime](https://github.com/MaximeVH/EquivalentCircuits.jl/issues/11) to find an optimal solution for the parameters of an equivalent circuit. For this purpose there is the established python package [impedance.py](https://impedancepy.readthedocs.io/en/latest/getting-started.html),  
but this package fails to compete with a commercial fitting tool.  
The solution provided by Maxime reaches already the quality of the commercial reference software and outperforms the [impedance.py](https://impedancepy.readthedocs.io/en/latest/getting-started.html)-package.  
The number of fitting parameters is 11. Is there beside the optimization package [BlackBoxOptim](https://github.com/robertfeldt/BlackBoxOptim.jl) another suggestion to optimize such problems?  
Here the link to my code:  
[EC\_optimisation\_experiment\_Maxime.jl](https://github.com/StefanPofahl/EquivalentCircuits.jl/blob/master/examples/EC_optimisation_experiment_Maxime.jl#L1)  
Dependency:  
Currently the master version of [EquivalentCircuits.jl](https://github.com/StefanPofahl/EquivalentCircuits.jl) must be installed to enable the execution.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 2, 2023, 4:25pm UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/2 "2023-02-02T16:25:51Z")

</div>

What’s the nature of this optimization problem? Is it

- Nonconvex?
- Does it have constraints? Linear, nonlinear?
- Does it have integer variables?
- Can you compute gradients of the loss and constraint functions?

---

<div class="post-metadata">

**Author:** ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)\
**Post date:** [February 2, 2023, 4:33pm UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/3 "2023-02-02T16:33:45Z")

</div>

It is a continuous parameter space. The problem is the rugged quality mountain. The parameter room is constrained (all parameters are positive). The quality function is nonlinear. The variables are Float64.

> Can you compute gradients of the loss and constraint functions?

I have no experience for this task.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 2, 2023, 4:36pm UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/4 "2023-02-02T16:36:59Z")

</div>

If you write your problem using [Optimization.jl](https://github.com/SciML/Optimization.jl) you can try out a large number of solvers rather easily. You can use BBO through this interface, but also MultistartOptimization.jl and some of the global optimization algorithms from NLopt and Evolutionary.jl etc.

The [docs](https://docs.sciml.ai/Optimization/stable/) has a table of solvers and what problem features they support.

If a particular solver does not support enforcing positivity of the parameters, a common trick is to optimize p\_l = \log(p) instead, that way the parameter seen by the optimizer is unconstrained, and you compute p = \exp(p\_l) in the cost function to get a positive parameter.

---

<div class="post-metadata">

**Author:** ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)\
**Post date:** [February 2, 2023, 4:39pm UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/5 "2023-02-02T16:39:42Z")

</div>

> [@baggepinnen](#):
>
> trick is to optimize p\_l = \log(p)pl=log(p)p\_l = \log(p) instead

thanks 🙂

---

<div class="post-metadata">

**Author:** ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)\
**Post date:** [February 3, 2023, 11:16am UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/6 "2023-02-03T11:16:59Z")

</div>

I have started to use the package `Optimization.jl` but the objective function generated by the package [EquivalentCircuits.jl](https://github.com/MaximeVH/EquivalentCircuits.jl) does not seem to be compatible to the function: `Optimization.OptimizationProblem()` do you have a suggestion?  
Here is my code: [EC\_optimisation\_via\_evolution\_strategy.jl](https://github.com/StefanPofahl/EquivalentCircuits.jl/blob/master/examples/EC_optimisation_via_evolution_strategy.jl#L1)

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 3, 2023, 11:32am UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/7 "2023-02-03T11:32:28Z")

</div>

That’s a rather large amount of code, and it’s not obvious to me where the cost function is defined. What problem do you encounter?

---

<div class="post-metadata">

**Author:** ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)\
**Post date:** [February 3, 2023, 12:05pm UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/8 "2023-02-03T12:05:26Z")

</div>

Thanks for your replay! - The code can be executed without error. If you comment-in line l103:

```julia
prob = Optimization.OptimizationProblem(objective, initial_parameters, SciMLBase.NullParameters(),; lb = lower, ub = upper)

```

The message starts with:

```julia
ERROR: All methods for the model function `f` had too few arguments. [...]

```

The object function `objective` that causes the issue is compatible to `Optim.optimize()`,  
but not to `Optimization.OptimizationProblem()`.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 3, 2023, 1:06pm UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/9 "2023-02-03T13:06:46Z")

</div>

Optimization.jl assumes that your objective function takes two arguments `cost(x, p)`

1. The optimization variables `x`
2. Other parameters `p`

If you have no “other parameters”, you can create an anonymous function that just discards the extra parameters like this

```julia
obj = (x, p) -> objective(x)

```

and pass `obj` into Optimization.jl

* * *

I submitted a PR to clarify the documentation on this point

> <https://github.com/SciML/Optimization.jl/pull/466>
>
> It's not obvious why the objective takes two arguments, since most (all?) other …optimization libraries use objective function that take a single argument only. This PR adds some more explanation under "Basic usage"
> 
> https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/6?u=baggepinnen

---

<div class="post-metadata">

**Author:** ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)\
**Post date:** [February 3, 2023, 4:30pm UTC](https://discourse.julialang.org/t/equivalent-circuit-optimization/93907/10 "2023-02-03T16:30:45Z")

</div>

Thanks for the advice, the error messag is gone, but the results are not yet promissing.

P.S.:  
What worked very fine to increase the result is a weighting functionality inside the quality function  
in the package [`EquivalentCircuits`](https://github.com/MaximeVH/EquivalentCircuits.jl):

```julia
function objectivefunction(circuitfunc,measurements,frequencies,weights=nothing) 
    if isnothing(weights) ; weights = ones(length(frequencies)) ; end
    function objective(x)
        model_output = [circuitfunc(x,fr) for fr in frequencies] 
        return mean(weights .* (abs.(measurements - model_output).^2)./(abs.(measurements).^2 .+ abs.(model_output).^2))
    end
    return objective
end

```
