LCOV - code coverage report
Current view: top level - shared/common/src/28_numeric_noabirule - m_slsqp.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 946 0
Test Date: 2026-11-10 14:34:30 Functions: 0.0 % 19 0
Branches: 0.0 % 562 0

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_slsqp
       2                 :             : !! NAME
       3                 :             : !! m_slsqp
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! This module contains the SLSQP optimization routine.
       7                 :             : !! This was taken from scipy.
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !! Copyright (c) 2001-2002 Enthought, Inc. 2003-2024, SciPy Developers.
      11                 :             : !! All rights reserved.
      12                 :             : !!
      13                 :             : !! Redistribution and use in source and binary forms, with or without
      14                 :             : !! modification, are permitted provided that the following conditions
      15                 :             : !! are met:
      16                 :             : !!
      17                 :             : !! 1. Redistributions of source code must retain the above copyright
      18                 :             : !!    notice, this list of conditions and the following disclaimer.
      19                 :             : !!
      20                 :             : !! 2. Redistributions in binary form must reproduce the above
      21                 :             : !!    copyright notice, this list of conditions and the following
      22                 :             : !!    disclaimer in the documentation and/or other materials provided
      23                 :             : !!    with the distribution.
      24                 :             : !!
      25                 :             : !! 3. Neither the name of the copyright holder nor the names of its
      26                 :             : !!    contributors may be used to endorse or promote products derived
      27                 :             : !!    from this software without specific prior written permission.
      28                 :             : !!
      29                 :             : !! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      30                 :             : !! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      31                 :             : !! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      32                 :             : !! A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      33                 :             : !! OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      34                 :             : !! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      35                 :             : !! LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      36                 :             : !! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      37                 :             : !! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      38                 :             : !! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      39                 :             : !! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      40                 :             : !!
      41                 :             : !! This file is distributed under the terms of the
      42                 :             : !! GNU General Public License, see ~abinit/COPYING
      43                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      44                 :             : !!
      45                 :             : !! SOURCE
      46                 :             : 
      47                 :             : #if defined HAVE_CONFIG_H
      48                 :             : #include "config.h"
      49                 :             : #endif
      50                 :             : 
      51                 :             : #include "abi_common.h"
      52                 :             : 
      53                 :             : MODULE m_slsqp
      54                 :             : 
      55                 :             :  implicit none
      56                 :             : 
      57                 :             :  private
      58                 :             : 
      59                 :             :  public :: slsqp
      60                 :             : 
      61                 :             : CONTAINS  !========================================================================================
      62                 :             : !!***
      63                 :             : 
      64                 :             : !C
      65                 :             : !C      ALGORITHM 733, COLLECTED ALGORITHMS FROM ACM.
      66                 :             : !C      TRANSACTIONS ON MATHEMATICAL SOFTWARE,
      67                 :             : !C      VOL. 20, NO. 3, SEPTEMBER, 1994, PP. 262-281.
      68                 :             : !C      https://doi.org/10.1145/192115.192124
      69                 :             : !C
      70                 :             : !C
      71                 :             : !C      https://web.archive.org/web/20170106155705/http://permalink.gmane.org/gmane.comp.python.scientific.devel/6725
      72                 :             : !C      ------
      73                 :             : !C      From: Deborah Cotton <cotton@hq.acm.org>
      74                 :             : !C      Date: Fri, 14 Sep 2007 12:35:55 -0500
      75                 :             : !C      Subject: RE: Algorithm License requested
      76                 :             : !C      To: Alan Isaac
      77                 :             : !C
      78                 :             : !C      Prof. Issac,
      79                 :             : !C
      80                 :             : !C      In that case, then because the author consents to [the ACM] releasing
      81                 :             : !C      the code currently archived at http://www.netlib.org/toms/733 under the
      82                 :             : !C      BSD license, the ACM hereby releases this code under the BSD license.
      83                 :             : !C
      84                 :             : !C      Regards,
      85                 :             : !C
      86                 :             : !C      Deborah Cotton, Copyright & Permissions
      87                 :             : !C      ACM Publications
      88                 :             : !C      2 Penn Plaza, Suite 701**
      89                 :             : !C      New York, NY 10121-0701
      90                 :             : !C      permissions@acm.org
      91                 :             : !C      212.869.7440 ext. 652
      92                 :             : !C      Fax. 212.869.0481
      93                 :             : !C      ------
      94                 :             : !C
      95                 :             : 
      96                 :             : !************************************************************************
      97                 :             : !*                              optimizer                               *
      98                 :             : !************************************************************************
      99                 :             : 
     100                 :           0 :       SUBROUTINE slsqp (m, meq, la, n, x, xl, xu, f, c, g, a,  &
     101                 :           0 :                        acc, iter, mode, w, l_w, jw, l_jw,  &
     102                 :             :                        alpha, f0, gs, h1, h2, h3, h4, t, t0, tol, &
     103                 :             :                        iexact, incons, ireset, itermx, line, &
     104                 :             :                        n1, n2, n3)
     105                 :             : 
     106                 :             : !C   SLSQP       S EQUENTIAL  L EAST  SQ UARES  P ROGRAMMING
     107                 :             : !C            TO SOLVE GENERAL NONLINEAR OPTIMIZATION PROBLEMS
     108                 :             : 
     109                 :             : !C***********************************************************************
     110                 :             : !C*                                                                     *
     111                 :             : !C*                                                                     *
     112                 :             : !C*            A NONLINEAR PROGRAMMING METHOD WITH                      *
     113                 :             : !C*            QUADRATIC  PROGRAMMING  SUBPROBLEMS                      *
     114                 :             : !C*                                                                     *
     115                 :             : !C*                                                                     *
     116                 :             : !C*  THIS SUBROUTINE SOLVES THE GENERAL NONLINEAR PROGRAMMING PROBLEM   *
     117                 :             : !C*                                                                     *
     118                 :             : !C*            MINIMIZE    F(X)                                         *
     119                 :             : !C*                                                                     *
     120                 :             : !C*            SUBJECT TO  C (X) .EQ. 0  ,  J = 1,...,MEQ               *
     121                 :             : !C*                         J                                           *
     122                 :             : !C*                                                                     *
     123                 :             : !C*                        C (X) .GE. 0  ,  J = MEQ+1,...,M             *
     124                 :             : !C*                         J                                           *
     125                 :             : !C*                                                                     *
     126                 :             : !C*                        XL .LE. X .LE. XU , I = 1,...,N.             *
     127                 :             : !C*                          I      I       I                           *
     128                 :             : !C*                                                                     *
     129                 :             : !C*  THE ALGORITHM IMPLEMENTS THE METHOD OF HAN AND POWELL              *
     130                 :             : !C*  WITH BFGS-UPDATE OF THE B-MATRIX AND L1-TEST FUNCTION              *
     131                 :             : !C*  WITHIN THE STEPLENGTH ALGORITHM.                                   *
     132                 :             : !C*                                                                     *
     133                 :             : !C*    PARAMETER DESCRIPTION:                                           *
     134                 :             : !C*    ( * MEANS THIS PARAMETER WILL BE CHANGED DURING CALCULATION )    *
     135                 :             : !C*                                                                     *
     136                 :             : !C*    M              IS THE TOTAL NUMBER OF CONSTRAINTS, M .GE. 0      *
     137                 :             : !C*    MEQ            IS THE NUMBER OF EQUALITY CONSTRAINTS, MEQ .GE. 0 *
     138                 :             : !C*    LA             SEE A, LA .GE. MAX(M,1)                           *
     139                 :             : !C*    N              IS THE NUMBER OF VARIBLES, N .GE. 1               *
     140                 :             : !C*  * X()            X() STORES THE CURRENT ITERATE OF THE N VECTOR X  *
     141                 :             : !C*                   ON ENTRY X() MUST BE INITIALIZED. ON EXIT X()     *
     142                 :             : !C*                   STORES THE SOLUTION VECTOR X IF MODE = 0.         *
     143                 :             : !C*    XL()           XL() STORES AN N VECTOR OF LOWER BOUNDS XL TO X.  *
     144                 :             : !C*                   ELEMENTS MAY BE NAN TO INDICATE NO LOWER BOUND.   *
     145                 :             : !C*    XU()           XU() STORES AN N VECTOR OF UPPER BOUNDS XU TO X.  *
     146                 :             : !C*                   ELEMENTS MAY BE NAN TO INDICATE NO UPPER BOUND.   *
     147                 :             : !C*    F              IS THE VALUE OF THE OBJECTIVE FUNCTION.           *
     148                 :             : !C*    C()            C() STORES THE M VECTOR C OF CONSTRAINTS,         *
     149                 :             : !C*                   EQUALITY CONSTRAINTS (IF ANY) FIRST.              *
     150                 :             : !C*                   DIMENSION OF C MUST BE GREATER OR EQUAL LA,       *
     151                 :             : !C*                   which must be GREATER OR EQUAL MAX(1,M).          *
     152                 :             : !C*    G()            G() STORES THE N VECTOR G OF PARTIALS OF THE      *
     153                 :             : !C*                   OBJECTIVE FUNCTION; DIMENSION OF G MUST BE        *
     154                 :             : !C*                   GREATER OR EQUAL N+1.                             *
     155                 :             : !C*    A(),LA,M,N     THE LA BY N + 1 ARRAY A() STORES                  *
     156                 :             : !C*                   THE M BY N MATRIX A OF CONSTRAINT NORMALS.        *
     157                 :             : !C*                   A() HAS FIRST DIMENSIONING PARAMETER LA,          *
     158                 :             : !C*                   WHICH MUST BE GREATER OR EQUAL MAX(1,M).          *
     159                 :             : !C*    F,C,G,A        MUST ALL BE SET BY THE USER BEFORE EACH CALL.     *
     160                 :             : !C*  * ACC            ABS(ACC) CONTROLS THE FINAL ACCURACY.             *
     161                 :             : !C*                   IF ACC .LT. ZERO AN EXACT LINESEARCH IS PERFORMED,*
     162                 :             : !C*                   OTHERWISE AN ARMIJO-TYPE LINESEARCH IS USED.      *
     163                 :             : !C*  * ITER           PRESCRIBES THE MAXIMUM NUMBER OF ITERATIONS.      *
     164                 :             : !C*                   ON EXIT ITER INDICATES THE NUMBER OF ITERATIONS.  *
     165                 :             : !C*  * MODE           MODE CONTROLS CALCULATION:                        *
     166                 :             : !C*                   REVERSE COMMUNICATION IS USED IN THE SENSE THAT   *
     167                 :             : !C*                   THE PROGRAM IS INITIALIZED BY MODE = 0; THEN IT IS*
     168                 :             : !C*                   TO BE CALLED REPEATEDLY BY THE USER UNTIL A RETURN*
     169                 :             : !C*                   WITH MODE .NE. IABS(1) TAKES PLACE.               *
     170                 :             : !C*                   IF MODE = -1 GRADIENTS HAVE TO BE CALCULATED,     *
     171                 :             : !C*                   WHILE WITH MODE = 1 FUNCTIONS HAVE TO BE CALCULATED
     172                 :             : !C*                   MODE MUST NOT BE CHANGED BETWEEN SUBSEQUENT CALLS *
     173                 :             : !C*                   OF SQP.                                           *
     174                 :             : !C*                   EVALUATION MODES:                                 *
     175                 :             : !C*        MODE = -1: GRADIENT EVALUATION, (G&A)                        *
     176                 :             : !C*                0: ON ENTRY: INITIALIZATION, (F,G,C&A)               *
     177                 :             : !C*                   ON EXIT : REQUIRED ACCURACY FOR SOLUTION OBTAINED *
     178                 :             : !C*                1: FUNCTION EVALUATION, (F&C)                        *
     179                 :             : !C*                                                                     *
     180                 :             : !C*                   FAILURE MODES:                                    *
     181                 :             : !C*                2: NUMBER OF EQUALITY CONSTRAINTS LARGER THAN N      *
     182                 :             : !C*                3: MORE THAN 3*N ITERATIONS IN LSQ SUBPROBLEM        *
     183                 :             : !C*                4: INEQUALITY CONSTRAINTS INCOMPATIBLE               *
     184                 :             : !C*                5: SINGULAR MATRIX E IN LSQ SUBPROBLEM               *
     185                 :             : !C*                6: SINGULAR MATRIX C IN LSQ SUBPROBLEM               *
     186                 :             : !C*                7: RANK-DEFICIENT EQUALITY CONSTRAINT SUBPROBLEM HFTI*
     187                 :             : !C*                8: POSITIVE DIRECTIONAL DERIVATIVE FOR LINESEARCH    *
     188                 :             : !C*                9: MORE THAN ITER ITERATIONS IN SQP                  *
     189                 :             : !C*             >=10: WORKING SPACE W OR JW TOO SMALL,                  *
     190                 :             : !C*                   W SHOULD BE ENLARGED TO L_W=MODE/1000             *
     191                 :             : !C*                   JW SHOULD BE ENLARGED TO L_JW=MODE-1000*L_W       *
     192                 :             : !C*  * W(), L_W       W() IS A ONE DIMENSIONAL WORKING SPACE,           *
     193                 :             : !C*                   THE LENGTH L_W OF WHICH SHOULD BE AT LEAST        *
     194                 :             : !C*                   (3*N1+M)*(N1+1)                        for LSQ    *
     195                 :             : !C*                  +(N1-MEQ+1)*(MINEQ+2) + 2*MINEQ         for LSI    *
     196                 :             : !C*                  +(N1+MINEQ)*(N1-MEQ) + 2*MEQ + N1       for LSEI   *
     197                 :             : !C*                  + N1*N/2 + 2*M + 3*N + 3*N1 + 1         for SLSQPB *
     198                 :             : !C*                   with MINEQ = M - MEQ + 2*N1  &  N1 = N+1          *
     199                 :             : !C*        NOTICE:    FOR PROPER DIMENSIONING OF W IT IS RECOMMENDED TO *
     200                 :             : !C*                   COPY THE FOLLOWING STATEMENTS INTO THE HEAD OF    *
     201                 :             : !C*                   THE CALLING PROGRAM (AND REMOVE THE COMMENT C)    *
     202                 :             : !c#######################################################################
     203                 :             : !C     INTEGER LEN_W, LEN_JW, M, N, N1, MEQ, MINEQ
     204                 :             : !C     PARAMETER (M=... , MEQ=... , N=...  )
     205                 :             : !C     PARAMETER (N1= N+1, MINEQ= M-MEQ+N1+N1)
     206                 :             : !C     PARAMETER (LEN_W=
     207                 :             : !c    $           (3*N1+M)*(N1+1)
     208                 :             : !c    $          +(N1-MEQ+1)*(MINEQ+2) + 2*MINEQ
     209                 :             : !c    $          +(N1+MINEQ)*(N1-MEQ) + 2*MEQ + N1
     210                 :             : !c    $          +(N+1)*N/2 + 2*M + 3*N + 3*N1 + 1,
     211                 :             : !c    $           LEN_JW=MINEQ)
     212                 :             : !C     DOUBLE PRECISION W(LEN_W)
     213                 :             : !C     INTEGER          JW(LEN_JW)
     214                 :             : !c#######################################################################
     215                 :             : !C*                   THE FIRST M+N+N*N1/2 ELEMENTS OF W MUST NOT BE    *
     216                 :             : !C*                   CHANGED BETWEEN SUBSEQUENT CALLS OF SLSQP.        *
     217                 :             : !C*                   ON RETURN W(1) ... W(M) CONTAIN THE MULTIPLIERS   *
     218                 :             : !C*                   ASSOCIATED WITH THE GENERAL CONSTRAINTS, WHILE    *
     219                 :             : !C*                   W(M+1) ... W(M+N(N+1)/2) STORE THE CHOLESKY FACTOR*
     220                 :             : !C*                   L*D*L(T) OF THE APPROXIMATE HESSIAN OF THE        *
     221                 :             : !C*                   LAGRANGIAN COLUMNWISE DENSE AS LOWER TRIANGULAR   *
     222                 :             : !C*                   UNIT MATRIX L WITH D IN ITS 'DIAGONAL' and        *
     223                 :             : !C*                   W(M+N(N+1)/2+N+2 ... W(M+N(N+1)/2+N+2+M+2N)       *
     224                 :             : !C*                   CONTAIN THE MULTIPLIERS ASSOCIATED WITH ALL       *
     225                 :             : !C*                   ALL CONSTRAINTS OF THE QUADRATIC PROGRAM FINDING  *
     226                 :             : !C*                   THE SEARCH DIRECTION TO THE SOLUTION X*           *
     227                 :             : !C*  * JW(), L_JW     JW() IS A ONE DIMENSIONAL INTEGER WORKING SPACE   *
     228                 :             : !C*                   THE LENGTH L_JW OF WHICH SHOULD BE AT LEAST       *
     229                 :             : !C*                   MINEQ                                             *
     230                 :             : !C*                   with MINEQ = M - MEQ + 2*N1  &  N1 = N+1          *
     231                 :             : !C*                                                                     *
     232                 :             : !C*  THE USER HAS TO PROVIDE THE FOLLOWING SUBROUTINES:                 *
     233                 :             : !C*     LDL(N,A,Z,SIG,W) :   UPDATE OF THE LDL'-FACTORIZATION.          *
     234                 :             : !C*     LINMIN(A,B,F,TOL) :  LINESEARCH ALGORITHM IF EXACT = 1          *
     235                 :             : !C*     LSQ(M,MEQ,LA,N,NC,C,D,A,B,XL,XU,X,LAMBDA,W,....) :              *
     236                 :             : !C*                                                                     *
     237                 :             : !C*        SOLUTION OF THE QUADRATIC PROGRAM                            *
     238                 :             : !C*                QPSOL IS RECOMMENDED:                                *
     239                 :             : !C*     PE GILL, W MURRAY, MA SAUNDERS, MH WRIGHT:                      *
     240                 :             : !C*     USER'S GUIDE FOR SOL/QPSOL:                                     *
     241                 :             : !C*     A FORTRAN PACKAGE FOR QUADRATIC PROGRAMMING,                    *
     242                 :             : !C*     TECHNICAL REPORT SOL 83-7, JULY 1983                            *
     243                 :             : !C*     DEPARTMENT OF OPERATIONS RESEARCH, STANFORD UNIVERSITY          *
     244                 :             : !C*     STANFORD, CA 94305                                              *
     245                 :             : !C*     QPSOL IS THE MOST ROBUST AND EFFICIENT QP-SOLVER                *
     246                 :             : !C*     AS IT ALLOWS WARM STARTS WITH PROPER WORKING SETS               *
     247                 :             : !C*                                                                     *
     248                 :             : !C*     IF IT IS NOT AVAILABLE USE LSEI, A CONSTRAINT LINEAR LEAST      *
     249                 :             : !C*     SQUARES SOLVER IMPLEMENTED USING THE SOFTWARE HFTI, LDP, NNLS   *
     250                 :             : !C*     FROM C.L. LAWSON, R.J.HANSON: SOLVING LEAST SQUARES PROBLEMS,   *
     251                 :             : !C*     PRENTICE HALL, ENGLEWOOD CLIFFS, 1974.                          *
     252                 :             : !C*     LSEI COMES WITH THIS PACKAGE, together with all necessary SR's. *
     253                 :             : !C*                                                                     *
     254                 :             : !C*     TOGETHER WITH A COUPLE OF SUBROUTINES FROM BLAS LEVEL 1         *
     255                 :             : !C*                                                                     *
     256                 :             : !C*     SQP IS HEAD SUBROUTINE FOR BODY SUBROUTINE SQPBDY               *
     257                 :             : !C*     IN WHICH THE ALGORITHM HAS BEEN IMPLEMENTED.                    *
     258                 :             : !C*                                                                     *
     259                 :             : !C*  IMPLEMENTED BY: DIETER KRAFT, DFVLR OBERPFAFFENHOFEN               *
     260                 :             : !C*  as described in Dieter Kraft: A Software Package for               *
     261                 :             : !C*                                Sequential Quadratic Programming     *
     262                 :             : !C*                                DFVLR-FB 88-28, 1988                 *
     263                 :             : !C*  which should be referenced if the user publishes results of SLSQP  *
     264                 :             : !C*                                                                     *
     265                 :             : !C*  DATE:           APRIL - OCTOBER, 1981.                             *
     266                 :             : !C*  STATUS:         DECEMBER, 31-ST, 1984.                             *
     267                 :             : !C*  STATUS:         MARCH   , 21-ST, 1987, REVISED TO FORTRAN 77       *
     268                 :             : !C*  STATUS:         MARCH   , 20-th, 1989, REVISED TO MS-FORTRAN       *
     269                 :             : !C*  STATUS:         APRIL   , 14-th, 1989, HESSE   in-line coded       *
     270                 :             : !C*  STATUS:         FEBRUARY, 28-th, 1991, FORTRAN/2 Version 1.04      *
     271                 :             : !C*                                         accepts Statement Functions *
     272                 :             : !C*  STATUS:         MARCH   ,  1-st, 1991, tested with SALFORD         *
     273                 :             : !C*                                         FTN77/386 COMPILER VERS 2.40*
     274                 :             : !C*                                         in protected mode           *
     275                 :             : !C*                                                                     *
     276                 :             : !C***********************************************************************
     277                 :             : !C*                                                                     *
     278                 :             : !C*  Copyright 1991: Dieter Kraft, FHM                                  *
     279                 :             : !C*                                                                     *
     280                 :             : !C***********************************************************************
     281                 :             : 
     282                 :             :       INTEGER          il, im, ir, is, iter, iu, iv, iw, ix, l_w, l_jw, &
     283                 :             :                        jw(l_jw), la, m, meq, mineq, mode, n
     284                 :             : 
     285                 :             :       DOUBLE PRECISION acc, a(la,n+1), c(la), f, g(n+1), &
     286                 :             :                        x(n), xl(n), xu(n), w(l_w)
     287                 :             : 
     288                 :             :       INTEGER          iexact, incons, ireset, itermx, line, n1, n2, n3
     289                 :             : 
     290                 :             :       DOUBLE PRECISION alpha, f0, gs, h1, h2, h3, h4, t, t0, tol
     291                 :             : 
     292                 :             : !c     dim(W) =         N1*(N1+1) + MEQ*(N1+1) + MINEQ*(N1+1)  for LSQ
     293                 :             : !c                    +(N1-MEQ+1)*(MINEQ+2) + 2*MINEQ          for LSI
     294                 :             : !c                    +(N1+MINEQ)*(N1-MEQ) + 2*MEQ + N1        for LSEI
     295                 :             : !c                    + N1*N/2 + 2*M + 3*N +3*N1 + 1           for SLSQPB
     296                 :             : !c                      with MINEQ = M - MEQ + 2*N1  &  N1 = N+1
     297                 :             : 
     298                 :             : !C   CHECK LENGTH OF WORKING ARRAYS
     299                 :             : 
     300                 :           0 :       n1 = n+1
     301                 :           0 :       mineq = m-meq+n1+n1
     302                 :             :       il = (3*n1+m)*(n1+1) +  &
     303                 :             :       (n1-meq+1)*(mineq+2) + 2*mineq + &
     304                 :             :       (n1+mineq)*(n1-meq)  + 2*meq +  &
     305                 :           0 :       n1*n/2 + 2*m + 3*n + 4*n1 + 1
     306                 :           0 :       im = MAX(mineq, n1-meq)
     307   [ #  #  #  # ]:           0 :       IF (l_w .LT. il .OR. l_jw .LT. im) THEN
     308                 :           0 :           mode = 1000*MAX(10,il)
     309                 :           0 :           mode = mode+MAX(10,im)
     310                 :           0 :           RETURN
     311                 :             :       ENDIF
     312                 :             : 
     313                 :             : !C   PREPARE DATA FOR CALLING SQPBDY  -  INITIAL ADDRESSES IN W
     314                 :             : 
     315                 :           0 :       im = 1
     316                 :           0 :       il = im + MAX(1,m)
     317                 :           0 :       il = im + la
     318                 :           0 :       ix = il + n1*n/2 + 1
     319                 :           0 :       ir = ix + n
     320                 :           0 :       is = ir + n + n + MAX(1,m)
     321                 :           0 :       is = ir + n + n + la
     322                 :           0 :       iu = is + n1
     323                 :           0 :       iv = iu + n1
     324                 :           0 :       iw = iv + n1
     325                 :             : 
     326                 :             :       CALL slsqpb  (m, meq, la, n, x, xl, xu, f, c, g, a, acc, iter,  &
     327                 :             :        mode, w(ir), w(il), w(ix), w(im), w(is), w(iu), w(iv), w(iw), jw, &
     328                 :             :        alpha, f0, gs, h1, h2, h3, h4, t, t0, tol, &
     329                 :             :        iexact, incons, ireset, itermx, line, &
     330                 :           0 :        n1, n2, n3)
     331                 :             : 
     332                 :             :       END SUBROUTINE slsqp
     333                 :             : 
     334                 :           0 :       SUBROUTINE slsqpb (m, meq, la, n, x, xl, xu, f, c, g, a, acc,  &
     335                 :           0 :                          iter, mode, r, l, x0, mu, s, u, v, w, iw, &
     336                 :             :                          alpha, f0, gs, h1, h2, h3, h4, t, t0, tol, &
     337                 :             :                          iexact, incons, ireset, itermx, line, &
     338                 :             :                          n1, n2, n3)
     339                 :             : 
     340                 :             : !C   NONLINEAR PROGRAMMING BY SOLVING SEQUENTIALLY QUADRATIC PROGRAMS
     341                 :             : 
     342                 :             : !C        -  L1 - LINE SEARCH,  POSITIVE DEFINITE  BFGS UPDATE  -
     343                 :             : 
     344                 :             : !C                      BODY SUBROUTINE FOR SLSQP
     345                 :             : 
     346                 :             :       INTEGER          iw(*), i, iexact, incons, ireset, iter, itermx, &
     347                 :             :                        k, j, la, line, m, meq, mode, n, n1, n2, n3
     348                 :             :       LOGICAL          badlin
     349                 :             : 
     350                 :             :       DOUBLE PRECISION a(la,n+1), c(la), g(n+1), l((n+1)*(n+2)/2), &
     351                 :             :                        mu(la), r(m+n+n+2), s(n+1), u(n+1), v(n+1), w(*), &
     352                 :             :                        x(n), xl(n), xu(n), x0(n), &
     353                 :             :                        acc, alfmin, alpha, f, f0, gs, h1, h2, h3, h4, &
     354                 :             :                        hun, one, t, t0, ten, tol, two, ZERO
     355                 :             : 
     356                 :             : !c     dim(W) =         N1*(N1+1) + MEQ*(N1+1) + MINEQ*(N1+1)  for LSQ
     357                 :             : !c                     +(N1-MEQ+1)*(MINEQ+2) + 2*MINEQ
     358                 :             : !c                     +(N1+MINEQ)*(N1-MEQ) + 2*MEQ + N1       for LSEI
     359                 :             : !c                      with MINEQ = M - MEQ + 2*N1  &  N1 = N+1
     360                 :             : 
     361                 :             :       DATA             ZERO /0.0d0/, one /1.0d0/, alfmin /1.0d-1/, &
     362                 :             :                        hun /1.0d+2/, ten /1.0d+1/, two /2.0d0/
     363                 :             : 
     364                 :             : !C     The badlin flag keeps track whether the SQP problem on the current
     365                 :             : !C     iteration was inconsistent or not.
     366                 :           0 :       badlin = .false.
     367                 :             : 
     368         [ #  # ]:           0 :       IF (mode.LT.0) GO TO 260
     369         [ #  # ]:           0 :       IF (mode.EQ.0) GO TO 100
     370                 :             :       IF (mode.GT.0) GO TO 220
     371                 :             : 
     372                 :           0 :   100 itermx = iter
     373         [ #  # ]:           0 :       IF (acc.GE.ZERO) THEN
     374                 :           0 :           iexact = 0
     375                 :             :       ELSE
     376                 :           0 :           iexact = 1
     377                 :             :       ENDIF
     378                 :           0 :       acc = ABS(acc)
     379                 :           0 :       tol = ten*acc
     380                 :           0 :       iter = 0
     381                 :           0 :       ireset = 0
     382                 :           0 :       n1 = n + 1
     383                 :           0 :       n2 = n1*n/2
     384                 :           0 :       n3 = n2 + 1
     385                 :           0 :       s(1) = ZERO
     386                 :           0 :       mu(1) = ZERO
     387                 :           0 :       CALL dcopy_(n, s(1),  0, s,  1)
     388                 :           0 :       CALL dcopy_(m, mu(1), 0, mu, 1)
     389                 :             : 
     390                 :             : !C   RESET BFGS MATRIX
     391                 :             : 
     392                 :           0 :   110 ireset = ireset + 1
     393         [ #  # ]:           0 :       IF (ireset.GT.5) GO TO 255
     394                 :           0 :       l(1) = ZERO
     395                 :           0 :       CALL dcopy_(n2, l(1), 0, l, 1)
     396                 :           0 :       j = 1
     397         [ #  # ]:           0 :       DO 120 i=1,n
     398                 :           0 :          l(j) = one
     399                 :           0 :          j = j + n1 - i
     400                 :           0 :   120 CONTINUE
     401                 :             : 
     402                 :             : !C   MAIN ITERATION : SEARCH DIRECTION, STEPLENGTH, LDL'-UPDATE
     403                 :             : 
     404                 :           0 :   130 iter = iter + 1
     405                 :           0 :       mode = 9
     406         [ #  # ]:           0 :       IF (iter.GT.itermx) GO TO 330
     407                 :             : 
     408                 :             : !C   SEARCH DIRECTION AS SOLUTION OF QP - SUBPROBLEM
     409                 :             : 
     410                 :           0 :       CALL dcopy_(n, xl, 1, u, 1)
     411                 :           0 :       CALL dcopy_(n, xu, 1, v, 1)
     412                 :           0 :       CALL daxpy_sl(n, -one, x, 1, u, 1)
     413                 :           0 :       CALL daxpy_sl(n, -one, x, 1, v, 1)
     414                 :           0 :       h4 = one
     415                 :           0 :       CALL lsq (m, meq, n , n3, la, l, g, a, c, u, v, s, r, w, iw, mode)
     416                 :             : 
     417                 :             : !C   AUGMENTED PROBLEM FOR INCONSISTENT LINEARIZATION
     418                 :             : !C
     419                 :             : !C   If it turns out that the original SQP problem is inconsistent,
     420                 :             : !C   disallow termination with convergence on this iteration,
     421                 :             : !C   even if the augmented problem was solved.
     422                 :             : 
     423                 :           0 :       badlin = .false.
     424         [ #  # ]:           0 :       IF (mode.EQ.6) THEN
     425         [ #  # ]:           0 :           IF (n.EQ.meq) THEN
     426                 :           0 :               mode = 4
     427                 :             :           ENDIF
     428                 :             :       ENDIF
     429         [ #  # ]:           0 :       IF (mode.EQ.4) THEN
     430                 :           0 :           badlin = .true.
     431         [ #  # ]:           0 :           DO 140 j=1,m
     432         [ #  # ]:           0 :              IF (j.LE.meq) THEN
     433                 :           0 :                  a(j,n1) = -c(j)
     434                 :             :              ELSE
     435                 :           0 :                  a(j,n1) = MAX(-c(j),ZERO)
     436                 :             :              ENDIF
     437                 :           0 :   140     CONTINUE
     438                 :           0 :           s(1) = ZERO
     439                 :           0 :           CALL dcopy_(n, s(1), 0, s, 1)
     440                 :           0 :           h3 = ZERO
     441                 :           0 :           g(n1) = ZERO
     442                 :           0 :           l(n3) = hun
     443                 :           0 :           s(n1) = one
     444                 :           0 :           u(n1) = ZERO
     445                 :           0 :           v(n1) = one
     446                 :           0 :           incons = 0
     447                 :             :   150     CALL lsq (m, meq, n1, n3, la, l, g, a, c, u, v, s, r, &
     448                 :           0 :                     w, iw, mode)
     449                 :           0 :           h4 = one - s(n1)
     450         [ #  # ]:           0 :           IF (mode.EQ.4) THEN
     451                 :           0 :               l(n3) = ten*l(n3)
     452                 :           0 :               incons = incons + 1
     453         [ #  # ]:           0 :               IF (incons.GT.5) GO TO 330
     454                 :             :               GOTO 150
     455         [ #  # ]:           0 :           ELSE IF (mode.NE.1) THEN
     456                 :             :               GOTO 330
     457                 :             :           ENDIF
     458         [ #  # ]:           0 :       ELSE IF (mode.NE.1) THEN
     459                 :             :           GOTO 330
     460                 :             :       ENDIF
     461                 :             : 
     462                 :             : !C   UPDATE MULTIPLIERS FOR L1-TEST
     463                 :             : 
     464         [ #  # ]:           0 :       DO 160 i=1,n
     465                 :           0 :          v(i) = g(i) - ddot_sl(m,a(1,i),1,r,1)
     466                 :           0 :   160 CONTINUE
     467                 :           0 :       f0 = f
     468                 :           0 :       CALL dcopy_(n, x, 1, x0, 1)
     469                 :           0 :       gs = ddot_sl(n, g, 1, s, 1)
     470                 :           0 :       h1 = ABS(gs)
     471                 :           0 :       h2 = ZERO
     472         [ #  # ]:           0 :       DO 170 j=1,m
     473         [ #  # ]:           0 :          IF (j.LE.meq) THEN
     474                 :           0 :              h3 = c(j)
     475                 :             :          ELSE
     476                 :           0 :              h3 = ZERO
     477                 :             :          ENDIF
     478                 :           0 :          h2 = h2 + MAX(-c(j),h3)
     479                 :           0 :          h3 = ABS(r(j))
     480                 :           0 :          mu(j) = MAX(h3,(mu(j)+h3)/two)
     481                 :           0 :          h1 = h1 + h3*ABS(c(j))
     482                 :           0 :   170 CONTINUE
     483                 :             : 
     484                 :             : !C   CHECK CONVERGENCE
     485                 :             : 
     486                 :           0 :       mode = 0
     487                 :             :       IF (h1.LT.acc .AND. h2.LT.acc .AND. .NOT. badlin  &
     488   [ #  #  #  #  :           0 :            .AND. f .EQ. f) GO TO 330
             #  #  #  # ]
     489                 :           0 :       h1 = ZERO
     490         [ #  # ]:           0 :       DO 180 j=1,m
     491         [ #  # ]:           0 :          IF (j.LE.meq) THEN
     492                 :           0 :              h3 = c(j)
     493                 :             :          ELSE
     494                 :           0 :              h3 = ZERO
     495                 :             :          ENDIF
     496                 :           0 :          h1 = h1 + mu(j)*MAX(-c(j),h3)
     497                 :           0 :   180 CONTINUE
     498                 :           0 :       t0 = f + h1
     499                 :           0 :       h3 = gs - h1*h4
     500                 :           0 :       mode = 8
     501         [ #  # ]:           0 :       IF (h3.GE.ZERO) GO TO 110
     502                 :             : 
     503                 :             : !C   LINE SEARCH WITH AN L1-TESTFUNCTION
     504                 :             : 
     505                 :           0 :       line = 0
     506                 :           0 :       alpha = one
     507         [ #  # ]:           0 :       IF (iexact.EQ.1) GOTO 210
     508                 :             : 
     509                 :             : !C   INEXACT LINESEARCH
     510                 :             : 
     511                 :           0 :   190     line = line + 1
     512                 :           0 :           h3 = alpha*h3
     513                 :           0 :           CALL dscal_sl(n, alpha, s, 1)
     514                 :           0 :           CALL dcopy_(n, x0, 1, x, 1)
     515                 :           0 :           CALL daxpy_sl(n, one, s, 1, x, 1)
     516                 :           0 :           mode = 1
     517                 :           0 :           GO TO 330
     518   [ #  #  #  # ]:           0 :   200         IF (h1.LE.h3/ten .OR. line.GT.10) GO TO 240
     519                 :           0 :               alpha = MAX(h3/(two*(h3-h1)),alfmin)
     520                 :           0 :               GO TO 190
     521                 :             : 
     522                 :             : !C   EXACT LINESEARCH
     523                 :             : 
     524         [ #  # ]:           0 :   210 IF (line.NE.3) THEN
     525                 :           0 :           alpha = linmin(line,alfmin,one,t,tol)
     526                 :           0 :           CALL dcopy_(n, x0, 1, x, 1)
     527                 :           0 :           CALL daxpy_sl(n, alpha, s, 1, x, 1)
     528                 :           0 :           mode = 1
     529                 :           0 :           GOTO 330
     530                 :             :       ENDIF
     531                 :           0 :       CALL dscal_sl(n, alpha, s, 1)
     532                 :           0 :       GOTO 240
     533                 :             : 
     534                 :             : !C   CALL FUNCTIONS AT CURRENT X
     535                 :             : 
     536                 :           0 :   220     t = f
     537         [ #  # ]:           0 :           DO 230 j=1,m
     538         [ #  # ]:           0 :              IF (j.LE.meq) THEN
     539                 :           0 :                  h1 = c(j)
     540                 :             :              ELSE
     541                 :           0 :                  h1 = ZERO
     542                 :             :              ENDIF
     543                 :           0 :              t = t + mu(j)*MAX(-c(j),h1)
     544                 :           0 :   230     CONTINUE
     545                 :           0 :           h1 = t - t0
     546      [ #  #  # ]:           0 :           GOTO (200, 210) iexact+1
     547                 :             : 
     548                 :             : !C   CHECK CONVERGENCE
     549                 :             : 
     550                 :           0 :   240 h3 = ZERO
     551         [ #  # ]:           0 :       DO 250 j=1,m
     552         [ #  # ]:           0 :          IF (j.LE.meq) THEN
     553                 :           0 :              h1 = c(j)
     554                 :             :          ELSE
     555                 :           0 :              h1 = ZERO
     556                 :             :          ENDIF
     557                 :           0 :          h3 = h3 + MAX(-c(j),h1)
     558                 :           0 :   250 CONTINUE
     559                 :             :       IF ((ABS(f-f0).LT.acc .OR. dnrm2_(n,s,1).LT.acc) .AND. h3.LT.acc  &
     560   [ #  #  #  #  :           0 :            .AND. .NOT. badlin .AND. f .EQ. f) &
          #  #  #  #  #  
                      # ]
     561                 :             :          THEN
     562                 :           0 :             mode = 0
     563                 :             :          ELSE
     564                 :           0 :             mode = -1
     565                 :             :          ENDIF
     566                 :           0 :       GO TO 330
     567                 :             : 
     568                 :             : !C   CHECK relaxed CONVERGENCE in case of positive directional derivative
     569                 :             : 
     570                 :             :   255 CONTINUE
     571                 :           0 :       h3 = ZERO
     572         [ #  # ]:           0 :       DO 256 j=1,m
     573         [ #  # ]:           0 :          IF (j.LE.meq) THEN
     574                 :           0 :              h1 = c(j)
     575                 :             :          ELSE
     576                 :           0 :              h1 = ZERO
     577                 :             :          ENDIF
     578                 :           0 :          h3 = h3 + MAX(-c(j),h1)
     579                 :           0 :   256 CONTINUE
     580                 :             :       IF ((ABS(f-f0).LT.tol .OR. dnrm2_(n,s,1).LT.tol) .AND. h3.LT.tol  &
     581   [ #  #  #  #  :           0 :            .AND. .NOT. badlin .AND. f .EQ. f) &
          #  #  #  #  #  
                      # ]
     582                 :             :          THEN
     583                 :           0 :             mode = 0
     584                 :             :          ELSE
     585                 :           0 :             mode = 8
     586                 :             :          ENDIF
     587                 :           0 :       GO TO 330
     588                 :             : 
     589                 :             : !C   CALL JACOBIAN AT CURRENT X
     590                 :             : 
     591                 :             : !C   UPDATE CHOLESKY-FACTORS OF HESSIAN MATRIX BY MODIFIED BFGS FORMULA
     592                 :             : 
     593         [ #  # ]:           0 :   260 DO 270 i=1,n
     594                 :           0 :          u(i) = g(i) - ddot_sl(m,a(1,i),1,r,1) - v(i)
     595                 :           0 :   270 CONTINUE
     596                 :             : 
     597                 :             : !C   L'*S
     598                 :             : 
     599                 :             :       k = 0
     600         [ #  # ]:           0 :       DO 290 i=1,n
     601                 :           0 :          h1 = ZERO
     602                 :           0 :          k = k + 1
     603         [ #  # ]:           0 :          DO 280 j=i+1,n
     604                 :           0 :             k = k + 1
     605                 :           0 :             h1 = h1 + l(k)*s(j)
     606                 :           0 :   280    CONTINUE
     607                 :           0 :          v(i) = s(i) + h1
     608                 :           0 :   290 CONTINUE
     609                 :             : 
     610                 :             : !C   D*L'*S
     611                 :             : 
     612                 :             :       k = 1
     613         [ #  # ]:           0 :       DO 300 i=1,n
     614                 :           0 :          v(i) = l(k)*v(i)
     615                 :           0 :          k = k + n1 - i
     616                 :           0 :   300 CONTINUE
     617                 :             : 
     618                 :             : !C   L*D*L'*S
     619                 :             : 
     620         [ #  # ]:           0 :       DO 320 i=n,1,-1
     621                 :           0 :          h1 = ZERO
     622                 :           0 :          k = i
     623         [ #  # ]:           0 :          DO 310 j=1,i - 1
     624                 :           0 :             h1 = h1 + l(k)*v(j)
     625                 :           0 :             k = k + n - j
     626                 :           0 :   310    CONTINUE
     627                 :           0 :          v(i) = v(i) + h1
     628                 :           0 :   320 CONTINUE
     629                 :             : 
     630                 :           0 :       h1 = ddot_sl(n,s,1,u,1)
     631                 :           0 :       h2 = ddot_sl(n,s,1,v,1)
     632                 :           0 :       h3 = 0.2d0*h2
     633         [ #  # ]:           0 :       IF (h1.LT.h3) THEN
     634                 :           0 :           h4 = (h2-h3)/(h2-h1)
     635                 :           0 :           h1 = h3
     636                 :           0 :           CALL dscal_sl(n, h4, u, 1)
     637                 :           0 :           CALL daxpy_sl(n, one-h4, v, 1, u, 1)
     638                 :             :       ENDIF
     639   [ #  #  #  # ]:           0 :       IF (h1.EQ.0 .or. h2.EQ.0) THEN
     640                 :             : !C         Singular update: reset hessian.
     641                 :             :           GO TO 110
     642                 :             :       end if
     643                 :           0 :       CALL ldl(n, l, u, +one/h1, v)
     644                 :           0 :       CALL ldl(n, l, v, -one/h2, u)
     645                 :             : 
     646                 :             : !C   END OF MAIN ITERATION
     647                 :             : 
     648                 :           0 :       GO TO 130
     649                 :             : 
     650                 :             : !C   END OF SLSQPB
     651                 :             : 
     652                 :             :   330 continue
     653                 :           0 :       END SUBROUTINE slsqpb
     654                 :             : 
     655                 :             : 
     656                 :           0 :       SUBROUTINE lsq(m,meq,n,nl,la,l,g,a,b,xl,xu,x,y,w,jw,mode)
     657                 :             : 
     658                 :             : !C   MINIMIZE with respect to X
     659                 :             : 
     660                 :             : !C             ||E*X - F||
     661                 :             : !C                                      1/2  T
     662                 :             : !C   WITH UPPER TRIANGULAR MATRIX E = +D   *L ,
     663                 :             : 
     664                 :             : !C                                      -1/2  -1
     665                 :             : !C                     AND VECTOR F = -D    *L  *G,
     666                 :             : 
     667                 :             : !C  WHERE THE UNIT LOWER TRIDIANGULAR MATRIX L IS STORED COLUMNWISE
     668                 :             : !C  DENSE IN THE N*(N+1)/2 ARRAY L WITH VECTOR D STORED IN ITS
     669                 :             : !C 'DIAGONAL' THUS SUBSTITUTING THE ONE-ELEMENTS OF L
     670                 :             : 
     671                 :             : !C   SUBJECT TO
     672                 :             : 
     673                 :             : !C             A(J)*X - B(J) = 0 ,         J=1,...,MEQ,
     674                 :             : !C             A(J)*X - B(J) >=0,          J=MEQ+1,...,M,
     675                 :             : !C             XL(I) <= X(I) <= XU(I),     I=1,...,N,
     676                 :             : !C     ON ENTRY, THE USER HAS TO PROVIDE THE ARRAYS L, G, A, B, XL, XU.
     677                 :             : !C     WITH DIMENSIONS: L(N*(N+1)/2), G(N), A(LA,N), B(M), XL(N), XU(N)
     678                 :             : !C     THE WORKING ARRAY W MUST HAVE AT LEAST THE FOLLOWING DIMENSION:
     679                 :             : !c     DIM(W) =        (3*N+M)*(N+1)                        for LSQ
     680                 :             : !c                    +(N-MEQ+1)*(MINEQ+2) + 2*MINEQ        for LSI
     681                 :             : !c                    +(N+MINEQ)*(N-MEQ) + 2*MEQ + N        for LSEI
     682                 :             : !c                      with MINEQ = M - MEQ + 2*N
     683                 :             : !C     ON RETURN, NO ARRAY WILL BE CHANGED BY THE SUBROUTINE.
     684                 :             : !C     X     STORES THE N-DIMENSIONAL SOLUTION VECTOR
     685                 :             : !C     Y     STORES THE VECTOR OF LAGRANGE MULTIPLIERS OF DIMENSION
     686                 :             : !C           M+N+N (CONSTRAINTS+LOWER+UPPER BOUNDS)
     687                 :             : !C     MODE  IS A SUCCESS-FAILURE FLAG WITH THE FOLLOWING MEANINGS:
     688                 :             : !C          MODE=1: SUCCESSFUL COMPUTATION
     689                 :             : !C               2: ERROR RETURN BECAUSE OF WRONG DIMENSIONS (N<1)
     690                 :             : !C               3: ITERATION COUNT EXCEEDED BY NNLS
     691                 :             : !C               4: INEQUALITY CONSTRAINTS INCOMPATIBLE
     692                 :             : !C               5: MATRIX E IS NOT OF FULL RANK
     693                 :             : !C               6: MATRIX C IS NOT OF FULL RANK
     694                 :             : !C               7: RANK DEFECT IN HFTI
     695                 :             : 
     696                 :             : !c     coded            Dieter Kraft, april 1987
     697                 :             : !c     revised                        march 1989
     698                 :             : 
     699                 :             :       DOUBLE PRECISION l,g,a,b,w,xl,xu,x,y, &
     700                 :             :                        diag,ZERO,one,xnorm
     701                 :             : 
     702                 :             :       INTEGER          jw(*),i,ic,id,ie,IF,ig,ih,il,ip,iw,&
     703                 :             :            i1,i2,i3,i4,la,m,meq,mineq,mode,m1,n,nl,n1,n2,n3,&
     704                 :             :            nancnt,j
     705                 :             : 
     706                 :             :       DIMENSION        a(la,n), b(la), g(n), l(nl),&
     707                 :             :                        w(*), x(n), xl(n), xu(n), y(m+n+n)
     708                 :             : 
     709                 :             :       DATA             ZERO/0.0d0/, one/1.0d0/
     710                 :             : 
     711                 :           0 :       n1 = n + 1
     712                 :           0 :       mineq = m - meq
     713                 :           0 :       m1 = mineq + n + n
     714                 :             : 
     715                 :             : !c  determine whether to solve problem
     716                 :             : !c  with inconsistent linerarization (n2=1)
     717                 :             : !c  or not (n2=0)
     718                 :             : 
     719                 :           0 :       n2 = n1*n/2 + 1
     720         [ #  # ]:           0 :       IF (n2.EQ.nl) THEN
     721                 :             :           n2 = 0
     722                 :             :       ELSE
     723                 :           0 :           n2 = 1
     724                 :             :       ENDIF
     725                 :           0 :       n3 = n-n2
     726                 :             : 
     727                 :             : !C  RECOVER MATRIX E AND VECTOR F FROM L AND G
     728                 :             : 
     729                 :           0 :       i2 = 1
     730                 :           0 :       i3 = 1
     731                 :           0 :       i4 = 1
     732                 :           0 :       ie = 1
     733                 :           0 :       IF = n*n+1
     734         [ #  # ]:           0 :       DO 10 i=1,n3
     735                 :           0 :          i1 = n1-i
     736                 :           0 :          diag = SQRT (l(i2))
     737                 :           0 :          w(i3) = ZERO
     738                 :           0 :          CALL dcopy_ (i1  ,  w(i3), 0, w(i3), 1)
     739                 :           0 :          CALL dcopy_ (i1-n2, l(i2), 1, w(i3), n)
     740                 :           0 :          CALL dscal_sl (i1-n2,     diag, w(i3), n)
     741                 :           0 :          w(i3) = diag
     742                 :           0 :          w(IF-1+i) = (g(i) - ddot_sl (i-1, w(i4), 1, w(IF), 1))/diag
     743                 :           0 :          i2 = i2 + i1 - n2
     744                 :           0 :          i3 = i3 + n1
     745                 :           0 :          i4 = i4 + n
     746                 :           0 :    10 CONTINUE
     747         [ #  # ]:           0 :       IF (n2.EQ.1) THEN
     748                 :           0 :           w(i3) = l(nl)
     749                 :           0 :           w(i4) = ZERO
     750                 :           0 :           CALL dcopy_ (n3, w(i4), 0, w(i4), 1)
     751                 :           0 :           w(IF-1+n) = ZERO
     752                 :             :       ENDIF
     753                 :           0 :       CALL dscal_sl (n, - one, w(IF), 1)
     754                 :             : 
     755                 :           0 :       ic = IF + n
     756                 :           0 :       id = ic + meq*n
     757                 :             : 
     758         [ #  # ]:           0 :       IF (meq .GT. 0) THEN
     759                 :             : 
     760                 :             : !C  RECOVER MATRIX C FROM UPPER PART OF A
     761                 :             : 
     762         [ #  # ]:           0 :           DO 20 i=1,meq
     763                 :           0 :               CALL dcopy_ (n, a(i,1), la, w(ic-1+i), meq)
     764                 :           0 :    20     CONTINUE
     765                 :             : 
     766                 :             : !C  RECOVER VECTOR D FROM UPPER PART OF B
     767                 :             : 
     768                 :           0 :           CALL dcopy_ (meq, b(1), 1, w(id), 1)
     769                 :           0 :           CALL dscal_sl (meq,   - one, w(id), 1)
     770                 :             : 
     771                 :             :       ENDIF
     772                 :             : 
     773                 :           0 :       ig = id + meq
     774                 :             : 
     775                 :             : !C  RECOVER MATRIX G FROM LOWER PART OF A
     776                 :             : !C  The matrix G(mineq+2*n,m1) is stored at w(ig)
     777                 :             : !C  Not all rows will be filled if some of the upper/lower
     778                 :             : !C  bounds are unbounded.
     779                 :             : 
     780         [ #  # ]:           0 :       IF (mineq .GT. 0) THEN
     781                 :             : 
     782         [ #  # ]:           0 :           DO 30 i=1,mineq
     783                 :           0 :               CALL dcopy_ (n, a(meq+i,1), la, w(ig-1+i), m1)
     784                 :           0 :    30     CONTINUE
     785                 :             : 
     786                 :             :       ENDIF
     787                 :             : 
     788                 :           0 :       ih = ig + m1*n
     789                 :           0 :       iw = ih + mineq + 2*n
     790                 :             : 
     791         [ #  # ]:           0 :       IF (mineq .GT. 0) THEN
     792                 :             : 
     793                 :             : !C  RECOVER H FROM LOWER PART OF B
     794                 :             : !C  The vector H(mineq+2*n) is stored at w(ih)
     795                 :             : 
     796                 :           0 :           CALL dcopy_ (mineq, b(meq+1), 1, w(ih), 1)
     797                 :           0 :           CALL dscal_sl (mineq,       - one, w(ih), 1)
     798                 :             : 
     799                 :             :       ENDIF
     800                 :             : 
     801                 :             : !C  AUGMENT MATRIX G BY +I AND -I, AND,
     802                 :             : !C  AUGMENT VECTOR H BY XL AND XU
     803                 :             : !C  NaN value indicates no bound
     804                 :             : 
     805                 :           0 :       ip = ig + mineq
     806                 :           0 :       il = ih + mineq
     807                 :           0 :       nancnt = 0
     808                 :             : 
     809         [ #  # ]:           0 :       DO 40 i=1,n
     810         [ #  # ]:           0 :          if (xl(i).eq.xl(i)) then
     811                 :           0 :             w(il) = xl(i)
     812         [ #  # ]:           0 :             do 41 j=1,n
     813                 :           0 :                w(ip + m1*(j-1)) = 0
     814                 :           0 :  41         continue
     815                 :           0 :             w(ip + m1*(i-1)) = 1
     816                 :           0 :             ip = ip + 1
     817                 :           0 :             il = il + 1
     818                 :             :          else
     819                 :           0 :             nancnt = nancnt + 1
     820                 :             :          end if
     821                 :           0 :    40 CONTINUE
     822                 :             : 
     823         [ #  # ]:           0 :       DO 50 i=1,n
     824         [ #  # ]:           0 :          if (xu(i).eq.xu(i)) then
     825                 :           0 :             w(il) = -xu(i)
     826         [ #  # ]:           0 :             do 51 j=1,n
     827                 :           0 :                w(ip + m1*(j-1)) = 0
     828                 :           0 :  51         continue
     829                 :           0 :             w(ip + m1*(i-1)) = -1
     830                 :           0 :             ip = ip + 1
     831                 :           0 :             il = il + 1
     832                 :             :          else
     833                 :           0 :             nancnt = nancnt + 1
     834                 :             :          end if
     835                 :           0 :  50   CONTINUE
     836                 :             : 
     837                 :             :       CALL lsei (w(ic), w(id), w(ie), w(IF), w(ig), w(ih), MAX(1,meq),&
     838                 :           0 :                  meq, n, n, m1, m1-nancnt, n, x, xnorm, w(iw), jw, mode)
     839                 :             : 
     840         [ #  # ]:           0 :       IF (mode .EQ. 1) THEN
     841                 :             : 
     842                 :             : !c   restore Lagrange multipliers (only for user-defined variables)
     843                 :             : 
     844                 :           0 :           CALL dcopy_ (m,  w(iw),     1, y(1),      1)
     845                 :             : 
     846                 :             : !c   set rest of the multipliers to nan (they are not used)
     847                 :             : 
     848         [ #  # ]:           0 :           IF (n3 .GT. 0) THEN
     849                 :           0 :              y(m+1) = 0
     850                 :           0 :              y(m+1) = 0 / y(m+1)
     851         [ #  # ]:           0 :              do 60 i=m+2,m+n3+n3
     852                 :           0 :                 y(i) = y(m+1)
     853                 :           0 :  60          continue
     854                 :             :           ENDIF
     855                 :             : 
     856                 :             :       ENDIF
     857                 :           0 :       call bound(n, x, xl, xu)
     858                 :             : 
     859                 :             : !C   END OF SUBROUTINE LSQ
     860                 :             : 
     861                 :           0 :       END SUBROUTINE lsq
     862                 :             : 
     863                 :             : 
     864                 :           0 :       SUBROUTINE lsei(c,d,e,f,g,h,lc,mc,LE,me,lg,mg,n,x,xnrm,w,jw,mode)
     865                 :             : 
     866                 :             : !C     FOR MODE=1, THE SUBROUTINE RETURNS THE SOLUTION X OF
     867                 :             : !C     EQUALITY & INEQUALITY CONSTRAINED LEAST SQUARES PROBLEM LSEI :
     868                 :             : 
     869                 :             : !C                MIN ||E*X - F||
     870                 :             : !C                 X
     871                 :             : 
     872                 :             : !C                S.T.  C*X  = D,
     873                 :             : !C                      G*X >= H.
     874                 :             : 
     875                 :             : !C     USING QR DECOMPOSITION & ORTHOGONAL BASIS OF NULLSPACE OF C
     876                 :             : !C     CHAPTER 23.6 OF LAWSON & HANSON: SOLVING LEAST SQUARES PROBLEMS.
     877                 :             : 
     878                 :             : !C     THE FOLLOWING DIMENSIONS OF THE ARRAYS DEFINING THE PROBLEM
     879                 :             : !C     ARE NECESSARY
     880                 :             : !C     DIM(E) :   FORMAL (LE,N),    ACTUAL (ME,N)
     881                 :             : !C     DIM(F) :   FORMAL (LE  ),    ACTUAL (ME  )
     882                 :             : !C     DIM(C) :   FORMAL (LC,N),    ACTUAL (MC,N)
     883                 :             : !C     DIM(D) :   FORMAL (LC  ),    ACTUAL (MC  )
     884                 :             : !C     DIM(G) :   FORMAL (LG,N),    ACTUAL (MG,N)
     885                 :             : !C     DIM(H) :   FORMAL (LG  ),    ACTUAL (MG  )
     886                 :             : !C     DIM(X) :   FORMAL (N   ),    ACTUAL (N   )
     887                 :             : !C     DIM(W) :   2*MC+ME+(ME+MG)*(N-MC)  for LSEI
     888                 :             : !C              +(N-MC+1)*(MG+2)+2*MG     for LSI
     889                 :             : !C     DIM(JW):   MAX(MG,L)
     890                 :             : !C     ON ENTRY, THE USER HAS TO PROVIDE THE ARRAYS C, D, E, F, G, AND H.
     891                 :             : !C     ON RETURN, ALL ARRAYS WILL BE CHANGED BY THE SUBROUTINE.
     892                 :             : !C     X     STORES THE SOLUTION VECTOR
     893                 :             : !C     XNORM STORES THE RESIDUUM OF THE SOLUTION IN EUCLIDIAN NORM
     894                 :             : !C     W     STORES THE VECTOR OF LAGRANGE MULTIPLIERS IN ITS FIRST
     895                 :             : !C           MC+MG ELEMENTS
     896                 :             : !C     MODE  IS A SUCCESS-FAILURE FLAG WITH THE FOLLOWING MEANINGS:
     897                 :             : !C          MODE=1: SUCCESSFUL COMPUTATION
     898                 :             : !C               2: ERROR RETURN BECAUSE OF WRONG DIMENSIONS (N<1)
     899                 :             : !C               3: ITERATION COUNT EXCEEDED BY NNLS
     900                 :             : !C               4: INEQUALITY CONSTRAINTS INCOMPATIBLE
     901                 :             : !C               5: MATRIX E IS NOT OF FULL RANK
     902                 :             : !C               6: MATRIX C IS NOT OF FULL RANK
     903                 :             : !C               7: RANK DEFECT IN HFTI
     904                 :             : 
     905                 :             : !C     18.5.1981, DIETER KRAFT, DFVLR OBERPFAFFENHOFEN
     906                 :             : !C     20.3.1987, DIETER KRAFT, DFVLR OBERPFAFFENHOFEN
     907                 :             : 
     908                 :             :       INTEGER          jw(*),i,ie,IF,ig,iw,j,k,krank,l,lc,LE,lg,&
     909                 :             :                        mc,mc1,me,mg,mode,n
     910                 :             :       DOUBLE PRECISION c(lc,n),e(LE,n),g(lg,n),d(lc),f(LE),h(lg),x(n),&
     911                 :             :                        w(*),t,xnrm,rnorm(1),epmach,ZERO
     912                 :             :       DATA             epmach/2.22d-16/,ZERO/0.0d+00/
     913                 :             : 
     914                 :           0 :       mode=2
     915         [ #  # ]:           0 :       IF(mc.GT.n)                      GOTO 75
     916                 :           0 :       l=n-mc
     917                 :           0 :       mc1=mc+1
     918                 :           0 :       iw=(l+1)*(mg+2)+2*mg+mc
     919                 :           0 :       ie=iw+mc+1
     920                 :           0 :       IF=ie+me*l
     921                 :           0 :       ig=IF+me
     922                 :             : 
     923                 :             : !C  TRIANGULARIZE C AND APPLY FACTORS TO E AND G
     924                 :             : 
     925         [ #  # ]:           0 :       DO 10 i=1,mc
     926                 :           0 :           j=MIN(i+1,lc)
     927                 :           0 :           CALL h12(1,i,i+1,n,c(i,1),lc,w(iw+i),c(j,1),lc,1,mc-i)
     928                 :           0 :           CALL h12(2,i,i+1,n,c(i,1),lc,w(iw+i),e     ,LE,1,me)
     929                 :           0 :           CALL h12(2,i,i+1,n,c(i,1),lc,w(iw+i),g     ,lg,1,mg)
     930                 :           0 :    10 CONTINUE
     931                 :             : 
     932                 :             : !C  SOLVE C*X=D AND MODIFY F
     933                 :             : 
     934                 :           0 :       mode=6
     935         [ #  # ]:           0 :       DO 15 i=1,mc
     936         [ #  # ]:           0 :           IF(ABS(c(i,i)).LT.epmach)    GOTO 75
     937                 :           0 :           x(i)=(d(i)-ddot_sl(i-1,c(i,1),lc,x,1))/c(i,i)
     938                 :           0 :    15 CONTINUE
     939                 :           0 :       mode=1
     940                 :           0 :       w(mc1) = ZERO
     941                 :           0 :       CALL dcopy_ (mg-mc,w(mc1),0,w(mc1),1)
     942                 :             : 
     943         [ #  # ]:           0 :       IF(mc.EQ.n)                      GOTO 50
     944                 :             : 
     945         [ #  # ]:           0 :       DO 20 i=1,me
     946                 :           0 :           w(IF-1+i)=f(i)-ddot_sl(mc,e(i,1),LE,x,1)
     947                 :           0 :    20 CONTINUE
     948                 :             : !C  STORE TRANSFORMED E & G
     949                 :             : 
     950         [ #  # ]:           0 :       DO 25 i=1,me
     951                 :           0 :           CALL dcopy_(l,e(i,mc1),LE,w(ie-1+i),me)
     952                 :           0 :    25 CONTINUE
     953         [ #  # ]:           0 :       DO 30 i=1,mg
     954                 :           0 :           CALL dcopy_(l,g(i,mc1),lg,w(ig-1+i),mg)
     955                 :           0 :    30 CONTINUE
     956                 :             : 
     957         [ #  # ]:           0 :       IF(mg.GT.0)                      GOTO 40
     958                 :             : 
     959                 :             : !C  SOLVE LS WITHOUT INEQUALITY CONSTRAINTS
     960                 :             : 
     961                 :           0 :       mode=7
     962                 :           0 :       k=MAX(LE,n)
     963                 :           0 :       t=SQRT(epmach)
     964                 :           0 :       CALL hfti (w(ie),me,me,l,w(IF),k,1,t,krank,rnorm,w,w(l+1),jw)
     965                 :             : !C  HFTI IS MORE GENERIC, BUT WE ONLY CALL IT WITH NB=1, SO RETRIEVE THE
     966                 :             : !C  SINGLE VALUE WE NEED FROM RNORM HERE
     967                 :           0 :       xnrm = rnorm(1)
     968                 :           0 :       CALL dcopy_(l,w(IF),1,x(mc1),1)
     969         [ #  # ]:           0 :       IF(krank.NE.l)                   GOTO 75
     970                 :           0 :       mode=1
     971                 :           0 :                                        GOTO 50
     972                 :             : !C  MODIFY H AND SOLVE INEQUALITY CONSTRAINED LS PROBLEM
     973                 :             : 
     974         [ #  # ]:           0 :    40 DO 45 i=1,mg
     975                 :           0 :           h(i)=h(i)-ddot_sl(mc,g(i,1),lg,x,1)
     976                 :           0 :    45 CONTINUE
     977                 :             :       CALL lsi &
     978                 :           0 :        (w(ie),w(IF),w(ig),h,me,me,mg,mg,l,x(mc1),xnrm,w(mc1),jw,mode)
     979         [ #  # ]:           0 :       IF(mc.EQ.0)                      GOTO 75
     980                 :           0 :       t=dnrm2_(mc,x,1)
     981                 :           0 :       xnrm=SQRT(xnrm*xnrm+t*t)
     982         [ #  # ]:           0 :       IF(mode.NE.1)                    GOTO 75
     983                 :             : 
     984                 :             : !C  SOLUTION OF ORIGINAL PROBLEM AND LAGRANGE MULTIPLIERS
     985                 :             : 
     986         [ #  # ]:           0 :    50 DO 55 i=1,me
     987                 :           0 :           f(i)=ddot_sl(n,e(i,1),LE,x,1)-f(i)
     988                 :           0 :    55 CONTINUE
     989         [ #  # ]:           0 :       DO 60 i=1,mc
     990                 :           0 :           d(i)=ddot_sl(me,e(1,i),1,f,1)-ddot_sl(mg,g(1,i),1,w(mc1),1)
     991                 :           0 :    60 CONTINUE
     992         [ #  # ]:           0 :       DO 65 i=mc,1,-1
     993                 :           0 :           CALL h12(2,i,i+1,n,c(i,1),lc,w(iw+i),x,1,1,1)
     994                 :           0 :    65 CONTINUE
     995         [ #  # ]:           0 :       DO 70 i=mc,1,-1
     996                 :           0 :           j=MIN(i+1,lc)
     997                 :           0 :           w(i)=(d(i)-ddot_sl(mc-i,c(j,i),1,w(j),1))/c(i,i)
     998                 :           0 :    70 CONTINUE
     999                 :             : 
    1000                 :             : !C  END OF SUBROUTINE LSEI
    1001                 :             : 
    1002                 :             :    75 CONTINUE
    1003                 :             : 
    1004                 :           0 :       END SUBROUTINE lsei
    1005                 :             : 
    1006                 :           0 :       SUBROUTINE lsi(e,f,g,h,LE,me,lg,mg,n,x,xnorm,w,jw,mode)
    1007                 :             : 
    1008                 :             : !C     FOR MODE=1, THE SUBROUTINE RETURNS THE SOLUTION X OF
    1009                 :             : !C     INEQUALITY CONSTRAINED LINEAR LEAST SQUARES PROBLEM:
    1010                 :             : 
    1011                 :             : !C                    MIN ||E*X-F||
    1012                 :             : !C                     X
    1013                 :             : 
    1014                 :             : !C                    S.T.  G*X >= H
    1015                 :             : 
    1016                 :             : !C     THE ALGORITHM IS BASED ON QR DECOMPOSITION AS DESCRIBED IN
    1017                 :             : !C     CHAPTER 23.5 OF LAWSON & HANSON: SOLVING LEAST SQUARES PROBLEMS
    1018                 :             : 
    1019                 :             : !C     THE FOLLOWING DIMENSIONS OF THE ARRAYS DEFINING THE PROBLEM
    1020                 :             : !C     ARE NECESSARY
    1021                 :             : !C     DIM(E) :   FORMAL (LE,N),    ACTUAL (ME,N)
    1022                 :             : !C     DIM(F) :   FORMAL (LE  ),    ACTUAL (ME  )
    1023                 :             : !C     DIM(G) :   FORMAL (LG,N),    ACTUAL (MG,N)
    1024                 :             : !C     DIM(H) :   FORMAL (LG  ),    ACTUAL (MG  )
    1025                 :             : !C     DIM(X) :   N
    1026                 :             : !C     DIM(W) :   (N+1)*(MG+2) + 2*MG
    1027                 :             : !C     DIM(JW):   LG
    1028                 :             : !C     ON ENTRY, THE USER HAS TO PROVIDE THE ARRAYS E, F, G, AND H.
    1029                 :             : !C     ON RETURN, ALL ARRAYS WILL BE CHANGED BY THE SUBROUTINE.
    1030                 :             : !C     X     STORES THE SOLUTION VECTOR
    1031                 :             : !C     XNORM STORES THE RESIDUUM OF THE SOLUTION IN EUCLIDIAN NORM
    1032                 :             : !C     W     STORES THE VECTOR OF LAGRANGE MULTIPLIERS IN ITS FIRST
    1033                 :             : !C           MG ELEMENTS
    1034                 :             : !C     MODE  IS A SUCCESS-FAILURE FLAG WITH THE FOLLOWING MEANINGS:
    1035                 :             : !C          MODE=1: SUCCESSFUL COMPUTATION
    1036                 :             : !C               2: ERROR RETURN BECAUSE OF WRONG DIMENSIONS (N<1)
    1037                 :             : !C               3: ITERATION COUNT EXCEEDED BY NNLS
    1038                 :             : !C               4: INEQUALITY CONSTRAINTS INCOMPATIBLE
    1039                 :             : !C               5: MATRIX E IS NOT OF FULL RANK
    1040                 :             : 
    1041                 :             : !C     03.01.1980, DIETER KRAFT: CODED
    1042                 :             : !C     20.03.1987, DIETER KRAFT: REVISED TO FORTRAN 77
    1043                 :             : 
    1044                 :             :       INTEGER          i,j,LE,lg,me,mg,mode,n,jw(lg)
    1045                 :             :       DOUBLE PRECISION e(LE,n),f(LE),g(lg,n),h(lg),x(n),w(*),&
    1046                 :             :                        xnorm,epmach,t,one
    1047                 :             :       DATA             epmach/2.22d-16/,one/1.0d+00/
    1048                 :             : 
    1049                 :             : !C  QR-FACTORS OF E AND APPLICATION TO F
    1050                 :             : 
    1051         [ #  # ]:           0 :       DO 10 i=1,n
    1052                 :           0 :       j=MIN(i+1,n)
    1053                 :           0 :       CALL h12(1,i,i+1,me,e(1,i),1,t,e(1,j),1,LE,n-i)
    1054                 :           0 :       CALL h12(2,i,i+1,me,e(1,i),1,t,f     ,1,1 ,1  )
    1055                 :           0 :    10 CONTINUE
    1056                 :             : !C  TRANSFORM G AND H TO GET LEAST DISTANCE PROBLEM
    1057                 :             : 
    1058                 :           0 :       mode=5
    1059         [ #  # ]:           0 :       DO 30 i=1,mg
    1060         [ #  # ]:           0 :           DO 20 j=1,n
    1061         [ #  # ]:           0 :               IF (.NOT.(ABS(e(j,j)).GE.epmach)) GOTO 50
    1062                 :           0 :               g(i,j)=(g(i,j)-ddot_sl(j-1,g(i,1),lg,e(1,j),1))/e(j,j)
    1063                 :           0 :    20     CONTINUE
    1064                 :           0 :           h(i)=h(i)-ddot_sl(n,g(i,1),lg,f,1)
    1065                 :           0 :    30 CONTINUE
    1066                 :             : 
    1067                 :             : !C  SOLVE LEAST DISTANCE PROBLEM
    1068                 :             : 
    1069                 :           0 :       CALL ldp(g,lg,mg,n,h,x,xnorm,w,jw,mode)
    1070         [ #  # ]:           0 :       IF (mode.NE.1)                     GOTO 50
    1071                 :             : 
    1072                 :             : !C  SOLUTION OF ORIGINAL PROBLEM
    1073                 :             : 
    1074                 :           0 :       CALL daxpy_sl(n,one,f,1,x,1)
    1075         [ #  # ]:           0 :       DO 40 i=n,1,-1
    1076                 :           0 :           j=MIN(i+1,n)
    1077                 :           0 :           x(i)=(x(i)-ddot_sl(n-i,e(i,j),LE,x(j),1))/e(i,i)
    1078                 :           0 :    40 CONTINUE
    1079                 :           0 :       j=MIN(n+1,me)
    1080                 :           0 :       t=dnrm2_(me-n,f(j),1)
    1081                 :           0 :       xnorm=SQRT(xnorm*xnorm+t*t)
    1082                 :             : 
    1083                 :             : !C  END OF SUBROUTINE LSI
    1084                 :             : 
    1085                 :             :    50 CONTINUE
    1086                 :             : 
    1087                 :           0 :       END SUBROUTINE lsi
    1088                 :             : 
    1089                 :           0 :       SUBROUTINE ldp(g,mg,m,n,h,x,xnorm,w,INDEX,mode)
    1090                 :             : 
    1091                 :             : !C                     T
    1092                 :             : !C     MINIMIZE   1/2 X X    SUBJECT TO   G * X >= H.
    1093                 :             : 
    1094                 :             : !C       C.L. LAWSON, R.J. HANSON: 'SOLVING LEAST SQUARES PROBLEMS'
    1095                 :             : !C       PRENTICE HALL, ENGLEWOOD CLIFFS, NEW JERSEY, 1974.
    1096                 :             : 
    1097                 :             : !C     PARAMETER DESCRIPTION:
    1098                 :             : 
    1099                 :             : !C     G(),MG,M,N   ON ENTRY G() STORES THE M BY N MATRIX OF
    1100                 :             : !C                  LINEAR INEQUALITY CONSTRAINTS. G() HAS FIRST
    1101                 :             : !C                  DIMENSIONING PARAMETER MG
    1102                 :             : !C     H()          ON ENTRY H() STORES THE M VECTOR H REPRESENTING
    1103                 :             : !C                  THE RIGHT SIDE OF THE INEQUALITY SYSTEM
    1104                 :             : 
    1105                 :             : !C     REMARK: G(),H() WILL NOT BE CHANGED DURING CALCULATIONS BY LDP
    1106                 :             : 
    1107                 :             : !C     X()          ON ENTRY X() NEED NOT BE INITIALIZED.
    1108                 :             : !C                  ON EXIT X() STORES THE SOLUTION VECTOR X IF MODE=1.
    1109                 :             : !C     XNORM        ON EXIT XNORM STORES THE EUCLIDIAN NORM OF THE
    1110                 :             : !C                  SOLUTION VECTOR IF COMPUTATION IS SUCCESSFUL
    1111                 :             : !C     W()          W IS A ONE DIMENSIONAL WORKING SPACE, THE LENGTH
    1112                 :             : !C                  OF WHICH SHOULD BE AT LEAST (M+2)*(N+1) + 2*M
    1113                 :             : !C                  ON EXIT W() STORES THE LAGRANGE MULTIPLIERS
    1114                 :             : !C                  ASSOCIATED WITH THE CONSTRAINTS
    1115                 :             : !C                  AT THE SOLUTION OF PROBLEM LDP
    1116                 :             : !C     INDEX()      INDEX() IS A ONE DIMENSIONAL INTEGER WORKING SPACE
    1117                 :             : !C                  OF LENGTH AT LEAST M
    1118                 :             : !C     MODE         MODE IS A SUCCESS-FAILURE FLAG WITH THE FOLLOWING
    1119                 :             : !C                  MEANINGS:
    1120                 :             : !C          MODE=1: SUCCESSFUL COMPUTATION
    1121                 :             : !C               2: ERROR RETURN BECAUSE OF WRONG DIMENSIONS (N.LE.0)
    1122                 :             : !C               3: ITERATION COUNT EXCEEDED BY NNLS
    1123                 :             : !C               4: INEQUALITY CONSTRAINTS INCOMPATIBLE
    1124                 :             : 
    1125                 :             :       DOUBLE PRECISION g,h,x,xnorm,w,u,v,&
    1126                 :             :                        ZERO,one,fac,rnorm,diff
    1127                 :             :       INTEGER          INDEX,i,IF,iw,iwdual,iy,iz,j,m,mg,mode,n,n1
    1128                 :             :       DIMENSION        g(mg,n),h(m),x(n),w(*),INDEX(m)
    1129                 :             :       diff(u,v)=       u-v
    1130                 :             :       DATA             ZERO,one/0.0d0,1.0d0/
    1131                 :             : 
    1132                 :           0 :       mode=2
    1133         [ #  # ]:           0 :       IF(n.LE.0)                    GOTO 50
    1134                 :             : 
    1135                 :             : !C  STATE DUAL PROBLEM
    1136                 :             : 
    1137                 :           0 :       mode=1
    1138                 :           0 :       x(1)=ZERO
    1139                 :           0 :       CALL dcopy_(n,x(1),0,x,1)
    1140                 :           0 :       xnorm=ZERO
    1141         [ #  # ]:           0 :       IF(m.EQ.0)                    GOTO 50
    1142                 :             :       iw=0
    1143         [ #  # ]:           0 :       DO 20 j=1,m
    1144         [ #  # ]:           0 :           DO 10 i=1,n
    1145                 :           0 :               iw=iw+1
    1146                 :           0 :               w(iw)=g(j,i)
    1147                 :           0 :    10     CONTINUE
    1148                 :           0 :           iw=iw+1
    1149                 :           0 :           w(iw)=h(j)
    1150                 :           0 :    20 CONTINUE
    1151                 :             :       IF=iw+1
    1152         [ #  # ]:           0 :       DO 30 i=1,n
    1153                 :           0 :           iw=iw+1
    1154                 :           0 :           w(iw)=ZERO
    1155                 :           0 :    30 CONTINUE
    1156                 :           0 :       w(iw+1)=one
    1157                 :           0 :       n1=n+1
    1158                 :           0 :       iz=iw+2
    1159                 :           0 :       iy=iz+n1
    1160                 :           0 :       iwdual=iy+m
    1161                 :             : 
    1162                 :             : !C  SOLVE DUAL PROBLEM
    1163                 :             : 
    1164                 :           0 :       CALL nnls (w,n1,n1,m,w(IF),w(iy),rnorm,w(iwdual),w(iz),INDEX,mode)
    1165                 :             : 
    1166         [ #  # ]:           0 :       IF(mode.NE.1)                 GOTO 50
    1167                 :           0 :       mode=4
    1168         [ #  # ]:           0 :       IF(rnorm.LE.ZERO)             GOTO 50
    1169                 :             : 
    1170                 :             : !C  COMPUTE SOLUTION OF PRIMAL PROBLEM
    1171                 :             : 
    1172                 :           0 :       fac=one-ddot_sl(m,h,1,w(iy),1)
    1173         [ #  # ]:           0 :       IF(.NOT.(diff(one+fac,one).GT.ZERO)) GOTO 50
    1174                 :           0 :       mode=1
    1175                 :           0 :       fac=one/fac
    1176         [ #  # ]:           0 :       DO 40 j=1,n
    1177                 :           0 :           x(j)=fac*ddot_sl(m,g(1,j),1,w(iy),1)
    1178                 :           0 :    40 CONTINUE
    1179                 :           0 :       xnorm=dnrm2_(n,x,1)
    1180                 :             : 
    1181                 :             : !C  COMPUTE LAGRANGE MULTIPLIERS FOR PRIMAL PROBLEM
    1182                 :             : 
    1183                 :           0 :       w(1)=ZERO
    1184                 :           0 :       CALL dcopy_(m,w(1),0,w,1)
    1185                 :           0 :       CALL daxpy_sl(m,fac,w(iy),1,w,1)
    1186                 :             : 
    1187                 :             : !C  END OF SUBROUTINE LDP
    1188                 :             : 
    1189                 :             :    50 CONTINUE
    1190                 :             : 
    1191                 :           0 :       END SUBROUTINE ldp
    1192                 :             : 
    1193                 :             : 
    1194                 :           0 :       SUBROUTINE nnls (a, mda, m, n, b, x, rnorm, w, z, INDEX, mode)
    1195                 :             : 
    1196                 :             : !C     C.L.LAWSON AND R.J.HANSON, JET PROPULSION LABORATORY:
    1197                 :             : !C     'SOLVING LEAST SQUARES PROBLEMS'. PRENTICE-HALL.1974
    1198                 :             : 
    1199                 :             : !C      **********   NONNEGATIVE LEAST SQUARES   **********
    1200                 :             : 
    1201                 :             : !C     GIVEN AN M BY N MATRIX, A, AND AN M-VECTOR, B, COMPUTE AN
    1202                 :             : !C     N-VECTOR, X, WHICH SOLVES THE LEAST SQUARES PROBLEM
    1203                 :             : 
    1204                 :             : !C                  A*X = B  SUBJECT TO  X >= 0
    1205                 :             : 
    1206                 :             : !C     A(),MDA,M,N
    1207                 :             : !C            MDA IS THE FIRST DIMENSIONING PARAMETER FOR THE ARRAY,A().
    1208                 :             : !C            ON ENTRY A()  CONTAINS THE M BY N MATRIX,A.
    1209                 :             : !C            ON EXIT A() CONTAINS THE PRODUCT Q*A,
    1210                 :             : !C            WHERE Q IS AN M BY M ORTHOGONAL MATRIX GENERATED
    1211                 :             : !C            IMPLICITLY BY THIS SUBROUTINE.
    1212                 :             : !C            EITHER M>=N OR M<N IS PERMISSIBLE.
    1213                 :             : !C            THERE IS NO RESTRICTION ON THE RANK OF A.
    1214                 :             : !C     B()    ON ENTRY B() CONTAINS THE M-VECTOR, B.
    1215                 :             : !C            ON EXIT B() CONTAINS Q*B.
    1216                 :             : !C     X()    ON ENTRY X() NEED NOT BE INITIALIZED.
    1217                 :             : !C            ON EXIT X() WILL CONTAIN THE SOLUTION VECTOR.
    1218                 :             : !C     RNORM  ON EXIT RNORM CONTAINS THE EUCLIDEAN NORM OF THE
    1219                 :             : !C            RESIDUAL VECTOR.
    1220                 :             : !C     W()    AN N-ARRAY OF WORKING SPACE.
    1221                 :             : !C            ON EXIT W() WILL CONTAIN THE DUAL SOLUTION VECTOR.
    1222                 :             : !C            W WILL SATISFY W(I)=0 FOR ALL I IN SET P
    1223                 :             : !C            AND W(I)<=0 FOR ALL I IN SET Z
    1224                 :             : !C     Z()    AN M-ARRAY OF WORKING SPACE.
    1225                 :             : !C     INDEX()AN INTEGER WORKING ARRAY OF LENGTH AT LEAST N.
    1226                 :             : !C            ON EXIT THE CONTENTS OF THIS ARRAY DEFINE THE SETS
    1227                 :             : !C            P AND Z AS FOLLOWS:
    1228                 :             : !C            INDEX(1)    THRU INDEX(NSETP) = SET P.
    1229                 :             : !C            INDEX(IZ1)  THRU INDEX (IZ2)  = SET Z.
    1230                 :             : !C            IZ1=NSETP + 1 = NPP1, IZ2=N.
    1231                 :             : !C     MODE   THIS IS A SUCCESS-FAILURE FLAG WITH THE FOLLOWING MEANING:
    1232                 :             : !C            1    THE SOLUTION HAS BEEN COMPUTED SUCCESSFULLY.
    1233                 :             : !C            2    THE DIMENSIONS OF THE PROBLEM ARE WRONG,
    1234                 :             : !C                 EITHER M <= 0 OR N <= 0.
    1235                 :             : !C            3    ITERATION COUNT EXCEEDED, MORE THAN 3*N ITERATIONS.
    1236                 :             : 
    1237                 :             :       INTEGER          i,ii,ip,iter,itmax,iz,izmax,iz1,iz2,j,jj,jz,&
    1238                 :             :                        k,l,m,mda,mode,n,npp1,nsetp,INDEX(n)
    1239                 :             : 
    1240                 :             :       DOUBLE PRECISION a(mda,n),b(m),x(n),w(n),z(m),asave,diff,&
    1241                 :             :                        factor,ZERO,one,wmax,alpha,&
    1242                 :             :                        c,s,t,u,v,up,rnorm,unorm
    1243                 :             : 
    1244                 :             :       diff(u,v)=       u-v
    1245                 :             : 
    1246                 :             :       DATA             ZERO,one,factor/0.0d0,1.0d0,1.0d-2/
    1247                 :             : 
    1248                 :             : !c     revised          Dieter Kraft, March 1983
    1249                 :             : 
    1250                 :           0 :       mode=2
    1251   [ #  #  #  # ]:           0 :       IF(m.LE.0.OR.n.LE.0)            GOTO 290
    1252                 :           0 :       mode=1
    1253                 :           0 :       iter=0
    1254                 :           0 :       itmax=3*n
    1255                 :             : 
    1256                 :             : !C STEP ONE (INITIALIZE)
    1257                 :             : 
    1258         [ #  # ]:           0 :       DO 100 i=1,n
    1259                 :           0 :          INDEX(i)=i
    1260                 :           0 :   100 CONTINUE
    1261                 :           0 :       iz1=1
    1262                 :           0 :       iz2=n
    1263                 :           0 :       nsetp=0
    1264                 :           0 :       npp1=1
    1265                 :           0 :       x(1)=ZERO
    1266                 :           0 :       CALL dcopy_(n,x(1),0,x,1)
    1267                 :             : 
    1268                 :             : !C STEP TWO (COMPUTE DUAL VARIABLES)
    1269                 :             : !C .....ENTRY LOOP A
    1270                 :             : 
    1271   [ #  #  #  # ]:           0 :   110 IF(iz1.GT.iz2.OR.nsetp.GE.m)    GOTO 280
    1272         [ #  # ]:           0 :       DO 120 iz=iz1,iz2
    1273                 :           0 :          j=INDEX(iz)
    1274                 :           0 :          w(j)=ddot_sl(m-nsetp,a(npp1,j),1,b(npp1),1)
    1275                 :           0 :   120 CONTINUE
    1276                 :             : 
    1277                 :             : !C STEP THREE (TEST DUAL VARIABLES)
    1278                 :             : 
    1279                 :           0 :   130 wmax=ZERO
    1280         [ #  # ]:           0 :       DO 140 iz=iz1,iz2
    1281                 :           0 :       j=INDEX(iz)
    1282         [ #  # ]:           0 :          IF(w(j).LE.wmax)             GOTO 140
    1283                 :           0 :          wmax=w(j)
    1284                 :           0 :          izmax=iz
    1285                 :           0 :   140 CONTINUE
    1286                 :             : 
    1287                 :             : !C .....EXIT LOOP A
    1288                 :             : 
    1289         [ #  # ]:           0 :       IF(wmax.LE.ZERO)                GOTO 280
    1290                 :           0 :       iz=izmax
    1291                 :           0 :       j=INDEX(iz)
    1292                 :             : 
    1293                 :             : !C STEP FOUR (TEST INDEX J FOR LINEAR DEPENDENCY)
    1294                 :             : 
    1295                 :           0 :       asave=a(npp1,j)
    1296                 :           0 :       CALL h12(1,npp1,npp1+1,m,a(1,j),1,up,z,1,1,0)
    1297                 :           0 :       unorm=dnrm2_(nsetp,a(1,j),1)
    1298                 :           0 :       t=factor*ABS(a(npp1,j))
    1299         [ #  # ]:           0 :       IF(diff(unorm+t,unorm).LE.ZERO) GOTO 150
    1300                 :           0 :       CALL dcopy_(m,b,1,z,1)
    1301                 :           0 :       CALL h12(2,npp1,npp1+1,m,a(1,j),1,up,z,1,1,1)
    1302         [ #  # ]:           0 :       IF(z(npp1)/a(npp1,j).GT.ZERO)   GOTO 160
    1303                 :           0 :   150 a(npp1,j)=asave
    1304                 :           0 :       w(j)=ZERO
    1305                 :           0 :                                       GOTO 130
    1306                 :             : !C STEP FIVE (ADD COLUMN)
    1307                 :             : 
    1308                 :           0 :   160 CALL dcopy_(m,z,1,b,1)
    1309                 :           0 :       INDEX(iz)=INDEX(iz1)
    1310                 :           0 :       INDEX(iz1)=j
    1311                 :           0 :       iz1=iz1+1
    1312                 :           0 :       nsetp=npp1
    1313                 :           0 :       npp1=npp1+1
    1314         [ #  # ]:           0 :       DO 170 jz=iz1,iz2
    1315                 :           0 :          jj=INDEX(jz)
    1316                 :           0 :          CALL h12(2,nsetp,npp1,m,a(1,j),1,up,a(1,jj),1,mda,1)
    1317                 :           0 :   170 CONTINUE
    1318                 :           0 :       k=MIN(npp1,mda)
    1319                 :           0 :       w(j)=ZERO
    1320                 :           0 :       CALL dcopy_(m-nsetp,w(j),0,a(k,j),1)
    1321                 :             : 
    1322                 :             : !C STEP SIX (SOLVE LEAST SQUARES SUB-PROBLEM)
    1323                 :             : !C .....ENTRY LOOP B
    1324                 :             : 
    1325         [ #  # ]:           0 :   180 DO 200 ip=nsetp,1,-1
    1326         [ #  # ]:           0 :          IF(ip.EQ.nsetp)              GOTO 190
    1327                 :           0 :          CALL daxpy_sl(ip,-z(ip+1),a(1,jj),1,z,1)
    1328                 :           0 :   190    jj=INDEX(ip)
    1329                 :           0 :          z(ip)=z(ip)/a(ip,jj)
    1330                 :           0 :   200 CONTINUE
    1331                 :           0 :       iter=iter+1
    1332         [ #  # ]:           0 :       IF(iter.LE.itmax)               GOTO 220
    1333                 :           0 :   210 mode=3
    1334                 :           0 :                                       GOTO 280
    1335                 :             : !C STEP SEVEN TO TEN (STEP LENGTH ALGORITHM)
    1336                 :             : 
    1337                 :           0 :   220 alpha=one
    1338                 :           0 :       jj=0
    1339         [ #  # ]:           0 :       DO 230 ip=1,nsetp
    1340         [ #  # ]:           0 :          IF(z(ip).GT.ZERO)            GOTO 230
    1341                 :           0 :          l=INDEX(ip)
    1342                 :           0 :          t=-x(l)/(z(ip)-x(l))
    1343         [ #  # ]:           0 :          IF(alpha.LT.t)               GOTO 230
    1344                 :           0 :          alpha=t
    1345                 :           0 :          jj=ip
    1346                 :           0 :   230 CONTINUE
    1347         [ #  # ]:           0 :       DO 240 ip=1,nsetp
    1348                 :           0 :          l=INDEX(ip)
    1349                 :           0 :          x(l)=(one-alpha)*x(l) + alpha*z(ip)
    1350                 :           0 :   240 CONTINUE
    1351                 :             : 
    1352                 :             : !C .....EXIT LOOP B
    1353                 :             : 
    1354         [ #  # ]:           0 :       IF(jj.EQ.0)                     GOTO 110
    1355                 :             : 
    1356                 :             : !C STEP ELEVEN (DELETE COLUMN)
    1357                 :             : 
    1358                 :           0 :       i=INDEX(jj)
    1359                 :           0 :   250 x(i)=ZERO
    1360                 :           0 :       jj=jj+1
    1361         [ #  # ]:           0 :       DO 260 j=jj,nsetp
    1362                 :           0 :          ii=INDEX(j)
    1363                 :           0 :          INDEX(j-1)=ii
    1364                 :           0 :          CALL dsrotg(a(j-1,ii),a(j,ii),c,s)
    1365                 :           0 :          t=a(j-1,ii)
    1366                 :           0 :          CALL dsrot(n,a(j-1,1),mda,a(j,1),mda,c,s)
    1367                 :           0 :          a(j-1,ii)=t
    1368                 :           0 :          a(j,ii)=ZERO
    1369                 :           0 :          CALL dsrot(1,b(j-1),1,b(j),1,c,s)
    1370                 :           0 :   260 CONTINUE
    1371                 :           0 :       npp1=nsetp
    1372                 :           0 :       nsetp=nsetp-1
    1373                 :           0 :       iz1=iz1-1
    1374                 :           0 :       INDEX(iz1)=i
    1375         [ #  # ]:           0 :       IF(nsetp.LE.0)                  GOTO 210
    1376         [ #  # ]:           0 :       DO 270 jj=1,nsetp
    1377                 :           0 :          i=INDEX(jj)
    1378         [ #  # ]:           0 :          IF(x(i).LE.ZERO)             GOTO 250
    1379                 :           0 :   270 CONTINUE
    1380                 :           0 :       CALL dcopy_(m,b,1,z,1)
    1381                 :           0 :                                       GOTO 180
    1382                 :             : !C STEP TWELVE (SOLUTION)
    1383                 :             : 
    1384                 :           0 :   280 k=MIN(npp1,m)
    1385                 :           0 :       rnorm=dnrm2_(m-nsetp,b(k),1)
    1386         [ #  # ]:           0 :       IF(npp1.GT.m) THEN
    1387                 :           0 :          w(1)=ZERO
    1388                 :           0 :          CALL dcopy_(n,w(1),0,w,1)
    1389                 :             :       ENDIF
    1390                 :             : 
    1391                 :             : !C END OF SUBROUTINE NNLS
    1392                 :             : 
    1393                 :             :   290 CONTINUE
    1394                 :             : 
    1395                 :           0 :       END SUBROUTINE nnls
    1396                 :             : 
    1397                 :           0 :       SUBROUTINE hfti(a,mda,m,n,b,mdb,nb,tau,krank,rnorm,h,g,ip)
    1398                 :             : 
    1399                 :             : !C     RANK-DEFICIENT LEAST SQUARES ALGORITHM AS DESCRIBED IN:
    1400                 :             : !C     C.L.LAWSON AND R.J.HANSON, JET PROPULSION LABORATORY, 1973 JUN 12
    1401                 :             : !C     TO APPEAR IN 'SOLVING LEAST SQUARES PROBLEMS', PRENTICE-HALL, 1974
    1402                 :             : 
    1403                 :             : !C     A(*,*),MDA,M,N   THE ARRAY A INITIALLY CONTAINS THE M x N MATRIX A
    1404                 :             : !C                      OF THE LEAST SQUARES PROBLEM AX = B.
    1405                 :             : !C                      THE FIRST DIMENSIONING PARAMETER MDA MUST SATISFY
    1406                 :             : !C                      MDA >= M. EITHER M >= N OR M < N IS PERMITTED.
    1407                 :             : !C                      THERE IS NO RESTRICTION ON THE RANK OF A.
    1408                 :             : !C                      THE MATRIX A WILL BE MODIFIED BY THE SUBROUTINE.
    1409                 :             : !C     B(*,*),MDB,NB    IF NB = 0 THE SUBROUTINE WILL MAKE NO REFERENCE
    1410                 :             : !C                      TO THE ARRAY B. IF NB > 0 THE ARRAY B() MUST
    1411                 :             : !C                      INITIALLY CONTAIN THE M x NB MATRIX B  OF THE
    1412                 :             : !C                      THE LEAST SQUARES PROBLEM AX = B AND ON RETURN
    1413                 :             : !C                      THE ARRAY B() WILL CONTAIN THE N x NB SOLUTION X.
    1414                 :             : !C                      IF NB>1 THE ARRAY B() MUST BE DOUBLE SUBSCRIPTED
    1415                 :             : !C                      WITH FIRST DIMENSIONING PARAMETER MDB>=MAX(M,N),
    1416                 :             : !C                      IF NB=1 THE ARRAY B() MAY BE EITHER SINGLE OR
    1417                 :             : !C                      DOUBLE SUBSCRIPTED.
    1418                 :             : !C     TAU              ABSOLUTE TOLERANCE PARAMETER FOR PSEUDORANK
    1419                 :             : !C                      DETERMINATION, PROVIDED BY THE USER.
    1420                 :             : !C     KRANK            PSEUDORANK OF A, SET BY THE SUBROUTINE.
    1421                 :             : !C     RNORM            ON EXIT, RNORM(J) WILL CONTAIN THE EUCLIDIAN
    1422                 :             : !C                      NORM OF THE RESIDUAL VECTOR FOR THE PROBLEM
    1423                 :             : !C                      DEFINED BY THE J-TH COLUMN VECTOR OF THE ARRAY B.
    1424                 :             : !C     H(), G()         ARRAYS OF WORKING SPACE OF LENGTH >= N.
    1425                 :             : !C     IP()             INTEGER ARRAY OF WORKING SPACE OF LENGTH >= N
    1426                 :             : !C                      RECORDING PERMUTATION INDICES OF COLUMN VECTORS
    1427                 :             : 
    1428                 :             :       INTEGER          i,j,jb,k,kp1,krank,l,ldiag,lmax,m,&
    1429                 :             :                        mda,mdb,n,nb,ip(n)
    1430                 :             :       DOUBLE PRECISION a(mda,n),b(mdb,nb),h(n),g(n),rnorm(nb),factor,&
    1431                 :             :                        tau,ZERO,hmax,diff,tmp,u,v
    1432                 :             :       diff(u,v)=       u-v
    1433                 :             :       DATA             ZERO/0.0d0/, factor/1.0d-3/
    1434                 :             : 
    1435                 :           0 :       k=0
    1436                 :           0 :       ldiag=MIN(m,n)
    1437         [ #  # ]:           0 :       IF(ldiag.LE.0)                  GOTO 270
    1438                 :             : 
    1439                 :             : !C   COMPUTE LMAX
    1440                 :             : 
    1441         [ #  # ]:           0 :       DO 80 j=1,ldiag
    1442         [ #  # ]:           0 :           IF(j.EQ.1)                  GOTO 20
    1443                 :             :           lmax=j
    1444         [ #  # ]:           0 :           DO 10 l=j,n
    1445                 :           0 :               h(l)=h(l)-a(j-1,l)**2
    1446         [ #  # ]:           0 :               IF(h(l).GT.h(lmax)) lmax=l
    1447                 :           0 :    10     CONTINUE
    1448         [ #  # ]:           0 :           IF(diff(hmax+factor*h(lmax),hmax).GT.ZERO)&
    1449                 :             :                                       GOTO 50
    1450                 :           0 :    20     lmax=j
    1451         [ #  # ]:           0 :           DO 40 l=j,n
    1452                 :           0 :               h(l)=ZERO
    1453         [ #  # ]:           0 :               DO 30 i=j,m
    1454                 :           0 :                   h(l)=h(l)+a(i,l)**2
    1455                 :           0 :    30         CONTINUE
    1456         [ #  # ]:           0 :               IF(h(l).GT.h(lmax)) lmax=l
    1457                 :           0 :    40     CONTINUE
    1458                 :           0 :           hmax=h(lmax)
    1459                 :             : 
    1460                 :             : !C   COLUMN INTERCHANGES IF NEEDED
    1461                 :             : 
    1462                 :           0 :    50     ip(j)=lmax
    1463         [ #  # ]:           0 :           IF(ip(j).EQ.j)              GOTO 70
    1464         [ #  # ]:           0 :           DO 60 i=1,m
    1465                 :           0 :               tmp=a(i,j)
    1466                 :           0 :               a(i,j)=a(i,lmax)
    1467                 :           0 :               a(i,lmax)=tmp
    1468                 :           0 :    60     CONTINUE
    1469                 :           0 :           h(lmax)=h(j)
    1470                 :             : 
    1471                 :             : !C   J-TH TRANSFORMATION AND APPLICATION TO A AND B
    1472                 :             : 
    1473                 :           0 :    70     i=MIN(j+1,n)
    1474                 :           0 :           CALL h12(1,j,j+1,m,a(1,j),1,h(j),a(1,i),1,mda,n-j)
    1475                 :           0 :           CALL h12(2,j,j+1,m,a(1,j),1,h(j),b,1,mdb,nb)
    1476                 :           0 :    80 CONTINUE
    1477                 :             : 
    1478                 :             : !C   DETERMINE PSEUDORANK
    1479                 :             : 
    1480         [ #  # ]:           0 :       DO 90 j=1,ldiag
    1481         [ #  # ]:           0 :           IF(ABS(a(j,j)).LE.tau)      GOTO 100
    1482                 :           0 :    90 CONTINUE
    1483                 :             :       k=ldiag
    1484                 :           0 :       GOTO 110
    1485                 :           0 :   100 k=j-1
    1486                 :           0 :   110 kp1=k+1
    1487                 :             : 
    1488                 :             : !C   NORM OF RESIDUALS
    1489                 :             : 
    1490         [ #  # ]:           0 :       DO 130 jb=1,nb
    1491                 :           0 :           rnorm(jb)=dnrm2_(m-k,b(kp1,jb),1)
    1492                 :           0 :   130 CONTINUE
    1493         [ #  # ]:           0 :       IF(k.GT.0)                      GOTO 160
    1494         [ #  # ]:           0 :       DO 150 jb=1,nb
    1495         [ #  # ]:           0 :           DO 149 i=1,n
    1496                 :           0 :               b(i,jb)=ZERO
    1497                 :           0 :   149     CONTINUE
    1498                 :           0 :   150 CONTINUE
    1499                 :           0 :       GOTO 270
    1500         [ #  # ]:           0 :   160 IF(k.EQ.n)                      GOTO 180
    1501                 :             : 
    1502                 :             : !C   HOUSEHOLDER DECOMPOSITION OF FIRST K ROWS
    1503                 :             : 
    1504         [ #  # ]:           0 :       DO 170 i=k,1,-1
    1505                 :           0 :           CALL h12(1,i,kp1,n,a(i,1),mda,g(i),a,mda,1,i-1)
    1506                 :           0 :   170 CONTINUE
    1507         [ #  # ]:           0 :   180 DO 250 jb=1,nb
    1508                 :             : 
    1509                 :             : !C   SOLVE K*K TRIANGULAR SYSTEM
    1510                 :             : 
    1511         [ #  # ]:           0 :           DO 210 i=k,1,-1
    1512                 :           0 :               j=MIN(i+1,n)
    1513                 :           0 :               b(i,jb)=(b(i,jb)-ddot_sl(k-i,a(i,j),mda,b(j,jb),1))/a(i,i)
    1514                 :           0 :   210     CONTINUE
    1515                 :             : 
    1516                 :             : !C   COMPLETE SOLUTION VECTOR
    1517                 :             : 
    1518         [ #  # ]:           0 :           IF(k.EQ.n)                  GOTO 240
    1519         [ #  # ]:           0 :           DO 220 j=kp1,n
    1520                 :           0 :               b(j,jb)=ZERO
    1521                 :           0 :   220     CONTINUE
    1522         [ #  # ]:           0 :           DO 230 i=1,k
    1523                 :           0 :               CALL h12(2,i,kp1,n,a(i,1),mda,g(i),b(1,jb),1,mdb,1)
    1524                 :           0 :   230     CONTINUE
    1525                 :             : 
    1526                 :             : !C   REORDER SOLUTION ACCORDING TO PREVIOUS COLUMN INTERCHANGES
    1527                 :             : 
    1528         [ #  # ]:           0 :   240     DO 249 j=ldiag,1,-1
    1529         [ #  # ]:           0 :               IF(ip(j).EQ.j)          GOTO 249
    1530                 :           0 :               l=ip(j)
    1531                 :           0 :               tmp=b(l,jb)
    1532                 :           0 :               b(l,jb)=b(j,jb)
    1533                 :           0 :               b(j,jb)=tmp
    1534                 :           0 :   249     CONTINUE
    1535                 :           0 :   250 CONTINUE
    1536                 :           0 :   270 krank=k
    1537                 :           0 :       END SUBROUTINE hfti
    1538                 :             : 
    1539                 :           0 :       SUBROUTINE h12 (mode,lpivot,l1,m,u,iue,up,c,ice,icv,ncv)
    1540                 :             : 
    1541                 :             : !C     C.L.LAWSON AND R.J.HANSON, JET PROPULSION LABORATORY, 1973 JUN 12
    1542                 :             : !C     TO APPEAR IN 'SOLVING LEAST SQUARES PROBLEMS', PRENTICE-HALL, 1974
    1543                 :             : 
    1544                 :             : !C     CONSTRUCTION AND/OR APPLICATION OF A SINGLE
    1545                 :             : !C     HOUSEHOLDER TRANSFORMATION  Q = I + U*(U**T)/B
    1546                 :             : 
    1547                 :             : !C     MODE    = 1 OR 2   TO SELECT ALGORITHM  H1  OR  H2 .
    1548                 :             : !C     LPIVOT IS THE INDEX OF THE PIVOT ELEMENT.
    1549                 :             : !C     L1,M   IF L1 <= M   THE TRANSFORMATION WILL BE CONSTRUCTED TO
    1550                 :             : !C            ZERO ELEMENTS INDEXED FROM L1 THROUGH M.
    1551                 :             : !C            IF L1 > M THE SUBROUTINE DOES AN IDENTITY TRANSFORMATION.
    1552                 :             : !C     U(),IUE,UP
    1553                 :             : !C            ON ENTRY TO H1 U() STORES THE PIVOT VECTOR.
    1554                 :             : !C            IUE IS THE STORAGE INCREMENT BETWEEN ELEMENTS.
    1555                 :             : !C            ON EXIT FROM H1 U() AND UP STORE QUANTITIES DEFINING
    1556                 :             : !C            THE VECTOR U OF THE HOUSEHOLDER TRANSFORMATION.
    1557                 :             : !C            ON ENTRY TO H2 U() AND UP
    1558                 :             : !C            SHOULD STORE QUANTITIES PREVIOUSLY COMPUTED BY H1.
    1559                 :             : !C            THESE WILL NOT BE MODIFIED BY H2.
    1560                 :             : !C     C()    ON ENTRY TO H1 OR H2 C() STORES A MATRIX WHICH WILL BE
    1561                 :             : !C            REGARDED AS A SET OF VECTORS TO WHICH THE HOUSEHOLDER
    1562                 :             : !C            TRANSFORMATION IS TO BE APPLIED.
    1563                 :             : !C            ON EXIT C() STORES THE SET OF TRANSFORMED VECTORS.
    1564                 :             : !C     ICE    STORAGE INCREMENT BETWEEN ELEMENTS OF VECTORS IN C().
    1565                 :             : !C     ICV    STORAGE INCREMENT BETWEEN VECTORS IN C().
    1566                 :             : !C     NCV    NUMBER OF VECTORS IN C() TO BE TRANSFORMED.
    1567                 :             : !C            IF NCV <= 0 NO OPERATIONS WILL BE DONE ON C().
    1568                 :             : 
    1569                 :             :       INTEGER          incr, ice, icv, iue, lpivot, l1, mode, ncv
    1570                 :             :       INTEGER          i, i2, i3, i4, j, m
    1571                 :             :       DOUBLE PRECISION u,up,c,cl,clinv,b,sm,one,ZERO
    1572                 :             :       DIMENSION        u(iue,*), c(*)
    1573                 :             :       DATA             one/1.0d+00/, ZERO/0.0d+00/
    1574                 :             : 
    1575   [ #  #  #  #  :           0 :       IF (0.GE.lpivot.OR.lpivot.GE.l1.OR.l1.GT.m) GOTO 80
                   #  # ]
    1576                 :           0 :       cl=ABS(u(1,lpivot))
    1577         [ #  # ]:           0 :       IF (mode.EQ.2)                              GOTO 30
    1578                 :             : 
    1579                 :             : !C     ****** CONSTRUCT THE TRANSFORMATION ******
    1580                 :             : 
    1581         [ #  # ]:           0 :           DO 10 j=l1,m
    1582                 :           0 :              sm=ABS(u(1,j))
    1583                 :           0 :           cl=MAX(sm,cl)
    1584                 :           0 :    10     CONTINUE
    1585         [ #  # ]:           0 :       IF (cl.LE.ZERO)                             GOTO 80
    1586                 :           0 :       clinv=one/cl
    1587                 :           0 :       sm=(u(1,lpivot)*clinv)**2
    1588         [ #  # ]:           0 :           DO 20 j=l1,m
    1589                 :           0 :           sm=sm+(u(1,j)*clinv)**2
    1590                 :           0 :    20     CONTINUE
    1591                 :           0 :       cl=cl*SQRT(sm)
    1592         [ #  # ]:           0 :       IF (u(1,lpivot).GT.ZERO) cl=-cl
    1593                 :           0 :       up=u(1,lpivot)-cl
    1594                 :           0 :       u(1,lpivot)=cl
    1595                 :           0 :                                                   GOTO 40
    1596                 :             : !C     ****** APPLY THE TRANSFORMATION  I+U*(U**T)/B  TO C ******
    1597                 :             : 
    1598         [ #  # ]:           0 :    30 IF (cl.LE.ZERO)                             GOTO 80
    1599         [ #  # ]:           0 :    40 IF (ncv.LE.0)                               GOTO 80
    1600                 :           0 :       b=up*u(1,lpivot)
    1601         [ #  # ]:           0 :       IF (b.GE.ZERO)                              GOTO 80
    1602                 :           0 :       b=one/b
    1603                 :           0 :       i2=1-icv+ice*(lpivot-1)
    1604                 :           0 :       incr=ice*(l1-lpivot)
    1605         [ #  # ]:           0 :           DO 70 j=1,ncv
    1606                 :           0 :           i2=i2+icv
    1607                 :           0 :           i3=i2+incr
    1608                 :           0 :           i4=i3
    1609                 :           0 :           sm=c(i2)*up
    1610         [ #  # ]:           0 :               DO 50 i=l1,m
    1611                 :           0 :               sm=sm+c(i3)*u(1,i)
    1612                 :           0 :               i3=i3+ice
    1613                 :           0 :    50         CONTINUE
    1614         [ #  # ]:           0 :           IF (sm.EQ.ZERO)                         GOTO 70
    1615                 :           0 :           sm=sm*b
    1616                 :           0 :           c(i2)=c(i2)+sm*up
    1617         [ #  # ]:           0 :               DO 60 i=l1,m
    1618                 :           0 :               c(i4)=c(i4)+sm*u(1,i)
    1619                 :           0 :               i4=i4+ice
    1620                 :           0 :    60         CONTINUE
    1621                 :           0 :    70     CONTINUE
    1622                 :             :    80     CONTINUE
    1623                 :             : 
    1624                 :           0 :       END SUBROUTINE h12
    1625                 :             : 
    1626                 :           0 :       SUBROUTINE ldl (n,a,z,sigma,w)
    1627                 :             : !C   LDL     LDL' - RANK-ONE - UPDATE
    1628                 :             : 
    1629                 :             : !C   PURPOSE:
    1630                 :             : !C           UPDATES THE LDL' FACTORS OF MATRIX A BY RANK-ONE MATRIX
    1631                 :             : !C           SIGMA*Z*Z'
    1632                 :             : 
    1633                 :             : !C   INPUT ARGUMENTS: (* MEANS PARAMETERS ARE CHANGED DURING EXECUTION)
    1634                 :             : !C     N     : ORDER OF THE COEFFICIENT MATRIX A
    1635                 :             : !C   * A     : POSITIVE DEFINITE MATRIX OF DIMENSION N;
    1636                 :             : !C             ONLY THE LOWER TRIANGLE IS USED AND IS STORED COLUMN BY
    1637                 :             : !C             COLUMN AS ONE DIMENSIONAL ARRAY OF DIMENSION N*(N+1)/2.
    1638                 :             : !C   * Z     : VECTOR OF DIMENSION N OF UPDATING ELEMENTS
    1639                 :             : !C     SIGMA : SCALAR FACTOR BY WHICH THE MODIFYING DYADE Z*Z' IS
    1640                 :             : !C             MULTIPLIED
    1641                 :             : 
    1642                 :             : !C   OUTPUT ARGUMENTS:
    1643                 :             : !C     A     : UPDATED LDL' FACTORS
    1644                 :             : 
    1645                 :             : !C   WORKING ARRAY:
    1646                 :             : !C     W     : VECTOR OP DIMENSION N (USED ONLY IF SIGMA .LT. ZERO)
    1647                 :             : 
    1648                 :             : !C   METHOD:
    1649                 :             : !C     THAT OF FLETCHER AND POWELL AS DESCRIBED IN :
    1650                 :             : !C     FLETCHER,R.,(1974) ON THE MODIFICATION OF LDL' FACTORIZATION.
    1651                 :             : !C     POWELL,M.J.D.      MATH.COMPUTATION 28, 1067-1078.
    1652                 :             : 
    1653                 :             : !C   IMPLEMENTED BY:
    1654                 :             : !C     KRAFT,D., DFVLR - INSTITUT FUER DYNAMIK DER FLUGSYSTEME
    1655                 :             : !C               D-8031  OBERPFAFFENHOFEN
    1656                 :             : 
    1657                 :             : !C   STATUS: 15. JANUARY 1980
    1658                 :             : 
    1659                 :             : !C   SUBROUTINES REQUIRED: NONE
    1660                 :             : 
    1661                 :             :       INTEGER          i, ij, j, n
    1662                 :             :       DOUBLE PRECISION a(*), t, v, w(*), z(*), u, tp, one, beta, four,&
    1663                 :             :                        ZERO, alpha, delta, gamma, sigma, epmach
    1664                 :             :       DATA ZERO, one, four, epmach /0.0d0, 1.0d0, 4.0d0, 2.22d-16/
    1665                 :             : 
    1666         [ #  # ]:           0 :       IF(sigma.EQ.ZERO)               GOTO 280
    1667                 :           0 :       ij=1
    1668                 :           0 :       t=one/sigma
    1669         [ #  # ]:           0 :       IF(sigma.GT.ZERO)               GOTO 220
    1670                 :             : !C PREPARE NEGATIVE UPDATE
    1671         [ #  # ]:           0 :       DO 150 i=1,n
    1672                 :           0 :           w(i)=z(i)
    1673                 :           0 :   150 CONTINUE
    1674         [ #  # ]:           0 :       DO 170 i=1,n
    1675                 :           0 :           v=w(i)
    1676                 :           0 :           t=t+v*v/a(ij)
    1677         [ #  # ]:           0 :           DO 160 j=i+1,n
    1678                 :           0 :               ij=ij+1
    1679                 :           0 :               w(j)=w(j)-v*a(ij)
    1680                 :           0 :   160     CONTINUE
    1681                 :           0 :           ij=ij+1
    1682                 :           0 :   170 CONTINUE
    1683         [ #  # ]:           0 :       IF(t.GE.ZERO) t=epmach/sigma
    1684         [ #  # ]:           0 :       DO 210 i=1,n
    1685                 :           0 :           j=n+1-i
    1686                 :           0 :           ij=ij-i
    1687                 :           0 :           u=w(j)
    1688                 :           0 :           w(j)=t
    1689                 :           0 :           t=t-u*u/a(ij)
    1690                 :           0 :   210 CONTINUE
    1691                 :             :   220 CONTINUE
    1692                 :             : !C HERE UPDATING BEGINS
    1693         [ #  # ]:           0 :       DO 270 i=1,n
    1694                 :           0 :           v=z(i)
    1695                 :           0 :           delta=v/a(ij)
    1696         [ #  # ]:           0 :           IF(sigma.LT.ZERO) tp=w(i)
    1697         [ #  # ]:           0 :           IF(sigma.GT.ZERO) tp=t+delta*v
    1698                 :           0 :           alpha=tp/t
    1699                 :           0 :           a(ij)=alpha*a(ij)
    1700         [ #  # ]:           0 :           IF(i.EQ.n)                  GOTO 280
    1701                 :           0 :           beta=delta/tp
    1702         [ #  # ]:           0 :           IF(alpha.GT.four)           GOTO 240
    1703         [ #  # ]:           0 :           DO 230 j=i+1,n
    1704                 :           0 :               ij=ij+1
    1705                 :           0 :               z(j)=z(j)-v*a(ij)
    1706                 :           0 :               a(ij)=a(ij)+beta*z(j)
    1707                 :           0 :   230     CONTINUE
    1708                 :           0 :                                       GOTO 260
    1709                 :           0 :   240     gamma=t/tp
    1710         [ #  # ]:           0 :           DO 250 j=i+1,n
    1711                 :           0 :               ij=ij+1
    1712                 :           0 :               u=a(ij)
    1713                 :           0 :               a(ij)=gamma*u+beta*z(j)
    1714                 :           0 :               z(j)=z(j)-v*u
    1715                 :           0 :   250     CONTINUE
    1716                 :           0 :   260     ij=ij+1
    1717                 :           0 :           t=tp
    1718                 :           0 :   270 CONTINUE
    1719                 :           0 :   280 RETURN
    1720                 :             : !C END OF LDL
    1721                 :             :       END SUBROUTINE ldl
    1722                 :             : 
    1723                 :           0 :       DOUBLE PRECISION FUNCTION linmin (mode, ax, bx, f, tol)
    1724                 :             : !C   LINMIN  LINESEARCH WITHOUT DERIVATIVES
    1725                 :             : 
    1726                 :             : !C   PURPOSE:
    1727                 :             : 
    1728                 :             : !C  TO FIND THE ARGUMENT LINMIN WHERE THE FUNCTION F TAKES IT'S MINIMUM
    1729                 :             : !C  ON THE INTERVAL AX, BX.
    1730                 :             : !C  COMBINATION OF GOLDEN SECTION AND SUCCESSIVE QUADRATIC INTERPOLATION.
    1731                 :             : 
    1732                 :             : !C   INPUT ARGUMENTS: (* MEANS PARAMETERS ARE CHANGED DURING EXECUTION)
    1733                 :             : 
    1734                 :             : !C *MODE   SEE OUTPUT ARGUMENTS
    1735                 :             : !C  AX     LEFT ENDPOINT OF INITIAL INTERVAL
    1736                 :             : !C  BX     RIGHT ENDPOINT OF INITIAL INTERVAL
    1737                 :             : !C  F      FUNCTION VALUE AT LINMIN WHICH IS TO BE BROUGHT IN BY
    1738                 :             : !C         REVERSE COMMUNICATION CONTROLLED BY MODE
    1739                 :             : !C  TOL    DESIRED LENGTH OF INTERVAL OF UNCERTAINTY OF FINAL RESULT
    1740                 :             : 
    1741                 :             : !C   OUTPUT ARGUMENTS:
    1742                 :             : 
    1743                 :             : !C  LINMIN ABSCISSA APPROXIMATING THE POINT WHERE F ATTAINS A MINIMUM
    1744                 :             : !C  MODE   CONTROLS REVERSE COMMUNICATION
    1745                 :             : !C         MUST BE SET TO 0 INITIALLY, RETURNS WITH INTERMEDIATE
    1746                 :             : !C         VALUES 1 AND 2 WHICH MUST NOT BE CHANGED BY THE USER,
    1747                 :             : !C         ENDS WITH CONVERGENCE WITH VALUE 3.
    1748                 :             : 
    1749                 :             : !C   WORKING ARRAY:
    1750                 :             : 
    1751                 :             : !C  NONE
    1752                 :             : 
    1753                 :             : !C   METHOD:
    1754                 :             : 
    1755                 :             : !C  THIS FUNCTION SUBPROGRAM IS A SLIGHTLY MODIFIED VERSION OF THE
    1756                 :             : !C  ALGOL 60 PROCEDURE LOCALMIN GIVEN IN
    1757                 :             : !C  R.P. BRENT: ALGORITHMS FOR MINIMIZATION WITHOUT DERIVATIVES,
    1758                 :             : !C              PRENTICE-HALL (1973).
    1759                 :             : 
    1760                 :             : !C   IMPLEMENTED BY:
    1761                 :             : 
    1762                 :             : !C     KRAFT, D., DFVLR - INSTITUT FUER DYNAMIK DER FLUGSYSTEME
    1763                 :             : !C                D-8031  OBERPFAFFENHOFEN
    1764                 :             : 
    1765                 :             : !C   STATUS: 31. AUGUST  1984
    1766                 :             : 
    1767                 :             : !C   SUBROUTINES REQUIRED: NONE
    1768                 :             : 
    1769                 :             :       INTEGER          mode
    1770                 :             :       DOUBLE PRECISION f, tol, a, b, c, d, e, p, q, r, u, v, w, x, m,&
    1771                 :             :      &                 fu, fv, fw, fx, eps, tol1, tol2, ZERO, ax, bx
    1772                 :             :       DATA             c /0.381966011d0/, eps /1.5d-8/, ZERO /0.0d0/
    1773                 :             : 
    1774                 :             : !C  EPS = SQUARE - ROOT OF MACHINE PRECISION
    1775                 :             : !C  C = GOLDEN SECTION RATIO = (3-SQRT(5))/2
    1776                 :             : 
    1777      [ #  #  # ]:           0 :       GOTO (10, 55), mode
    1778                 :             : 
    1779                 :             : !C  INITIALIZATION
    1780                 :             : 
    1781                 :           0 :       a = ax
    1782                 :           0 :       b = bx
    1783                 :           0 :       e = ZERO
    1784                 :           0 :       v = a + c*(b - a)
    1785                 :           0 :       w = v
    1786                 :           0 :       x = w
    1787                 :           0 :       linmin = x
    1788                 :           0 :       mode = 1
    1789                 :           0 :       GOTO 100
    1790                 :             : 
    1791                 :             : !C  MAIN LOOP STARTS HERE
    1792                 :             : 
    1793                 :           0 :    10 fx = f
    1794                 :           0 :       fv = fx
    1795                 :           0 :       fw = fv
    1796                 :           0 :    20 m = 0.5d0*(a + b)
    1797                 :           0 :       tol1 = eps*ABS(x) + tol
    1798                 :           0 :       tol2 = tol1 + tol1
    1799                 :             : 
    1800                 :             : !C  TEST CONVERGENCE
    1801                 :             : 
    1802         [ #  # ]:           0 :       IF (ABS(x - m) .LE. tol2 - 0.5d0*(b - a)) GOTO 90
    1803                 :           0 :       r = ZERO
    1804                 :           0 :       q = r
    1805                 :           0 :       p = q
    1806         [ #  # ]:           0 :       IF (ABS(e) .LE. tol1) GOTO 30
    1807                 :             : 
    1808                 :             : !C  FIT PARABOLA
    1809                 :             : 
    1810                 :           0 :       r = (x - w)*(fx - fv)
    1811                 :           0 :       q = (x - v)*(fx - fw)
    1812                 :           0 :       p = (x - v)*q - (x - w)*r
    1813                 :           0 :       q = q - r
    1814                 :           0 :       q = q + q
    1815         [ #  # ]:           0 :       IF (q .GT. ZERO) p = -p
    1816         [ #  # ]:           0 :       IF (q .LT. ZERO) q = -q
    1817                 :             :       r = e
    1818                 :           0 :       e = d
    1819                 :             : 
    1820                 :             : !C  IS PARABOLA ACCEPTABLE
    1821                 :             : 
    1822                 :             :    30 IF (ABS(p) .GE. 0.5d0*ABS(q*r) .OR.&
    1823   [ #  #  #  #  :           0 :      &    p .LE. q*(a - x) .OR. p .GE. q*(b-x)) GOTO 40
                   #  # ]
    1824                 :             : 
    1825                 :             : !C  PARABOLIC INTERPOLATION STEP
    1826                 :             : 
    1827                 :           0 :       d = p/q
    1828                 :             : 
    1829                 :             : !C  F MUST NOT BE EVALUATED TOO CLOSE TO A OR B
    1830                 :             : 
    1831         [ #  # ]:           0 :       IF (u - a .LT. tol2) d = SIGN(tol1, m - x)
    1832         [ #  # ]:           0 :       IF (b - u .LT. tol2) d = SIGN(tol1, m - x)
    1833                 :           0 :       GOTO 50
    1834                 :             : 
    1835                 :             : !C  GOLDEN SECTION STEP
    1836                 :             : 
    1837         [ #  # ]:           0 :    40 IF (x .GE. m) e = a - x
    1838         [ #  # ]:           0 :       IF (x .LT. m) e = b - x
    1839                 :           0 :       d = c*e
    1840                 :             : 
    1841                 :             : !C  F MUST NOT BE EVALUATED TOO CLOSE TO X
    1842                 :             : 
    1843         [ #  # ]:           0 :    50 IF (ABS(d) .LT. tol1) d = SIGN(tol1, d)
    1844                 :           0 :       u = x + d
    1845                 :           0 :       linmin = u
    1846                 :           0 :       mode = 2
    1847                 :           0 :       GOTO 100
    1848                 :           0 :    55 fu = f
    1849                 :             : 
    1850                 :             : !C  UPDATE A, B, V, W, AND X
    1851                 :             : 
    1852         [ #  # ]:           0 :       IF (fu .GT. fx) GOTO 60
    1853                 :             :       IF (u .GE. x) a = x
    1854                 :             :       IF (u .LT. x) b = x
    1855                 :             :       v = w
    1856                 :             :       fv = fw
    1857                 :             :       w = x
    1858                 :             :       fw = fx
    1859                 :             :       x = u
    1860                 :             :       fx = fu
    1861                 :           0 :       GOTO 85
    1862                 :             :    60 IF (u .LT. x) a = u
    1863                 :             :       IF (u .GE. x) b = u
    1864   [ #  #  #  # ]:           0 :       IF (fu .LE. fw .OR. w .EQ. x) GOTO 70
    1865   [ #  #  #  # ]:           0 :       IF (fu .LE. fv .OR. v .EQ. x .OR. v .EQ. w) GOTO 80
    1866                 :           0 :       GOTO 85
    1867                 :             :    70 v = w
    1868                 :             :       fv = fw
    1869                 :             :       w = u
    1870                 :             :       fw = fu
    1871                 :           0 :       GOTO 85
    1872                 :           0 :    80 v = u
    1873                 :           0 :       fv = fu
    1874                 :           0 :    85 GOTO 20
    1875                 :             : 
    1876                 :             : !C  END OF MAIN LOOP
    1877                 :             : 
    1878                 :           0 :    90 linmin = x
    1879                 :           0 :       mode = 3
    1880                 :             :   100 RETURN
    1881                 :             : 
    1882                 :             : !C  END OF LINMIN
    1883                 :             : 
    1884                 :             :       END FUNCTION linmin
    1885                 :             : 
    1886                 :             : !C## Following a selection from BLAS Level 1
    1887                 :             : 
    1888                 :           0 :       SUBROUTINE daxpy_sl(n,da,dx,incx,dy,incy)
    1889                 :             : 
    1890                 :             : !C     CONSTANT TIMES A VECTOR PLUS A VECTOR.
    1891                 :             : !C     USES UNROLLED LOOPS FOR INCREMENTS EQUAL TO ONE.
    1892                 :             : !C     JACK DONGARRA, LINPACK, 3/11/78.
    1893                 :             : 
    1894                 :             :       DOUBLE PRECISION dx(*),dy(*),da
    1895                 :             :       INTEGER i,incx,incy,ix,iy,m,mp1,n
    1896                 :             : 
    1897         [ #  # ]:           0 :       IF(n.LE.0)RETURN
    1898         [ #  # ]:           0 :       IF(da.EQ.0.0d0)RETURN
    1899   [ #  #  #  # ]:           0 :       IF(incx.EQ.1.AND.incy.EQ.1)GO TO 20
    1900                 :             : 
    1901                 :             : !C        CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS
    1902                 :             : !C        NOT EQUAL TO 1
    1903                 :             : 
    1904                 :           0 :       ix = 1
    1905                 :           0 :       iy = 1
    1906         [ #  # ]:           0 :       IF(incx.LT.0)ix = (-n+1)*incx + 1
    1907         [ #  # ]:           0 :       IF(incy.LT.0)iy = (-n+1)*incy + 1
    1908         [ #  # ]:           0 :       DO 10 i = 1,n
    1909                 :           0 :         dy(iy) = dy(iy) + da*dx(ix)
    1910                 :           0 :         ix = ix + incx
    1911                 :           0 :         iy = iy + incy
    1912                 :           0 :    10 CONTINUE
    1913                 :           0 :       RETURN
    1914                 :             : 
    1915                 :             : !C        CODE FOR BOTH INCREMENTS EQUAL TO 1
    1916                 :             : 
    1917                 :             : !C        CLEAN-UP LOOP
    1918                 :             : 
    1919                 :           0 :    20 m = MOD(n,4)
    1920         [ #  # ]:           0 :       IF( m .EQ. 0 ) GO TO 40
    1921         [ #  # ]:           0 :       DO 30 i = 1,m
    1922                 :           0 :         dy(i) = dy(i) + da*dx(i)
    1923                 :           0 :    30 CONTINUE
    1924         [ #  # ]:           0 :       IF( n .LT. 4 ) RETURN
    1925                 :           0 :    40 mp1 = m + 1
    1926         [ #  # ]:           0 :       DO 50 i = mp1,n,4
    1927                 :           0 :         dy(i) = dy(i) + da*dx(i)
    1928                 :           0 :         dy(i + 1) = dy(i + 1) + da*dx(i + 1)
    1929                 :           0 :         dy(i + 2) = dy(i + 2) + da*dx(i + 2)
    1930         [ #  # ]:           0 :         dy(i + 3) = dy(i + 3) + da*dx(i + 3)
    1931                 :           0 :    50 CONTINUE
    1932                 :             :       RETURN
    1933                 :             :       END SUBROUTINE daxpy_sl
    1934                 :             : 
    1935                 :           0 :       SUBROUTINE  dcopy_(n,dx,incx,dy,incy)
    1936                 :             : 
    1937                 :             : !C     COPIES A VECTOR, X, TO A VECTOR, Y.
    1938                 :             : !C     USES UNROLLED LOOPS FOR INCREMENTS EQUAL TO ONE.
    1939                 :             : !C     JACK DONGARRA, LINPACK, 3/11/78.
    1940                 :             : 
    1941                 :             :       DOUBLE PRECISION dx(*),dy(*)
    1942                 :             :       INTEGER i,incx,incy,ix,iy,m,mp1,n
    1943                 :             : 
    1944         [ #  # ]:           0 :       IF(n.LE.0)RETURN
    1945   [ #  #  #  # ]:           0 :       IF(incx.EQ.1.AND.incy.EQ.1)GO TO 20
    1946                 :             : 
    1947                 :             : !C        CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS
    1948                 :             : !C        NOT EQUAL TO 1
    1949                 :             : 
    1950                 :           0 :       ix = 1
    1951                 :           0 :       iy = 1
    1952         [ #  # ]:           0 :       IF(incx.LT.0)ix = (-n+1)*incx + 1
    1953         [ #  # ]:           0 :       IF(incy.LT.0)iy = (-n+1)*incy + 1
    1954         [ #  # ]:           0 :       DO 10 i = 1,n
    1955                 :           0 :         dy(iy) = dx(ix)
    1956                 :           0 :         ix = ix + incx
    1957                 :           0 :         iy = iy + incy
    1958                 :           0 :    10 CONTINUE
    1959                 :           0 :       RETURN
    1960                 :             : 
    1961                 :             : !C        CODE FOR BOTH INCREMENTS EQUAL TO 1
    1962                 :             : 
    1963                 :             : !C        CLEAN-UP LOOP
    1964                 :             : 
    1965                 :           0 :    20 m = MOD(n,7)
    1966         [ #  # ]:           0 :       IF( m .EQ. 0 ) GO TO 40
    1967         [ #  # ]:           0 :       DO 30 i = 1,m
    1968                 :           0 :         dy(i) = dx(i)
    1969                 :           0 :    30 CONTINUE
    1970         [ #  # ]:           0 :       IF( n .LT. 7 ) RETURN
    1971                 :           0 :    40 mp1 = m + 1
    1972         [ #  # ]:           0 :       DO 50 i = mp1,n,7
    1973                 :           0 :         dy(i) = dx(i)
    1974                 :           0 :         dy(i + 1) = dx(i + 1)
    1975                 :           0 :         dy(i + 2) = dx(i + 2)
    1976                 :           0 :         dy(i + 3) = dx(i + 3)
    1977                 :           0 :         dy(i + 4) = dx(i + 4)
    1978                 :           0 :         dy(i + 5) = dx(i + 5)
    1979         [ #  # ]:           0 :         dy(i + 6) = dx(i + 6)
    1980                 :           0 :    50 CONTINUE
    1981                 :             :       RETURN
    1982                 :             :       END SUBROUTINE dcopy_
    1983                 :             : 
    1984                 :           0 :       DOUBLE PRECISION FUNCTION ddot_sl(n,dx,incx,dy,incy)
    1985                 :             : 
    1986                 :             : !C     FORMS THE DOT PRODUCT OF TWO VECTORS.
    1987                 :             : !C     USES UNROLLED LOOPS FOR INCREMENTS EQUAL TO ONE.
    1988                 :             : !C     JACK DONGARRA, LINPACK, 3/11/78.
    1989                 :             : 
    1990                 :             :       DOUBLE PRECISION dx(*),dy(*),dtemp
    1991                 :             :       INTEGER i,incx,incy,ix,iy,m,mp1,n
    1992                 :             : 
    1993                 :           0 :       ddot_sl = 0.0d0
    1994                 :           0 :       dtemp = 0.0d0
    1995         [ #  # ]:           0 :       IF(n.LE.0)RETURN
    1996   [ #  #  #  # ]:           0 :       IF(incx.EQ.1.AND.incy.EQ.1)GO TO 20
    1997                 :             : 
    1998                 :             : !C        CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS
    1999                 :             : !C          NOT EQUAL TO 1
    2000                 :             : 
    2001                 :           0 :       ix = 1
    2002                 :           0 :       iy = 1
    2003         [ #  # ]:           0 :       IF(incx.LT.0)ix = (-n+1)*incx + 1
    2004         [ #  # ]:           0 :       IF(incy.LT.0)iy = (-n+1)*incy + 1
    2005         [ #  # ]:           0 :       DO 10 i = 1,n
    2006                 :           0 :         dtemp = dtemp + dx(ix)*dy(iy)
    2007                 :           0 :         ix = ix + incx
    2008                 :           0 :         iy = iy + incy
    2009                 :           0 :    10 CONTINUE
    2010                 :           0 :       ddot_sl = dtemp
    2011                 :           0 :       RETURN
    2012                 :             : 
    2013                 :             : !C        CODE FOR BOTH INCREMENTS EQUAL TO 1
    2014                 :             : 
    2015                 :             : !C        CLEAN-UP LOOP
    2016                 :             : 
    2017                 :           0 :    20 m = MOD(n,5)
    2018         [ #  # ]:           0 :       IF( m .EQ. 0 ) GO TO 40
    2019         [ #  # ]:           0 :       DO 30 i = 1,m
    2020                 :           0 :         dtemp = dtemp + dx(i)*dy(i)
    2021                 :           0 :    30 CONTINUE
    2022         [ #  # ]:           0 :       IF( n .LT. 5 ) GO TO 60
    2023                 :           0 :    40 mp1 = m + 1
    2024         [ #  # ]:           0 :       DO 50 i = mp1,n,5
    2025                 :             :         dtemp = dtemp + dx(i)*dy(i) + dx(i + 1)*dy(i + 1) + &
    2026         [ #  # ]:           0 :          dx(i + 2)*dy(i + 2) + dx(i + 3)*dy(i + 3) + dx(i + 4)*dy(i + 4)
    2027                 :           0 :    50 CONTINUE
    2028                 :             :    60 ddot_sl = dtemp
    2029                 :             :       RETURN
    2030                 :             :       END FUNCTION ddot_sl
    2031                 :             : 
    2032                 :             :       DOUBLE PRECISION FUNCTION dnrm1(n,x,i,j)
    2033                 :             :       INTEGER n, i, j, k
    2034                 :             :       DOUBLE PRECISION snormx, sum, x(n), ZERO, one, scale, temp
    2035                 :             :       DATA ZERO/0.0d0/, one/1.0d0/
    2036                 :             : 
    2037                 :             : !C      DNRM1 - COMPUTES THE I-NORM OF A VECTOR
    2038                 :             : !C              BETWEEN THE ITH AND THE JTH ELEMENTS
    2039                 :             : 
    2040                 :             : !C      INPUT -
    2041                 :             : !C      N       LENGTH OF VECTOR
    2042                 :             : !C      X       VECTOR OF LENGTH N
    2043                 :             : !C      I       INITIAL ELEMENT OF VECTOR TO BE USED
    2044                 :             : !C      J       FINAL ELEMENT TO USE
    2045                 :             : 
    2046                 :             : !C      OUTPUT -
    2047                 :             : !C      DNRM1   NORM
    2048                 :             : 
    2049                 :             :       snormx=ZERO
    2050                 :             :       DO 10 k=i,j
    2051                 :             :          snormx=MAX(snormx,ABS(x(k)))
    2052                 :             :  10   CONTINUE
    2053                 :             :       dnrm1 = snormx
    2054                 :             :       IF (snormx.EQ.ZERO) RETURN
    2055                 :             :       scale = snormx
    2056                 :             :       IF (snormx.GE.one) scale=SQRT(snormx)
    2057                 :             :       sum=ZERO
    2058                 :             :       DO 20 k=i,j
    2059                 :             :          temp=ZERO
    2060                 :             :          IF (ABS(x(k))+scale .NE. scale) temp = x(k)/snormx
    2061                 :             :          IF (one+temp.NE.one) sum = sum+temp*temp
    2062                 :             :  20      CONTINUE
    2063                 :             :       sum=SQRT(sum)
    2064                 :             :       dnrm1=snormx*sum
    2065                 :             :       RETURN
    2066                 :             :       END FUNCTION dnrm1
    2067                 :             : 
    2068                 :           0 :       DOUBLE PRECISION FUNCTION dnrm2_ ( n, dx, incx)
    2069                 :             :       INTEGER          n, i, j, nn, next, incx
    2070                 :             :       DOUBLE PRECISION dx(*), cutlo, cuthi, hitest, sum, xmax, ZERO, one
    2071                 :             :       DATA             ZERO, one /0.0d0, 1.0d0/
    2072                 :             : 
    2073                 :             : !C     EUCLIDEAN NORM OF THE N-VECTOR STORED IN DX() WITH STORAGE
    2074                 :             : !C     INCREMENT INCX .
    2075                 :             : !C     IF    N .LE. 0 RETURN WITH RESULT = 0.
    2076                 :             : !C     IF N .GE. 1 THEN INCX MUST BE .GE. 1
    2077                 :             : 
    2078                 :             : !C           C.L.LAWSON, 1978 JAN 08
    2079                 :             : 
    2080                 :             : !C     FOUR PHASE METHOD     USING TWO BUILT-IN CONSTANTS THAT ARE
    2081                 :             : !C     HOPEFULLY APPLICABLE TO ALL MACHINES.
    2082                 :             : !C         CUTLO = MAXIMUM OF  SQRT(U/EPS)   OVER ALL KNOWN MACHINES.
    2083                 :             : !C         CUTHI = MINIMUM OF  SQRT(V)       OVER ALL KNOWN MACHINES.
    2084                 :             : !C     WHERE
    2085                 :             : !C         EPS = SMALLEST NO. SUCH THAT EPS + 1. .GT. 1.
    2086                 :             : !C         U   = SMALLEST POSITIVE NO.   (UNDERFLOW LIMIT)
    2087                 :             : !C         V   = LARGEST  NO.            (OVERFLOW  LIMIT)
    2088                 :             : 
    2089                 :             : !C     BRIEF OUTLINE OF ALGORITHM..
    2090                 :             : 
    2091                 :             : !C     PHASE 1    SCANS ZERO COMPONENTS.
    2092                 :             : !C     MOVE TO PHASE 2 WHEN A COMPONENT IS NONZERO AND .LE. CUTLO
    2093                 :             : !C     MOVE TO PHASE 3 WHEN A COMPONENT IS .GT. CUTLO
    2094                 :             : !C     MOVE TO PHASE 4 WHEN A COMPONENT IS .GE. CUTHI/M
    2095                 :             : !C     WHERE M = N FOR X() REAL AND M = 2*N FOR COMPLEX.
    2096                 :             : 
    2097                 :             : !C     VALUES FOR CUTLO AND CUTHI..
    2098                 :             : !C     FROM THE ENVIRONMENTAL PARAMETERS LISTED IN THE IMSL CONVERTER
    2099                 :             : !C     DOCUMENT THE LIMITING VALUES ARE AS FOLLOWS..
    2100                 :             : !C     CUTLO, S.P.   U/EPS = 2**(-102) FOR  HONEYWELL.  CLOSE SECONDS ARE
    2101                 :             : !C                   UNIVAC AND DEC AT 2**(-103)
    2102                 :             : !C                   THUS CUTLO = 2**(-51) = 4.44089E-16
    2103                 :             : !C     CUTHI, S.P.   V = 2**127 FOR UNIVAC, HONEYWELL, AND DEC.
    2104                 :             : !C                   THUS CUTHI = 2**(63.5) = 1.30438E19
    2105                 :             : !C     CUTLO, D.P.   U/EPS = 2**(-67) FOR HONEYWELL AND DEC.
    2106                 :             : !C                   THUS CUTLO = 2**(-33.5) = 8.23181D-11
    2107                 :             : !C     CUTHI, D.P.   SAME AS S.P.  CUTHI = 1.30438D19
    2108                 :             : !C     DATA CUTLO, CUTHI / 8.232D-11,  1.304D19 /
    2109                 :             : !C     DATA CUTLO, CUTHI / 4.441E-16,  1.304E19 /
    2110                 :             :       DATA cutlo, cuthi / 8.232d-11,  1.304d19 /
    2111                 :             : 
    2112         [ #  # ]:           0 :       IF(n .GT. 0) GO TO 10
    2113                 :           0 :          dnrm2_  = ZERO
    2114                 :           0 :          GO TO 300
    2115                 :             : 
    2116                 :           0 :    10 next = 30
    2117                 :           0 :       sum = ZERO
    2118                 :           0 :       nn = n * incx
    2119                 :             : !C                       BEGIN MAIN LOOP
    2120                 :           0 :       i = 1
    2121         [ #  # ]:           0 :    20 IF( next .EQ. 30) GO TO 30
    2122         [ #  # ]:           0 :       IF( next .EQ. 50) GO TO 50
    2123         [ #  # ]:           0 :       IF( next .EQ. 70) GO TO 70
    2124                 :             :       IF( next .EQ. 110) GO TO 110
    2125         [ #  # ]:           0 :    30 IF( ABS(dx(i)) .GT. cutlo) GO TO 85
    2126                 :             :       next = 50
    2127                 :           0 :       xmax = ZERO
    2128                 :             : 
    2129                 :             : !C                        PHASE 1.  SUM IS ZERO
    2130                 :             : 
    2131         [ #  # ]:           0 :    50 IF( dx(i) .EQ. ZERO) GO TO 200
    2132         [ #  # ]:           0 :       IF( ABS(dx(i)) .GT. cutlo) GO TO 85
    2133                 :             : 
    2134                 :             : !C                        PREPARE FOR PHASE 2.
    2135                 :             : 
    2136                 :             :       next = 70
    2137                 :           0 :       GO TO 105
    2138                 :             : 
    2139                 :             : !C                        PREPARE FOR PHASE 4.
    2140                 :             : 
    2141                 :           0 :   100 i = j
    2142                 :           0 :       next = 110
    2143                 :           0 :       sum = (sum / dx(i)) / dx(i)
    2144                 :           0 :   105 xmax = ABS(dx(i))
    2145                 :           0 :       GO TO 115
    2146                 :             : 
    2147                 :             : !C                   PHASE 2.  SUM IS SMALL.
    2148                 :             : !C                             SCALE TO AVOID DESTRUCTIVE UNDERFLOW.
    2149                 :             : 
    2150         [ #  # ]:           0 :    70 IF( ABS(dx(i)) .GT. cutlo ) GO TO 75
    2151                 :             : 
    2152                 :             : !C                   COMMON CODE FOR PHASES 2 AND 4.
    2153                 :             : !C                   IN PHASE 4 SUM IS LARGE.  SCALE TO AVOID OVERFLOW.
    2154                 :             : 
    2155         [ #  # ]:           0 :   110 IF( ABS(dx(i)) .LE. xmax ) GO TO 115
    2156                 :           0 :          sum = one + sum * (xmax / dx(i))**2
    2157                 :           0 :          xmax = ABS(dx(i))
    2158                 :           0 :          GO TO 200
    2159                 :             : 
    2160                 :           0 :   115 sum = sum + (dx(i)/xmax)**2
    2161                 :           0 :       GO TO 200
    2162                 :             : 
    2163                 :             : !C                  PREPARE FOR PHASE 3.
    2164                 :             : 
    2165                 :           0 :    75 sum = (sum * xmax) * xmax
    2166                 :             : 
    2167                 :             : !C     FOR REAL OR D.P. SET HITEST = CUTHI/N
    2168                 :             : !C     FOR COMPLEX      SET HITEST = CUTHI/(2*N)
    2169                 :             : 
    2170                 :           0 :    85 hitest = cuthi/float( n )
    2171                 :             : 
    2172                 :             : !C                   PHASE 3.  SUM IS MID-RANGE.  NO SCALING.
    2173                 :             : 
    2174   [ #  #  #  #  :           0 :       DO 95 j =i,nn,incx
                   #  # ]
    2175         [ #  # ]:           0 :       IF(ABS(dx(j)) .GE. hitest) GO TO 100
    2176         [ #  # ]:           0 :          sum = sum + dx(j)**2
    2177                 :           0 :    95 CONTINUE
    2178                 :           0 :       dnrm2_ = SQRT( sum )
    2179                 :           0 :       GO TO 300
    2180                 :             : 
    2181                 :             :   200 CONTINUE
    2182                 :           0 :       i = i + incx
    2183         [ #  # ]:           0 :       IF ( i .LE. nn ) GO TO 20
    2184                 :             : 
    2185                 :             : !C              END OF MAIN LOOP.
    2186                 :             : 
    2187                 :             : !C              COMPUTE SQUARE ROOT AND ADJUST FOR SCALING.
    2188                 :             : 
    2189                 :           0 :       dnrm2_ = xmax * SQRT(sum)
    2190                 :             :   300 CONTINUE
    2191                 :             :       RETURN
    2192                 :             :       END FUNCTION dnrm2_
    2193                 :             : 
    2194                 :           0 :       SUBROUTINE  dsrot (n,dx,incx,dy,incy,c,s)
    2195                 :             : 
    2196                 :             : !C     APPLIES A PLANE ROTATION.
    2197                 :             : !C     JACK DONGARRA, LINPACK, 3/11/78.
    2198                 :             : 
    2199                 :             :       DOUBLE PRECISION dx(*),dy(*),dtemp,c,s
    2200                 :             :       INTEGER i,incx,incy,ix,iy,n
    2201                 :             : 
    2202         [ #  # ]:           0 :       IF(n.LE.0)RETURN
    2203   [ #  #  #  # ]:           0 :       IF(incx.EQ.1.AND.incy.EQ.1)GO TO 20
    2204                 :             : 
    2205                 :             : !C       CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS NOT EQUAL
    2206                 :             : !C         TO 1
    2207                 :             : 
    2208                 :           0 :       ix = 1
    2209                 :           0 :       iy = 1
    2210         [ #  # ]:           0 :       IF(incx.LT.0)ix = (-n+1)*incx + 1
    2211         [ #  # ]:           0 :       IF(incy.LT.0)iy = (-n+1)*incy + 1
    2212         [ #  # ]:           0 :       DO 10 i = 1,n
    2213                 :           0 :         dtemp = c*dx(ix) + s*dy(iy)
    2214                 :           0 :         dy(iy) = c*dy(iy) - s*dx(ix)
    2215                 :           0 :         dx(ix) = dtemp
    2216                 :           0 :         ix = ix + incx
    2217                 :           0 :         iy = iy + incy
    2218                 :           0 :    10 CONTINUE
    2219                 :           0 :       RETURN
    2220                 :             : 
    2221                 :             : !C       CODE FOR BOTH INCREMENTS EQUAL TO 1
    2222                 :             : 
    2223         [ #  # ]:           0 :    20 DO 30 i = 1,n
    2224                 :           0 :         dtemp = c*dx(i) + s*dy(i)
    2225                 :           0 :         dy(i) = c*dy(i) - s*dx(i)
    2226                 :           0 :         dx(i) = dtemp
    2227                 :           0 :    30 CONTINUE
    2228                 :             :       RETURN
    2229                 :             :       END SUBROUTINE dsrot
    2230                 :             : 
    2231                 :           0 :       SUBROUTINE dsrotg(da,db,c,s)
    2232                 :             : 
    2233                 :             : !C     CONSTRUCT GIVENS PLANE ROTATION.
    2234                 :             : !C     JACK DONGARRA, LINPACK, 3/11/78.
    2235                 :             : !C                    MODIFIED 9/27/86.
    2236                 :             : 
    2237                 :             :       DOUBLE PRECISION da,db,c,s,roe,scale,r,z,one,ZERO
    2238                 :             :       DATA one, ZERO /1.0d+00, 0.0d+00/
    2239                 :             : 
    2240                 :           0 :       roe = db
    2241         [ #  # ]:           0 :       IF( ABS(da) .GT. ABS(db) ) roe = da
    2242                 :           0 :       scale = ABS(da) + ABS(db)
    2243         [ #  # ]:           0 :       IF( scale .NE. ZERO ) GO TO 10
    2244                 :           0 :          c = one
    2245                 :           0 :          s = ZERO
    2246                 :           0 :          r = ZERO
    2247                 :           0 :          GO TO 20
    2248                 :           0 :    10 r = scale*SQRT((da/scale)**2 + (db/scale)**2)
    2249                 :           0 :       r = SIGN(one,roe)*r
    2250                 :           0 :       c = da/r
    2251                 :           0 :       s = db/r
    2252                 :           0 :    20 z = s
    2253   [ #  #  #  # ]:           0 :       IF( ABS(c) .GT. ZERO .AND. ABS(c) .LE. s ) z = one/c
    2254                 :           0 :       da = r
    2255                 :           0 :       db = z
    2256                 :           0 :       RETURN
    2257                 :             :       END SUBROUTINE dsrotg
    2258                 :             : 
    2259                 :           0 :       SUBROUTINE  dscal_sl(n,da,dx,incx)
    2260                 :             : 
    2261                 :             : !C     SCALES A VECTOR BY A CONSTANT.
    2262                 :             : !C     USES UNROLLED LOOPS FOR INCREMENT EQUAL TO ONE.
    2263                 :             : !C     JACK DONGARRA, LINPACK, 3/11/78.
    2264                 :             : 
    2265                 :             :       DOUBLE PRECISION da,dx(*)
    2266                 :             :       INTEGER i,incx,m,mp1,n,nincx
    2267                 :             : 
    2268         [ #  # ]:           0 :       IF(n.LE.0)RETURN
    2269         [ #  # ]:           0 :       IF(incx.EQ.1)GO TO 20
    2270                 :             : 
    2271                 :             : 
    2272                 :             : !C        CODE FOR INCREMENT NOT EQUAL TO 1
    2273                 :             : 
    2274                 :           0 :       nincx = n*incx
    2275   [ #  #  #  #  :           0 :       DO 10 i = 1,nincx,incx
                   #  # ]
    2276         [ #  # ]:           0 :         dx(i) = da*dx(i)
    2277                 :           0 :    10 CONTINUE
    2278                 :           0 :       RETURN
    2279                 :             : 
    2280                 :             : !C        CODE FOR INCREMENT EQUAL TO 1
    2281                 :             : 
    2282                 :             : !C        CLEAN-UP LOOP
    2283                 :             : 
    2284                 :           0 :    20 m = MOD(n,5)
    2285         [ #  # ]:           0 :       IF( m .EQ. 0 ) GO TO 40
    2286         [ #  # ]:           0 :       DO 30 i = 1,m
    2287                 :           0 :         dx(i) = da*dx(i)
    2288                 :           0 :    30 CONTINUE
    2289         [ #  # ]:           0 :       IF( n .LT. 5 ) RETURN
    2290                 :           0 :    40 mp1 = m + 1
    2291         [ #  # ]:           0 :       DO 50 i = mp1,n,5
    2292                 :           0 :         dx(i) = da*dx(i)
    2293                 :           0 :         dx(i + 1) = da*dx(i + 1)
    2294                 :           0 :         dx(i + 2) = da*dx(i + 2)
    2295                 :           0 :         dx(i + 3) = da*dx(i + 3)
    2296         [ #  # ]:           0 :         dx(i + 4) = da*dx(i + 4)
    2297                 :           0 :    50 CONTINUE
    2298                 :             :       RETURN
    2299                 :             :       END SUBROUTINE dscal_sl
    2300                 :             : 
    2301                 :           0 :       subroutine bound(n, x, xl, xu)
    2302                 :             :       integer n, i
    2303                 :             :       double precision x(n), xl(n), xu(n)
    2304         [ #  # ]:           0 :       do i = 1, n
    2305                 :             : !C        Note that xl(i) and xu(i) may be NaN to indicate no bound
    2306   [ #  #  #  # ]:           0 :          if(xl(i).eq.xl(i).and.x(i) < xl(i))then
    2307                 :           0 :             x(i) = xl(i)
    2308   [ #  #  #  # ]:           0 :          else if(xu(i).eq.xu(i).and.x(i) > xu(i))then
    2309                 :           0 :             x(i) = xu(i)
    2310                 :             :          end if
    2311                 :             :       end do
    2312                 :           0 :       end subroutine bound
    2313                 :             : 
    2314                 :             : !----------------------------------------------------------------------
    2315                 :             : 
    2316                 :             : END MODULE m_slsqp
    2317                 :             : !!***
    2318                 :             : 
        

Generated by: LCOV version 2.3-1