# Thread: NEQNF over only some variables

1. ## NEQNF over only some variables

I want to solve a nonlinear system of equations F(x,y) = 0, where y is a fixed parameter and the solving happens only through manipulation of x.

As a simple example, let's say the equation is

2*x + y = 0

I want to solve for x while specifying various values of y.

It seems like NEQNF can do this if you pass it a function FCN whose output is 1-dimensional but pass a 2-dimensional output vector X and a 2-dimensional guess vector XGUESS which has as its second element the value for y. But am I guaranteed that NEQNF will not manipulate y in its final solution?

Below is Fortran code that solves the above equation for y = 4:

program test
use neqnf_int

real :: sols(2), guess(2), err

external fcn

guess(1) = 15.0
guess(2) = 4.0

call neqnf(fcn, sols, xguess = guess, fnorm = err)

print*, sols, err

end

subroutine fcn(x, f, n)

integer :: n
real :: x(2), f(1)

f(1) = 2*x(1) - x(2)
print*, x

end subroutine

The program's output, which shows the intermediate guesses on the way to the solution, is as follows:

15.00000000 4.000000000
15.00517941 4.000000000
15.00000000 4.001380920
2.001006126 4.000000000
2.000000000 4.000000000
2.000000000 4.000000000 0.0000000000E+00

Notice that it gets the answer right, but in the third iteration, it manipulates y! This makes me nervous that sometimes, I will get solutions that don't preserve the original value of y. Is there any way to guarantee that y will be untouched?  Reply With Quote

2. I think you mean 2-element initial guess vector XGUESS, it is not 2-dimensional. The function fcn is just the evaluating function, external to the subroutine. All it is doing is asking for evaluations along the function. This will also be used as part of the finite-difference approximation calculations it is making, so you should not infer that ever iteration is part of the steps to the actual solution. You can print out intermediate results from eval function, and this is often a good debugging technique, but the individual calls to the function should not be used to make determinations on where the solution process is at some point.  Reply With Quote

3. Whoops, I did mean 2-element, not 2-dimensional.

Thanks for pointing out that gradient evaluation is what generated the movement in the y variable. But are you additionally implying that y will never be manipulated in the final solution?

Here's a counterexample. Take the system

sin(x) - y = 0

Set y = 4, so that there is no x satisfying this equation. The output is below:

15.00000000 4.000000000
15.00517941 4.000000000
15.00000000 4.001380920
10.60075378 4.000000000
15.74079990 1.928875446
19.71863937 0.5000436306E-01
17.73172379 0.5000436306E-01
18.86583138 0.5000436306E-01
18.90431404 0.5000436306E-01
18.89958382 0.5000436306E-01
18.89958191 0.5000436306E-01
18.89958191 0.5000436306E-01 0.5775380174E-12

The final solution I get is x = 18.89958191 and y = 0.05000436306. Clearly, y has been manipulated. Granted, this is a pathological example. What I'd like to know, though, is whether NEQNF will always try its hardest to solve the system manipulating only x before resorting to manipulating y as well.

Another way to put it is, if I run NEQNF and find afterwards that y has been manipulated, is that a sure sign that NEQNF could not have found the solution in x even if y had been passed as a global variable? Originally Posted by pate
I think you mean 2-element initial guess vector XGUESS, it is not 2-dimensional. The function fcn is just the evaluating function, external to the subroutine. All it is doing is asking for evaluations along the function. This will also be used as part of the finite-difference approximation calculations it is making, so you should not infer that ever iteration is part of the steps to the actual solution. You can print out intermediate results from eval function, and this is often a good debugging technique, but the individual calls to the function should not be used to make determinations on where the solution process is at some point.  Reply With Quote

4. Originally Posted by bayes777
What I'd like to know, though, is whether NEQNF will always try its hardest to solve the system manipulating only x before resorting to manipulating y as well.

Another way to put it is, if I run NEQNF and find afterwards that y has been manipulated, is that a sure sign that NEQNF could not have found the solution in x even if y had been passed as a global variable?
I am front-end support engineer, so I am not sure I could make that statement, but maybe some developer here can that has worked on the source code. Let me see if I can get a more informed response.  Reply With Quote

5. This thread is now over a decade old, but has been left without a proper closure.

The problem posed by bayes777 is quite reasonable and commonly encountered. Given vector variables x and y, and a vector function F(x,y), one wishes to specify values for y and solve for x, when F and x have the same number of elements, and y has zero or more elements.

The attempts to use NEQNF after packing x and y into a single array, i.e., to define z = [x; y] and call NEQNF to solve F(z) = 0, are not going to work, for the following reason. NEQNF, when called with the F95 interface, assumes that z and F have as many elements, N, as there are coupled equations, and this assumption is not satisfied when the artifice of ignoring some elements of x is used. Secondly, the user-provided FCN routine will be called from NEQNF with different values of x, and FCN must compute N elements of F given N elements of x.

A simple way of solving the problem is to pass the parameter array y to FCN through means other than its argument list. Here, for example, is the example code from https://docs.roguewave.com/imsl/fort....10.10.html%23 , modified to use C(1), C(2) and C(3) in place of 27, 10 and 7 in FCN. The value of C is passed through a module that is USEd in the main program as well as in FCN. The main program sets the values into C, and these values are used in computing F(x,C).

Code:
```      module params
implicit none
real C(3)
end module

program xneqnf
USE NEQNF_INT
USE UMACH_INT
use params

IMPLICIT   NONE
!
INTEGER    N
PARAMETER  (N=3)
!
INTEGER    K, NOUT
REAL       FNORM, X(N), XGUESS(N)
EXTERNAL   FCN
!                                 Set values of initial guess
!                                 XGUESS = (  4.0  4.0  4.0 )
!
DATA XGUESS/4.0, 4.0, 4.0/
!
!
CALL UMACH (2, NOUT)
C = [27.0, 10.0, 7.0]                        ! original values
!                                 Find the solution
CALL NEQNF (FCN, X, xguess=xguess, fnorm=fnorm)
!                                 Output
WRITE (NOUT,99999) (X(K),K=1,N), FNORM
C = [27.0, 10.0, 8.0]                        ! C(3) is changed from 7 to 8
xguess = x
!                                 Find the solution
CALL NEQNF (FCN, X, xguess=xguess, fnorm=fnorm)
!                                 Output
WRITE (NOUT,99999) (X(K),K=1,N), FNORM

99999 FORMAT ('  The solution to the system is', /, '  X = (', 3F9.5, &
')', /, '  with FNORM =', es10.3, //)
!
END
!                                 User-defined subroutine
SUBROUTINE FCN (X, F, N)
use params
INTEGER    N
REAL       X(N), F(N)
!
REAL       EXP, SIN
INTRINSIC  EXP, SIN
!
F(1) = X(1) + EXP(X(1)-1.0) + (X(2)+X(3))*(X(2)+X(3)) - C(1)
F(2) = EXP(X(2)-2.0)/X(1) + X(3)*X(3) - C(2)
F(3) = X(3) + SIN(X(2)-2.0) + X(2)*X(2) - C(3)
RETURN
END```  Reply With Quote

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•