# Minimizing a nonlinear user function

**URL:** <https://discourse.julialang.org/t/minimizing-a-nonlinear-user-function/124772>\
**Category:** Optimization (Mathematical)\
**Created:** [January 14, 2025, 6:17pm UTC](https://discourse.julialang.org/t/minimizing-a-nonlinear-user-function/124772 "2025-01-14T18:17:28Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [January 14, 2025, 6:17pm UTC](https://discourse.julialang.org/t/minimizing-a-nonlinear-user-function/124772/1 "2025-01-14T18:17:28Z")

</div>

I would like to know if and how the problem discussed [Here](https://discourse.julialang.org/t/looking-for-programmatic-solutions/124525/8) can be solved using JuMP’s “powerfull means”

This is the problem of day 24 of the advent of code 2024.

You are asked to “fix” a 45-bit full-adder that has 4 pairs of inverted gates.

The idea that I would like to implement (if possible) is the following.

The final and intermediate gates are in the variable Zk. I build a matrix Az (length(zk), length(zk)) by setting the diagonal (initial configuration) =1.

I define the functions that are needed to test the full-adder.  
I give as input a series of powers of two and return the square of the difference with respect to the exact result.  
I expect that in some way the optimizer changes configuration (i.e. modifies the matrix Az, appropriately exchanging pairs of gates) looking for the min of my f().  
Can it be done?  
How?

```julia
function parseinp()
    XY,Z=open("input_aoc24_d24.txt") do f 
        split(read(f, String), "\n\n")
    end
    XY=split.(split(XY, "\n"),": ")
    Z=split.(split(Z, "\n")," -> ")
    Z, XY
end

function mapkeyval(kz1,D,Z)
    prl(a,op,b)= op=="OR" ? a||b : op=="AND" ? a && b : xor(a, b)
    v=split.(first.(Z)," ")
    k=last.(Z)
    ikz=findfirst(==(kz1),k)
    l,op,r = v[ikz]
    if l in keys(D) && r in keys(D)
        D[kz1]=prl(D[l],op,D[r])
    elseif l in keys(D)
        ir=findfirst(==(r),k)
        D[kz1]=prl(D[l],op,mapkeyval(k[ir],D,Z))
    elseif r in keys(D)
        il=findfirst(==(l),k)
        D[kz1]=prl(mapkeyval(k[il],D,Z),op,D[r])
    else
        ir=findfirst(==(r),k)
        il=findfirst(==(l),k)
        D[kz1]=prl(mapkeyval(k[il],D,Z),op,mapkeyval(k[ir],D,Z))
    end
end

function swapz(Z,x,y)
    Z[x][2],Z[y][2]=Z[y][2],Z[x][2] 
end

function f(Az,Z,kz,kxy,kx,ky)
    for i in eachindex(Zk)
        for j in i:length(Zk)
            Az[Zk[i],Zk[j]]==1 && swapz(Z,i,j)
        end
    end
    mq=0
    for n in eachindex(kxy)
        D=Dict{String,Bool}()
        for key in kxy
            D[key]=false
        end
        for (i,d) in enumerate(digits(n, base=2))
            D[kx[i]]=d==1
            D[ky[i]]=d==1
        end
        mq+=(2n-reduce((s,c)->s*2+c, mapkeyval(j,D,Z) for j in kz ;init=0))^2
    end
    mq
end 

#########################

Z, XY=parseinp()
kz=sort(filter(e->startswith(e,"z"),Zk),rev=true)
kxy=first.(XY)
kx=[x for x in kxy if startswith(x,"x")]
ky=[x for x in kxy if startswith(x,"y")]

Zk=String.(last.(Z))
Az0=fill(false,length(Zk),length(Zk))
for i in eachindex(Zk)
    Az0[i,i] = true
end
d0=Dict{Tuple{String,String},Bool}()

for I in CartesianIndices(Az0)
    d0[(Zk[I[1]],Zk[I[2]])]=Az0[I[1],I[2]]
end

using JuMP

@variable(MFA, Az[i = Zk,j = Zk],Bin,start = d0[i,j])

@constraint(MFA, c[i=Zk], sum(Az[i,j] for j in Zk) == 1)

#objective(MFA, Min, f)

```

[here](https://adventofcode.com/2024/day/24) you can download the file to do some tests

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [January 14, 2025, 7:32pm UTC](https://discourse.julialang.org/t/minimizing-a-nonlinear-user-function/124772/2 "2025-01-14T19:32:25Z")

</div>

JuMP is not designed to optimize functions like this.

Take a read of [Should you use JuMP? · JuMP](https://jump.dev/JuMP.jl/stable/should_i_use/#When-should-you-not-use-JuMP)?
