BoundsError when solving non linear system of equations

Hi

I’ve been trying to solve a non linear system of equations, but I have 4 equations and two variables so I guess the system is overdetermined and maybe that is the issue, but Mathematica doesn’t seem to have any issues with it. I was wondering if there was a way for Julia to solve this as well. Here is the code that I’m working with:

using Calculus
using LinearAlgebra
using SymPy
const l=1
const A=l/(2*pi)
const alpha=0.
const Phi=pi/2


a(x)= (-A*sin(x/A))*[0 1-alpha 0 0]-A*cos(x/A)*[0 0 1-alpha 2*sqrt(alpha)*(1-alpha)] + A*(-sin(3*x/A)/3)*[0 alpha 0 0] -A*(cos(3*x/A)/3)*[0 0 alpha 0] + [x 0 0 0]

b(x)=(A *sin(x/A))*[0 1 0 0]- 
 A*cos(x/A)*[0 0 cos(Phi) sin(Phi)] + [x 0 0 0]

apnew=lambdify(diff(a))
bpnew=lambdify(diff(b))

function testf!(testF,xtest2)
    testF[1]=(apnew(xtest2[1])-bpnew(xtest2[2]))[1]
    testF[2]=(apnew(xtest2[1])-bpnew(xtest2[2]))[2]
    testF[3]=(apnew(xtest2[1])-bpnew(xtest2[2]))[3]
    testF[4]=(apnew(xtest2[1])-bpnew(xtest2[2]))[4]
end

using NLsolve
nlsolve(testf!,[1.0;1.0])

This is returning the error

BoundsError: attempt to access 2-element Vector{Float64} at index [3]

Any help would be appreciated. TIA!

Welcome! As it is, we can’t run your code (which package does nlsolve! come from?), so please provide a minimal (non-) working example, as described here:

It’ll also be easier to help if you use triple backticks (```) to quote your code, since that has syntax highlighting an preserves indentation.

Hello!
Thanks for the reply, I’ve edited my code.

Thank you, but it seems there’s still something missing - I get this error when defining apnew:

julia> apnew=lambdify(diff(a))
ERROR: ArgumentError: ref of NULL PyObject
Stacktrace:
 [1] _getproperty
   @ ~/.julia/packages/PyCall/BD546/src/PyCall.jl:299 [inlined]
 [2] __getproperty(o::PyCall.PyObject, s::Symbol)
   @ PyCall ~/.julia/packages/PyCall/BD546/src/PyCall.jl:306
 [3] getproperty
   @ ~/.julia/packages/PyCall/BD546/src/PyCall.jl:312 [inlined]
 [4] symbols(x::String; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ SymPy ~/.julia/packages/SymPy/uawSQ/src/constructors.jl:16
 [5] symbols
   @ ~/.julia/packages/SymPy/uawSQ/src/constructors.jl:16 [inlined]
 [6] #symbols#16
   @ ~/.julia/packages/SymPy/uawSQ/src/constructors.jl:18 [inlined]
 [7] symbols
   @ ~/.julia/packages/SymPy/uawSQ/src/constructors.jl:18 [inlined]
 [8] diff(f::typeof(a), n::Int64) (repeats 2 times)
   @ SymPy ~/.julia/packages/SymPy/uawSQ/src/mathfuns.jl:63
 [9] top-level scope

Can you post the error you get in full? I suspect there’s some helpful information in there, like where the bounds error was thrown and what operation caused it exactly.

That’s weird. I’m not sure why you’re getting that error. Here is the BoundsError that I’m getting:

BoundsError: attempt to access 2-element Vector{Float64} at index [3]

Stacktrace:
  [1] setindex!(A::Vector{Float64}, x::Float64, i1::Int64)
    @ Base ./array.jl:839
  [2] testf!(testF::Vector{Float64}, xtest2::Vector{Float64})
    @ Main ./In[150]:4
  [3] (::NLSolversBase.var"#fj_finitediff!#21"{typeof(testf!), FiniteDiff.JacobianCache{Vector{Float64}, Vector{Float64}, Vector{Float64}, UnitRange{Int64}, Nothing, Val{:central}(), Float64}})(F::Vector{Float64}, J::Matrix{Float64}, x::Vector{Float64})
    @ NLSolversBase ~/.julia/packages/NLSolversBase/GRQ1x/src/objective_types/oncedifferentiable.jl:138
  [4] value_jacobian!!(obj::OnceDifferentiable{Vector{Float64}, Matrix{Float64}, Vector{Float64}}, F::Vector{Float64}, J::Matrix{Float64}, x::Vector{Float64})
    @ NLSolversBase ~/.julia/packages/NLSolversBase/GRQ1x/src/interface.jl:124
  [5] value_jacobian!!
    @ ~/.julia/packages/NLSolversBase/GRQ1x/src/interface.jl:122 [inlined]
  [6] trust_region_(df::OnceDifferentiable{Vector{Float64}, Matrix{Float64}, Vector{Float64}}, initial_x::Vector{Float64}, xtol::Float64, ftol::Float64, iterations::Int64, store_trace::Bool, show_trace::Bool, extended_trace::Bool, factor::Float64, autoscale::Bool, cache::NLsolve.NewtonTrustRegionCache{Vector{Float64}})
    @ NLsolve ~/.julia/packages/NLsolve/gJL1I/src/solvers/trust_region.jl:119
  [7] trust_region (repeats 2 times)
    @ ~/.julia/packages/NLsolve/gJL1I/src/solvers/trust_region.jl:235 [inlined]
  [8] nlsolve(df::OnceDifferentiable{Vector{Float64}, Matrix{Float64}, Vector{Float64}}, initial_x::Vector{Float64}; method::Symbol, xtol::Float64, ftol::Float64, iterations::Int64, store_trace::Bool, show_trace::Bool, extended_trace::Bool, linesearch::Static, linsolve::NLsolve.var"#27#29", factor::Float64, autoscale::Bool, m::Int64, beta::Int64, aa_start::Int64, droptol::Float64)
    @ NLsolve ~/.julia/packages/NLsolve/gJL1I/src/nlsolve/nlsolve.jl:26
  [9] nlsolve(f::Function, initial_x::Vector{Float64}; method::Symbol, autodiff::Symbol, inplace::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ NLsolve ~/.julia/packages/NLsolve/gJL1I/src/nlsolve/nlsolve.jl:52
 [10] nlsolve(f::Function, initial_x::Vector{Float64})
    @ NLsolve ~/.julia/packages/NLsolve/gJL1I/src/nlsolve/nlsolve.jl:46
 [11] top-level scope
    @ In[151]:1
 [12] eval
    @ ./boot.jl:360 [inlined]
 [13] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base ./loading.jl:1116

Seems like you get that BoundsError in line 4 of testf!, which would correspond to this:

testF[3]=(apnew(xtest2[1])-bpnew(xtest2[2]))[3]

Since nlsolve uses this function and presumably passes the original array you created into this function, I’d suggest using a larger array as a starting point, like this:

nlsolve(testf!, [1.0, 1.0, 1.0, 1.0])

I tried doing that, but it didn’t seem to converge. I’m expecting two zeros: (0,0.5) and (0.5,0).

Sounds like you have a nonlinear least squares problem and not a nonlinear system of equations.

A fast trip to Google found this

https://github.com/JuliaNLSolvers/LsqFit.jl

which seems to do something sensible.