Results 1 to 5 of 5

Thread: NEQNF over only some variables

  1. #1
    Junior Member
    Join Date
    Feb 2006
    Posts
    2

    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?

  2. #2
    Senior Member
    Join Date
    Sep 2005
    Posts
    105
    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.

  3. #3
    Junior Member
    Join Date
    Feb 2006
    Posts
    2
    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?

    Quote 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.

  4. #4
    Unregistered
    Guest
    Quote 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.

  5. #5
    Senior Member mecej4's Avatar
    Join Date
    Dec 2009
    Posts
    128
    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

Posting Permissions

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