packages feed

HsASA (empty) → 0.1

raw patch · 35 files changed

+25092/−0 lines, 35 filesdep +arraydep +basedep +haskell98setup-changedbinary-added

Dependencies added: array, base, haskell98

Files

+ HsASA.cabal view
@@ -0,0 +1,30 @@+name:               HsASA+version:            0.1+homepage:           http://repetae.net/recent/out/HsASA.html+synopsis:           A haskell interface to Lester Ingber's adaptive simulating annealing code+description:        A haskell interface to Lester Ingber's adaptive simulating annealing code+category:           Math+license:            BSD3+license-file:       LICENSE.asa+author:             John Meacham+extra-source-files: Main.hs Makefile README+cabal-version:      >= 1.2+build-type:         Simple++library+    build-depends:    base, array, haskell98+    exposed-modules:+                      Optimize.ASA+                      Optimize.Parameter++    ghc-options:      -O2 -funbox-strict-fields+    cc-options:       -O2 -msse+    extensions:       ForeignFunctionInterface,+                      UndecidableInstances,+                      PatternSignatures,+                      Rank2Types++    c-sources:        cbits/asa.c cbits/hs_asa.c+    include-dirs:     include+    includes:         asa.h asa_usr.h asa_usr_asa.h+    install-includes: asa.h asa_usr.h asa_usr_asa.h
+ LICENSE.asa view
@@ -0,0 +1,58 @@+/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* This LICENSE file must be included with ASA code.+***********************************************************************/+	+$Id: LICENSE,v 25.15 2004/09/23 18:10:35 ingber Exp ingber $++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++			CONDITIONS++1. Redistributions of ASA source code must retain the above copyright+notice, this list of conditions, and the following disclaimer.++2. Redistributions in binary form must contain the above copyright+notice, this list of conditions and the following disclaimer in the+documentation and/or other materials provided with the distribution.++3. All modifications to the source code must be clearly marked as+such.  Binary redistributions based on modified source code must be+clearly marked as modified versions in the documentation and/or other+materials provided with the distribution.++4. Notice must be given of the location of the availability of the+unmodified current source code, e.g.,+	http://www.ingber.com/+or+	ftp://ftp.ingber.com+in the documentation and/or other materials provided with the+distribution.++5. All advertising and published materials mentioning features or use+of this software must display the following acknowledgment:  "This+product includes software developed by Lester Ingber and other+contributors."++6. The name of Lester Ingber may not be used to endorse or promote+products derived from this software without specific prior written+permission.++			DISCLAIMER++This software is provided by Lester Ingber and contributors "as is" and+any expressed or implied warranties, including, but not limited to, the+implied warranties of merchantability and fitness for a particular+purpose are disclaimed.  In no event shall Lester Ingber or+contributors be liable for any direct, indirect, incidental, special,+exemplary, or consequential damages (including, but not limited to,+procurement of substitute goods or services; loss of use, data, or+profits; or business interruption) however caused and on any theory of+liability, whether in contract, strict liability, or tort (including+negligence or otherwise) arising in any way out of the use of this+software, even if advised of the possibility of such damage.+
+ Main.hs view
@@ -0,0 +1,23 @@+++import Optimize.ASA+import Optimize.Parameter+import Random+++f :: (Bool,(Double,Double)) -> Double+f (tf,(x,y)) = if  tf then x*x + y*y else x + x*x - log y ++g :: Either (Int,Int) Int -> Double+g (Left (x,y)) = realToFrac $ x * y+g (Right r) = pi*(realToFrac r)^2++main =  do+    v1 <- minimize (empty,(limit (-10) 3, limit 4 7)) f  +    v2 <- minimize (empty,(limit (-10) 3, limit 4 7)) (negate . f)  +    v3 <- minimize ((limit 10 100,limit 3 1000), limit 4 1000) g  +    v4 <- minimize ((limit 10 100,limit 3 1000), limit 4 1000) (negate . g)  +    print v1+    print v2+    print v3+    print v4
+ Makefile view
@@ -0,0 +1,27 @@+HSC2HS = hsc2hs+CC = ghc+LDLIBS = -lm +CFLAGS = -O2 -optc-msse -optc-g+HSC_CFLAGS = -C -O2 -C -optc-msse -C -optc-g++main: Main.hs asa.o hs_asa.o  Optimize/*.hs Optimize/ASA.hs+	ghc -O --make Main.hs asa.o hs_asa.o  -o $@++www-publish: Optimize/ASA.hs++asa.o: asa.h asa_usr.h asa_usr_asa.h+hs_asa.o: asa_usr.h asa_usr_asa.h++clean:+	rm *.o main Optimize/*.o Optimize/*.hi *.hi++asa_fuzzy: asa_fuzzy.o asa.o ++%.hi: %.o +	@:+%_hsc.c: %.hs+	@:+%_hsc.h: %.hs+	@:+%.hs: %.hsc+	$(HSC2HS) $(HSC_CFLAGS) -C -I. -C -I@srcdir@ -o $@ $<
+ Optimize/ASA.hsc view
@@ -0,0 +1,80 @@+{-# OPTIONS -ffi -fglasgow-exts #-}+-- | interface to the Adaptive Simulated Annealing algorithm.++module Optimize.ASA where ++#include "asa_usr.h"++import Optimize.Parameter+import Foreign.C.Types+import Foreign.Storable+import Foreign.Ptr+import Foreign.Marshal.Array+import Foreign.Marshal.Alloc+import Random+import Data.Array.Unboxed+import Data.Int+++newtype UserOptions = UserOptions (Ptr UserOptions)+type Doubles = UArray Int Double    ++data ExitCode =  NormalExit | PTempTooSmall | CTempTooSmall | CostRepeating | TooManyInvalidStates | ImmediateExit | InvalidUserInput | InvalidCostFunction | InvalidCostFunctionDeriv +    deriving(Eq,Ord,Enum,Show,Read)+++data Results x = Results {+    optimalValue :: Double,+    optimalParam :: x,+    exitCode :: ExitCode+    }+++type CostFunction =  Ptr Double -> Ptr Int -> IO Double++foreign import ccall "wrapper" mkCostFunction :: CostFunction -> IO (FunPtr CostFunction)  +foreign import ccall "asa_usr.h asa_main" asa_main :: FunPtr CostFunction -> CInt -> Ptr Double -> Ptr Double -> Ptr CInt -> Ptr Double -> Ptr Double -> Ptr CInt -> CInt -> IO CInt+++++asa :: UserOptions     -- Options+    -> (Doubles -> IO (Maybe Double)) -- cost function +    -> Int64           -- random number seed+    -> Maybe Doubles   -- starting position+    -> Doubles         -- upper bounds+    -> Doubles         -- lower bounds+    -> UArray Int Bool -- parameters are integral+    -> IO (ExitCode,Doubles)      -- final answers+asa = undefined++toBasicCostFunction :: Parameter z x => z -> (x -> Double) -> CostFunction+toBasicCostFunction z fn = f where+    thePeek = peekParam z +    f pd pf = do+        poke pf 1+        x <- thePeek pd+        let v = fn x+        --putStrLn $ ">> Haskell Function Called: " ++ show v +        return $  v+        ++minimize :: Parameter z x => z -> (x -> Double) -> IO x +minimize z (fn :: x -> Double ) = do+    cf <- mkCostFunction (toBasicCostFunction z fn)+    let n = numParams (undefined :: x) z +    let ps = paramInfo (undefined :: x) z []+    withArray (map limitLow ps) $ \lower_bounds -> do  +    withArray (map limitHigh ps) $ \upper_bounds -> do  +    withArray (map (\x -> if isIntegral x then (#const INTEGER_TYPE) else (#const REAL_TYPE)) ps) $ \real_int -> do  +    alloca $ \dummy_cost_val -> do +    allocaArray n $ \ret -> do+    alloca $ \exit_code -> do +    r <- randomIO+    asa_main cf (fromIntegral n) upper_bounds lower_bounds real_int dummy_cost_val ret exit_code (fromIntegral (r :: Int))+    --code <- peek exit_code+    --print (toEnum (fromIntegral code) :: ExitCode)+    peekParam z ret +++    
+ Optimize/Parameter.hs view
@@ -0,0 +1,203 @@+{-# OPTIONS -fglasgow-exts #-}+-- | Defines the mapping between haskell types and a set of optimization+-- parameters used to represent said type.++module Optimize.Parameter where ++import Foreign.Storable+import Foreign.Ptr+import Foreign.C.Types+import Char+++smallDouble :: Double+smallDouble = 1.0e-12+bigDouble = 1.0e6++data ParamInfo = ParamInfo {+    limitLow :: {-# UNBOX #-} !Double,+    limitHigh :: {-# UNBOX #-} !Double,+    isIntegral :: {-# UNBOX #-} !Bool+}++paramInfoFloat = ParamInfo {+    limitLow = -bigDouble,+    limitHigh = bigDouble,+    isIntegral = False+}++paramInfoInt = paramInfoFloat { limitLow = realToFrac (minBound :: Int), limitHigh = realToFrac (maxBound :: Int), isIntegral = True }++data Limit a = Limit { minLimit :: Maybe a, maxLimit :: Maybe a }++limit x y = Limit { minLimit = Just x, maxLimit = Just y }+limitMin x = Limit { minLimit = Just x, maxLimit = Nothing }+limitMax x = Limit { minLimit = Nothing, maxLimit = Just x }+limitPositive,limitNegative,limitUnit :: Num a => Limit a+limitPositive = limitMin 0+limitNegative = limitMax 0+limitUnit = limit 0 1++++-- z is the meta-info for the given type. such as bounds.++-- This really should be a superclass of Monoid+class Empty a where+    empty :: a++instance Empty () where+    empty = ()+instance (Empty x, Empty y) => Empty (x,y) where+    empty = (empty,empty)+instance (Empty x, Empty y, Empty z) => Empty (x,y,z) where+    empty = (empty,empty,empty)+instance Empty (Maybe a) where+    empty = Nothing+instance Empty (Limit a) where+    empty = Limit { minLimit = Nothing, maxLimit = Nothing }++class Empty z => Parameter z x | x -> z where+    pokeParam :: z -> x -> Ptr Double -> IO ()+    peekParam :: z -> Ptr Double -> IO x    -- needs to be as fast as possible+    -- x is only needed on these for its type. (can we do this in a better way?)+    paramInfo :: x -> z -> [ParamInfo] -> [ParamInfo]+    numParams :: x -> z ->  Int++instance Parameter () () where+    pokeParam _ _ _ = return ()+    peekParam _ _ = return ()+    numParams _ _ = 0+    paramInfo _ _ x = x+++instance Parameter () Bool where+    pokeParam _ False p = poke p 0+    pokeParam _ True p = poke p 1+    peekParam _ p = do+        x <- peek p+        return (not $ abs x < smallDouble)+    paramInfo _ _ xs = ParamInfo { limitLow = 0, limitHigh = 1, isIntegral = True }:xs+    numParams _ _ = 1++instance (Parameter za a, Parameter zb b) => Parameter (za,zb) (a,b) where+    pokeParam (za,zb) ((a::a),b) p = do+        pokeParam za a p +        pokeParam zb b (p `advancePtr` numParams (undefined::a) za) +    peekParam (za,zb) p = do+        (a::a) <- peekParam za p +        b <- peekParam zb (p `advancePtr` numParams (undefined::a) za)+        return (a,b)+    paramInfo (_ :: (a,b)) (za,zb) = paramInfo a za . paramInfo b zb where+        a = undefined :: a+        b = undefined :: b++    numParams (_ :: (a,b)) (za,zb) = numParams a za + numParams b zb  where+        a = undefined :: a+        b = undefined :: b++instance (Parameter za a, Parameter zb b, Parameter zc c) => Parameter (za,zb,zc) (a,b,c) where+    pokeParam (za,zb,zc) (a,b,c) p = do+        pokeParam (za,(zb,zc)) (a,(b,c)) p+    peekParam (za,zb,zc) p = do+        (a,(b,c)) <- peekParam (za,(zb,zc)) p +        return (a,b,c)+    paramInfo (_ :: (a,b,c)) (za,zb,zc) = paramInfo a za . paramInfo b zb . paramInfo c zc where+        a = undefined :: a+        b = undefined :: b+        c = undefined :: c++    numParams (_ :: (a,b,c)) (za,zb,zc) = numParams a za + numParams b zb + numParams c zc  where+        a = undefined :: a+        b = undefined :: b+        c = undefined :: c++instance Parameter (Limit Double) Double where+    pokeParam _ x p = poke p  x+    peekParam _ p = peek p +    paramInfo _ Limit { minLimit = Nothing, maxLimit = Nothing } xs = paramInfoFloat :xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Nothing } xs = paramInfoFloat { limitLow =  x }:xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Just y } xs = paramInfoFloat { limitLow =  x, limitHigh =  y }:xs+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Just y } xs = paramInfoFloat { limitHigh =  y }:xs+    numParams _ _ = 1+    +instance Parameter (Limit Int) Int where+    pokeParam _ x p = poke p (realToFrac x)+    peekParam _ p = peek p >>= return . round+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Nothing } xs = paramInfoInt :xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Nothing } xs = paramInfoInt { limitLow = realToFrac x }:xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Just y } xs = paramInfoInt { limitLow = realToFrac x, limitHigh = realToFrac y }:xs+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Just y } xs = paramInfoInt { limitHigh = realToFrac y }:xs+    numParams _ _ = 1+++-- Of questionable utility.+instance Parameter ()  Char where +    pokeParam _ x p = poke p (realToFrac $ ord x)+    peekParam _ p = peek p >>= return . chr . round+    paramInfo _ () xs = paramInfoInt { limitLow = 0x20, limitHigh = 0x7e }:xs+    numParams _ _ = 1+    +++instance Parameter (Limit Float) Float where+    pokeParam _ x p = poke p (realToFrac x)+    peekParam _ p = peek p >>= return . realToFrac+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Nothing } xs = paramInfoFloat :xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Nothing } xs = paramInfoFloat { limitLow = realToFrac x }:xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Just y } xs = paramInfoFloat { limitLow = realToFrac x, limitHigh = realToFrac y }:xs+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Just y } xs = paramInfoFloat { limitHigh = realToFrac y }:xs+    numParams _ _ = 1++instance Parameter zb b => Parameter zb (Maybe b) where+    pokeParam zb (Nothing :: Maybe b) p = do+        pokeParam ((),zb) (Left () :: Either () b) p+    pokeParam zb (Just b :: Maybe b) p = do+        pokeParam ((),zb) (Right b :: Either () b) p+    peekParam zb p = do+        v <- peekParam ((),zb) p+        case v of+            Right b -> return $ Just b+            Left () -> return $ Nothing+    paramInfo (_ :: Maybe b) z = paramInfo (undefined :: Either () b) ((),z)+    numParams (_ :: Maybe b) z = numParams (undefined :: Either () b) ((),z)++    +    +    ++instance (Parameter za a, Parameter zb b) => Parameter (za,zb) (Either a b) where+    pokeParam (za,zb) (Left a :: Either a b) p = do+        pokeParam empty False p+        p <- return $  (p `advancePtr` 1)+        pokeParam za a p+    pokeParam (za,zb) (Right b :: Either a b) p = do+        pokeParam empty False p+        p <- return $  (p `advancePtr` (1 + numParams (undefined :: a) za))+        pokeParam zb b p+    peekParam (za,zb) p  = do+        b <- peekParam () p+        p <- return $  (p `advancePtr` 1)+        case b of+            False -> do+                a <- peekParam za p +                return $ Left a+            True -> do+                let f :: Either a b -> a -> Either a b+                    f x _ = x+                un <- return undefined+                p <- return $ (p `advancePtr` numParams un za)+                a <- peekParam zb p +                return $ f (Right a) un+    paramInfo (_ :: Either a b) (za,zb) = paramInfo (undefined :: Bool) empty . paramInfo a za . paramInfo b zb where+        a = undefined :: a+        b = undefined :: b+    numParams (_ :: Either a b) (za,zb) = 1 + numParams a za + numParams b zb  where+        a = undefined :: a+        b = undefined :: b++advancePtr :: forall a. Storable a => Ptr a -> Int -> Ptr a+advancePtr (p :: Ptr a) n = p `plusPtr` (n * sizeOf (undefined :: a)) ++--instance (Parameter a, Parameter b) => Parameter (Either a b) where+--      pokeParam = pokeParam (Bool,a,b)
+ README view
@@ -0,0 +1,2 @@+A haskell interface to Lester Ingber's adaptive simulating annealing code. +
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ _darcs/format view
@@ -0,0 +1,1 @@+darcs-1.0
+ _darcs/inventory view
@@ -0,0 +1,8 @@+[initial import+John Meacham <john@repetae.net>**20050119222636] +[Get ready for publication+John Meacham <john@repetae.net>**20050119223112] +[Fix for haddock+John Meacham <john@repetae.net>**20050119225844] +[Don't pass CFLAGS as a lump+Aaron Denney <wnoise@ofb.net>**20050518054418] 
+ _darcs/patches/20050119222636-1a7c6-21b43a4c7b95ff8cf14b9172c183ce40fad6063a.gz view

binary file changed (absent → 62384 bytes)

+ _darcs/patches/20050119223112-1a7c6-9e5331c024ae010cc8dbc5ac7b9c5f0535e42bd8.gz view

binary file changed (absent → 220 bytes)

+ _darcs/patches/20050119225844-1a7c6-780693a86626c686cb86fec84175b7a2e901a1a0.gz view

binary file changed (absent → 293 bytes)

+ _darcs/patches/20050518054418-859d9-e48366547a7cac704fd95ac4b7bd3333d6a28035.gz view

binary file changed (absent → 203 bytes)

+ _darcs/prefs/binaries view
@@ -0,0 +1,59 @@+# Binary file regexps:+\.png$+\.PNG$+\.gz$+\.GZ$+\.pdf$+\.PDF$+\.jpg$+\.JPG$+\.jpeg$+\.JPEG$+\.gif$+\.GIF$+\.tif$+\.TIF$+\.tiff$+\.TIFF$+\.pnm$+\.PNM$+\.pbm$+\.PBM$+\.pgm$+\.PGM$+\.ppm$+\.PPM$+\.bmp$+\.BMP$+\.mng$+\.MNG$+\.tar$+\.TAR$+\.bz2$+\.BZ2$+\.z$+\.Z$+\.zip$+\.ZIP$+\.jar$+\.JAR$+\.so$+\.SO$+\.a$+\.A$+\.tgz$+\.TGZ$+\.mpg$+\.MPG$+\.mpeg$+\.MPEG$+\.iso$+\.ISO$+\.exe$+\.EXE$+\.doc$+\.DOC$+\.elc$+\.ELC$+\.pyc$+\.PYC$
+ _darcs/prefs/boring view
@@ -0,0 +1,68 @@+# Boring file regexps:+\.hi$+\.hi-boot$+\.o-boot$+\.o$+\.o\.cmd$+\.p_hi$+\.p_o$+\.installed-pkg-config+\.setup-config+\.setup-config^dist(/|$)+# *.ko files aren't boring by default because they might+# be Korean translations rather than kernel modules.+# \.ko$+\.ko\.cmd$+\.mod\.c$+(^|/)\.tmp_versions($|/)+(^|/)CVS($|/)+\.cvsignore$+^\.#+(^|/)RCS($|/)+,v$+(^|/)\.svn($|/)+(^|/)\.hg($|/)+(^|/)\.git($|/)+\.bzr$+(^|/)SCCS($|/)+~$+(^|/)_darcs($|/)+(^|/)\.darcsrepo($|/)+\.bak$+\.BAK$+\.orig$+\.rej$+(^|/)vssver\.scc$+\.swp$+(^|/)MT($|/)+(^|/)\{arch\}($|/)+(^|/).arch-ids($|/)+(^|/),+\.prof$+(^|/)\.DS_Store$+(^|/)BitKeeper($|/)+(^|/)ChangeSet($|/)+\.py[co]$+\.elc$+\.class$+\.zwc$+\.revdep-rebuild.*+\..serverauth.*+\#+(^|/)Thumbs\.db$+(^|/)autom4te\.cache($|/)+(^|/)config\.(log|status)$+^\.depend$+(^|/)(tags|TAGS)$+#(^|/)\.[^/]+(^|/|\.)core$+\.(obj|a|exe|so|lo|la)$+^\.darcs-temp-mail$+-darcs-backup[[:digit:]]+$+\.(fas|fasl|sparcf|x86f)$+\.part$+(^|/)\.waf-[[:digit:].]+-[[:digit:]]+($|/)+(^|/)\.lock-wscript$+^\.darcs-temp-mail$+\_vti_cnf$+\_vti_pvt$
+ _darcs/prefs/defaultrepo view
@@ -0,0 +1,1 @@+http://repetae.net/john/repos/HsASA
+ _darcs/prefs/motd view
+ _darcs/prefs/repos view
@@ -0,0 +1,1 @@+http://repetae.net/john/repos/HsASA
+ _darcs/pristine/LICENSE.asa view
@@ -0,0 +1,58 @@+/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* This LICENSE file must be included with ASA code.+***********************************************************************/+	+$Id: LICENSE,v 25.15 2004/09/23 18:10:35 ingber Exp ingber $++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++			CONDITIONS++1. Redistributions of ASA source code must retain the above copyright+notice, this list of conditions, and the following disclaimer.++2. Redistributions in binary form must contain the above copyright+notice, this list of conditions and the following disclaimer in the+documentation and/or other materials provided with the distribution.++3. All modifications to the source code must be clearly marked as+such.  Binary redistributions based on modified source code must be+clearly marked as modified versions in the documentation and/or other+materials provided with the distribution.++4. Notice must be given of the location of the availability of the+unmodified current source code, e.g.,+	http://www.ingber.com/+or+	ftp://ftp.ingber.com+in the documentation and/or other materials provided with the+distribution.++5. All advertising and published materials mentioning features or use+of this software must display the following acknowledgment:  "This+product includes software developed by Lester Ingber and other+contributors."++6. The name of Lester Ingber may not be used to endorse or promote+products derived from this software without specific prior written+permission.++			DISCLAIMER++This software is provided by Lester Ingber and contributors "as is" and+any expressed or implied warranties, including, but not limited to, the+implied warranties of merchantability and fitness for a particular+purpose are disclaimed.  In no event shall Lester Ingber or+contributors be liable for any direct, indirect, incidental, special,+exemplary, or consequential damages (including, but not limited to,+procurement of substitute goods or services; loss of use, data, or+profits; or business interruption) however caused and on any theory of+liability, whether in contract, strict liability, or tort (including+negligence or otherwise) arising in any way out of the use of this+software, even if advised of the possibility of such damage.+
+ _darcs/pristine/Main.hs view
@@ -0,0 +1,23 @@+++import Optimize.ASA+import Optimize.Parameter+import Random+++f :: (Bool,(Double,Double)) -> Double+f (tf,(x,y)) = if  tf then x*x + y*y else x + x*x - log y ++g :: Either (Int,Int) Int -> Double+g (Left (x,y)) = realToFrac $ x * y+g (Right r) = pi*(realToFrac r)^2++main =  do+    v1 <- minimize (empty,(limit (-10) 3, limit 4 7)) f  +    v2 <- minimize (empty,(limit (-10) 3, limit 4 7)) (negate . f)  +    v3 <- minimize ((limit 10 100,limit 3 1000), limit 4 1000) g  +    v4 <- minimize ((limit 10 100,limit 3 1000), limit 4 1000) (negate . g)  +    print v1+    print v2+    print v3+    print v4
+ _darcs/pristine/Makefile view
@@ -0,0 +1,27 @@+HSC2HS = hsc2hs+CC = ghc+LDLIBS = -lm +CFLAGS = -O2 -optc-msse -optc-g+HSC_CFLAGS = -C -O2 -C -optc-msse -C -optc-g++main: Main.hs asa.o hs_asa.o  Optimize/*.hs Optimize/ASA.hs+	ghc -O --make Main.hs asa.o hs_asa.o  -o $@++www-publish: Optimize/ASA.hs++asa.o: asa.h asa_usr.h asa_usr_asa.h+hs_asa.o: asa_usr.h asa_usr_asa.h++clean:+	rm *.o main Optimize/*.o Optimize/*.hi *.hi++asa_fuzzy: asa_fuzzy.o asa.o ++%.hi: %.o +	@:+%_hsc.c: %.hs+	@:+%_hsc.h: %.hs+	@:+%.hs: %.hsc+	$(HSC2HS) $(HSC_CFLAGS) -C -I. -C -I@srcdir@ -o $@ $<
+ _darcs/pristine/Optimize/ASA.hsc view
@@ -0,0 +1,80 @@+{-# OPTIONS -ffi -fglasgow-exts #-}+-- | interface to the Adaptive Simulated Annealing algorithm.++module Optimize.ASA where ++#include "asa_usr.h"++import Optimize.Parameter+import Foreign.C.Types+import Foreign.Storable+import Foreign.Ptr+import Foreign.Marshal.Array+import Foreign.Marshal.Alloc+import Random+import Data.Array.Unboxed+import Int+++newtype UserOptions = UserOptions (Ptr UserOptions)+type Doubles = UArray Int Double    ++data ExitCode =  NormalExit | PTempTooSmall | CTempTooSmall | CostRepeating | TooManyInvalidStates | ImmediateExit | InvalidUserInput | InvalidCostFunction | InvalidCostFunctionDeriv +    deriving(Eq,Ord,Enum,Show,Read)+++data Results x = Results {+    optimalValue :: Double,+    optimalParam :: x,+    exitCode :: ExitCode+    }+++type CostFunction =  Ptr Double -> Ptr Int -> IO Double++foreign import ccall "wrapper" mkCostFunction :: CostFunction -> IO (FunPtr CostFunction)  +foreign import ccall "asa_usr.h asa_main" asa_main :: FunPtr CostFunction -> CInt -> Ptr Double -> Ptr Double -> Ptr CInt -> Ptr Double -> Ptr Double -> Ptr CInt -> CInt -> IO CInt+++++asa :: UserOptions     -- Options+    -> (Doubles -> IO (Maybe Double)) -- cost function +    -> Int64           -- random number seed+    -> Maybe Doubles   -- starting position+    -> Doubles         -- upper bounds+    -> Doubles         -- lower bounds+    -> UArray Int Bool -- parameters are integral+    -> IO (ExitCode,Doubles)      -- final answers+asa = undefined++toBasicCostFunction :: Parameter z x => z -> (x -> Double) -> CostFunction+toBasicCostFunction z fn = f where+    thePeek = peekParam z +    f pd pf = do+        poke pf 1+        x <- thePeek pd+        let v = fn x+        --putStrLn $ ">> Haskell Function Called: " ++ show v +        return $  v+        ++minimize :: Parameter z x => z -> (x -> Double) -> IO x +minimize z (fn :: x -> Double ) = do+    cf <- mkCostFunction (toBasicCostFunction z fn)+    let n = numParams (undefined :: x) z +    let ps = paramInfo (undefined :: x) z []+    withArray (map limitLow ps) $ \lower_bounds -> do  +    withArray (map limitHigh ps) $ \upper_bounds -> do  +    withArray (map (\x -> if isIntegral x then (#const INTEGER_TYPE) else (#const REAL_TYPE)) ps) $ \real_int -> do  +    alloca $ \dummy_cost_val -> do +    allocaArray n $ \ret -> do+    alloca $ \exit_code -> do +    r <- randomIO+    asa_main cf (fromIntegral n) upper_bounds lower_bounds real_int dummy_cost_val ret exit_code (fromIntegral (r :: Int))+    --code <- peek exit_code+    --print (toEnum (fromIntegral code) :: ExitCode)+    peekParam z ret +++    
+ _darcs/pristine/Optimize/Parameter.hs view
@@ -0,0 +1,202 @@+{-# OPTIONS -fglasgow-exts #-}+-- | Defines the mapping between haskell types and a set of optimization+-- parameters used to represent said type.++module Optimize.Parameter where ++import Foreign.Storable+import Foreign.Ptr+import Foreign.C.Types+import Char+++smallDouble :: Double+smallDouble = 1.0e-12+bigDouble = 1.0e6++data ParamInfo = ParamInfo {+    limitLow :: {-# UNBOX #-} !Double,+    limitHigh :: {-# UNBOX #-} !Double,+    isIntegral :: {-# UNBOX #-} !Bool+}++paramInfoFloat = ParamInfo {+    limitLow = -bigDouble,+    limitHigh = bigDouble,+    isIntegral = False+}++paramInfoInt = paramInfoFloat { limitLow = realToFrac (minBound :: Int), limitHigh = realToFrac (maxBound :: Int), isIntegral = True }++data Limit a = Limit { minLimit :: Maybe a, maxLimit :: Maybe a }++limit x y = Limit { minLimit = Just x, maxLimit = Just y }+limitMin x = Limit { minLimit = Just x, maxLimit = Nothing }+limitMax x = Limit { minLimit = Nothing, maxLimit = Just x }+limitPositive,limitNegative,limitUnit :: Num a => Limit a+limitPositive = limitMin 0+limitNegative = limitMax 0+limitUnit = limit 0 1++++-- z is the meta-info for the given type. such as bounds.++-- This really should be a superclass of Monoid+class Empty a where+    empty :: a++instance Empty () where+    empty = ()+instance (Empty x, Empty y) => Empty (x,y) where+    empty = (empty,empty)+instance (Empty x, Empty y, Empty z) => Empty (x,y,z) where+    empty = (empty,empty,empty)+instance Empty (Maybe a) where+    empty = Nothing+instance Empty (Limit a) where+    empty = Limit { minLimit = Nothing, maxLimit = Nothing }++class Empty z => Parameter z x | x -> z where+    pokeParam :: z -> x -> Ptr Double -> IO ()+    peekParam :: z -> Ptr Double -> IO x    -- needs to be as fast as possible+    -- x is only needed on these for its type. (can we do this in a better way?)+    paramInfo :: x -> z -> [ParamInfo] -> [ParamInfo]+    numParams :: x -> z ->  Int++instance Parameter () () where+    pokeParam _ _ _ = return ()+    peekParam _ _ = return ()+    numParams _ _ = 0+    paramInfo _ _ x = x+++instance Parameter () Bool where+    pokeParam _ False p = poke p 0+    pokeParam _ True p = poke p 1+    peekParam _ p = do+        x <- peek p+        return (not $ abs x < smallDouble)+    paramInfo _ _ xs = ParamInfo { limitLow = 0, limitHigh = 1, isIntegral = True }:xs+    numParams _ _ = 1++instance (Parameter za a, Parameter zb b) => Parameter (za,zb) (a,b) where+    pokeParam (za,zb) ((a::a),b) p = do+        pokeParam za a p +        pokeParam zb b (p `advancePtr` numParams (undefined::a) za) +    peekParam (za,zb) p = do+        (a::a) <- peekParam za p +        b <- peekParam zb (p `advancePtr` numParams (undefined::a) za)+        return (a,b)+    paramInfo (_ :: (a,b)) (za,zb) = paramInfo a za . paramInfo b zb where+        a = undefined :: a+        b = undefined :: b++    numParams (_ :: (a,b)) (za,zb) = numParams a za + numParams b zb  where+        a = undefined :: a+        b = undefined :: b++instance (Parameter za a, Parameter zb b, Parameter zc c) => Parameter (za,zb,zc) (a,b,c) where+    pokeParam (za,zb,zc) (a,b,c) p = do+        pokeParam (za,(zb,zc)) (a,(b,c)) p+    peekParam (za,zb,zc) p = do+        (a,(b,c)) <- peekParam (za,(zb,zc)) p +        return (a,b,c)+    paramInfo (_ :: (a,b,c)) (za,zb,zc) = paramInfo a za . paramInfo b zb . paramInfo c zc where+        a = undefined :: a+        b = undefined :: b+        c = undefined :: c++    numParams (_ :: (a,b,c)) (za,zb,zc) = numParams a za + numParams b zb + numParams c zc  where+        a = undefined :: a+        b = undefined :: b+        c = undefined :: c++instance Parameter (Limit Double) Double where+    pokeParam _ x p = poke p  x+    peekParam _ p = peek p +    paramInfo _ Limit { minLimit = Nothing, maxLimit = Nothing } xs = paramInfoFloat :xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Nothing } xs = paramInfoFloat { limitLow =  x }:xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Just y } xs = paramInfoFloat { limitLow =  x, limitHigh =  y }:xs+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Just y } xs = paramInfoFloat { limitHigh =  y }:xs+    numParams _ _ = 1+    +instance Parameter (Limit Int) Int where+    pokeParam _ x p = poke p (realToFrac x)+    peekParam _ p = peek p >>= return . round+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Nothing } xs = paramInfoInt :xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Nothing } xs = paramInfoInt { limitLow = realToFrac x }:xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Just y } xs = paramInfoInt { limitLow = realToFrac x, limitHigh = realToFrac y }:xs+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Just y } xs = paramInfoInt { limitHigh = realToFrac y }:xs+    numParams _ _ = 1+++-- Of questionable utility.+instance Parameter ()  Char where +    pokeParam _ x p = poke p (realToFrac $ ord x)+    peekParam _ p = peek p >>= return . chr . round+    paramInfo _ () xs = paramInfoInt { limitLow = 0x20, limitHigh = 0x7e }:xs+    numParams _ _ = 1+    +++instance Parameter (Limit Float) Float where+    pokeParam _ x p = poke p (realToFrac x)+    peekParam _ p = peek p >>= return . realToFrac+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Nothing } xs = paramInfoFloat :xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Nothing } xs = paramInfoFloat { limitLow = realToFrac x }:xs+    paramInfo _ Limit { minLimit = Just x, maxLimit = Just y } xs = paramInfoFloat { limitLow = realToFrac x, limitHigh = realToFrac y }:xs+    paramInfo _ Limit { minLimit = Nothing, maxLimit = Just y } xs = paramInfoFloat { limitHigh = realToFrac y }:xs+    numParams _ _ = 1++instance Parameter zb b => Parameter zb (Maybe b) where+    pokeParam zb (Nothing :: Maybe b) p = do+        pokeParam ((),zb) (Left () :: Either () b) p+    pokeParam zb (Just b :: Maybe b) p = do+        pokeParam ((),zb) (Right b :: Either () b) p+    peekParam zb p = do+        v <- peekParam ((),zb) p+        case v of+            Right b -> return $ Just b+            Left () -> return $ Nothing+    paramInfo (_ :: Maybe b) z = paramInfo (undefined :: Either () b) ((),z)+    numParams (_ :: Maybe b) z = numParams (undefined :: Either () b) ((),z)++    +    +    ++instance (Parameter za a, Parameter zb b) => Parameter (za,zb) (Either a b) where+    pokeParam (za,zb) (Left a :: Either a b) p = do+        pokeParam empty False p+        p <- return $  (p `advancePtr` 1)+        pokeParam za a p+    pokeParam (za,zb) (Right b :: Either a b) p = do+        pokeParam empty False p+        p <- return $  (p `advancePtr` (1 + numParams (undefined :: a) za))+        pokeParam zb b p+    peekParam (za,zb) p  = do+        b <- peekParam () p+        p <- return $  (p `advancePtr` 1)+        case b of+            False -> do+                a <- peekParam za p +                return $ Left a+            True -> do+                let f :: Either a b -> a -> Either a b+                    f x _ = x+                un <- return undefined+                p <- return $ (p `advancePtr` numParams un za)+                a <- peekParam zb p +                return $ f (Right a) un+    paramInfo (_ :: Either a b) (za,zb) = paramInfo (undefined :: Bool) empty . paramInfo a za . paramInfo b zb where+        a = undefined :: a+        b = undefined :: b+    numParams (_ :: Either a b) (za,zb) = 1 + numParams a za + numParams b zb  where+        a = undefined :: a+        b = undefined :: b++advancePtr (p :: Ptr a) n = p `plusPtr` (n * sizeOf (undefined :: a)) ++--instance (Parameter a, Parameter b) => Parameter (Either a b) where+--      pokeParam = pokeParam (Bool,a,b)
+ _darcs/pristine/README view
@@ -0,0 +1,2 @@+A haskell interface to Lester Ingber's adaptive simulating annealing code. +
+ _darcs/pristine/asa.c view
@@ -0,0 +1,6387 @@+/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+***********************************************************************/++#define ASA_ID \+"/* $Id: asa.c,v 25.15 2004/09/23 18:10:46 ingber Exp ingber $ */"++#include "asa.h"+static int asa_recursive_max = 0;       /* record of max recursions */++/***********************************************************************+* asa+*       This procedure implements the full ASA function optimization.+***********************************************************************/+#if HAVE_ANSI+double+asa (double (*user_cost_function)++      +     (double *, double *, double *, double *, double *, ALLOC_INT *, int *,+      int *, int *, USER_DEFINES *),+     double (*user_random_generator) (LONG_INT *), LONG_INT * seed,+     double *parameter_initial_final, double *parameter_minimum,+     double *parameter_maximum, double *tangents, double *curvature,+     ALLOC_INT * number_parameters, int *parameter_type,+     int *valid_state_generated_flag, int *exit_status,+     USER_DEFINES * OPTIONS)+#else+double+asa (user_cost_function,+     user_random_generator,+     seed,+     parameter_initial_final,+     parameter_minimum,+     parameter_maximum,+     tangents,+     curvature,+     number_parameters,+     parameter_type, valid_state_generated_flag, exit_status, OPTIONS)+     double (*user_cost_function) ();+     double (*user_random_generator) ();+     LONG_INT *seed;+     double *parameter_initial_final;+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *curvature;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     int *valid_state_generated_flag;+     int *exit_status;+     USER_DEFINES *OPTIONS;+#endif /* HAVE_ANSI */+{+#if USER_INITIAL_COST_TEMP+#if USER_REANNEAL_COST+#else+  int index_cost_constraint;    /* index cost functions averaged */+#endif /* USER_REANNEAL_COST */+#else /* USER_INITIAL_COST_TEMP */+  int index_cost_constraint;    /* index cost functions averaged */+#endif /* USER_INITIAL_COST_TEMP */++  int index_cost_repeat,        /* test OPTIONS->Cost_Precision when =+                                   OPTIONS->Maximum_Cost_Repeat */+    tmp_var_int, tmp_var_int1, tmp_var_int2;    /* temporary integers */++  ALLOC_INT index_v,            /* iteration index */+   *start_sequence;             /* initial OPTIONS->Sequential_Parameters+                                   used if >= 0 */+  double final_cost,            /* best cost to return to user */+    tmp_var_db, tmp_var_db1, tmp_var_db2;       /* temporary doubles */+  int *curvature_flag;+  FILE *ptr_asa_out;            /* file ptr to output file */++  /* The 3 states that are kept track of during the annealing process */+  STATE *current_generated_state, *last_saved_state, *best_generated_state;++#if ASA_SAVE+  FILE *ptr_save, *ptr_comm;+  int asa_read;+  char asa_save_comm[100];+#if ASA_SAVE_OPT+  char read_option[80];+  char read_if[4], read_FALSE[6], read_comm1[3], read_ASA_SAVE[9],+    read_comm2[3];+  int read_int;+#if INT_LONG+  LONG_INT read_long;+#endif+  double read_double;+  FILE *ptr_save_opt;+#endif+#endif /* ASA_SAVE */++#if ASA_PIPE_FILE+  FILE *ptr_asa_pipe;+#endif++  int immediate_flag;           /* save Immediate_Exit */+  int asa_exit_value;++  double xnumber_parameters[1];++  /* The array of tangents (absolute value of the numerical derivatives),+     and the maximum |tangent| of the array */+  double *maximum_tangent;++  /* ratio of acceptances to generated points - determines when to+     test/reanneal */+  double *accepted_to_generated_ratio;++  /* temperature parameters */+  double temperature_scale, *temperature_scale_parameters;+  /* relative scalings of cost and parameters to temperature_scale */+  double *temperature_scale_cost;+  double *current_user_parameter_temp;+  double *initial_user_parameter_temp;+  double *current_cost_temperature;+  double *initial_cost_temperature;+  double log_new_temperature_ratio;     /* current *temp = initial *temp *+                                           exp(log_new_temperature_ratio) */+  ALLOC_INT *index_exit_v;      /* information for asa_exit */++  /* counts of generated states and acceptances */+  LONG_INT *index_parameter_generations;+  LONG_INT *number_generated, *best_number_generated_saved;+  LONG_INT *recent_number_generated, *number_accepted;+  LONG_INT *recent_number_acceptances, *index_cost_acceptances;+  LONG_INT *number_acceptances_saved, *best_number_accepted_saved;++  /* Flag indicates that the parameters generated were+     invalid according to the cost function validity criteria. */+  LONG_INT *number_invalid_generated_states;+  LONG_INT repeated_invalid_states;++#if ASA_QUEUE+  int queue_new;                /* flag to add new entry */+  int *save_queue_flag;         /* save valid_state_generated_flag */+  LONG_INT queue;               /* index of queue */+  LONG_INT queue_v;             /* index of parameters in queue */+  LONG_INT save_queue_test;     /* test if all parameters are present */+  LONG_INT save_queue;          /* last filled position in queue */+  LONG_INT save_queue_indx;     /* current position in queue */+  double *save_queue_cost, *save_queue_param;   /* saved states */+  ALLOC_INT queue_size_tmp;+#endif++#if MULTI_MIN+  int multi_index;+  int multi_test, multi_test_cmp, multi_test_dim;+  int *multi_sort;+  double *multi_cost;+  double **multi_params;+#endif /* MULTI_MIN */++#if ASA_PARALLEL+  LONG_INT *parallel_sort;+  LONG_INT index_parallel, sort_index;  /* count of parallel generated states */+  LONG_INT parallel_generated;  /* saved *recent_number_generated */+  LONG_INT parallel_block_max;  /* saved OPTIONS->Gener_Block_Max */+  STATE *gener_block_state;+#endif++  /* used to index repeated and recursive calls to asa */+  /* This assumes that multiple calls (>= 1) _or_ recursive+     calls are being made to asa */+  static int asa_open = FALSE;+  static int number_asa_open = 0;+  static int recursive_asa_open = 0;++  /* initializations */++  if ((curvature_flag = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (exit_msg, "asa(): curvature_flag");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((maximum_tangent = (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): maximum_tangent");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((accepted_to_generated_ratio =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): accepted_to_generated_ratio");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((temperature_scale_cost =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): temperature_scale_cost");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((current_cost_temperature =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): current_cost_temperature");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((initial_cost_temperature =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): initial_cost_temperature");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((index_exit_v = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): index_exit_v");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((start_sequence = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): start_sequence");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((number_generated =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): number_generated");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((best_number_generated_saved =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): best_number_generated_saved");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((recent_number_generated =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): recent_number_generated");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((number_accepted =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): number_accepted");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((recent_number_acceptances =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): recent_number_acceptances");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((index_cost_acceptances =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): index_cost_acceptances");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((number_acceptances_saved =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): number_acceptances_saved");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((best_number_accepted_saved =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): best_number_accepted_saved");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((number_invalid_generated_states =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): number_invalid_generated_states");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }++  if ((current_generated_state =+       (STATE *) calloc (1, sizeof (STATE))) == NULL) {+    strcpy (exit_msg, "asa(): current_generated_state");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((last_saved_state = (STATE *) calloc (1, sizeof (STATE))) == NULL) {+    strcpy (exit_msg, "asa(): last_saved_state");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((best_generated_state = (STATE *) calloc (1, sizeof (STATE))) == NULL) {+    strcpy (exit_msg, "asa(): best_generated_state");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#if ASA_PARALLEL+  if ((gener_block_state =+       (STATE *) calloc (OPTIONS->Gener_Block_Max, sizeof (STATE))) == NULL) {+    strcpy (exit_msg, "asa(): gener_block_state");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  gener_block_state_qsort = gener_block_state;+  if ((parallel_sort =+       (LONG_INT *) calloc (OPTIONS->Gener_Block_Max,+                            sizeof (LONG_INT))) == NULL) {+    strcpy (exit_msg, "asa(): parallel_sort");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#endif++  /* set default */+  ptr_asa_out = (FILE *) NULL;++  OPTIONS->Immediate_Exit = FALSE;++  if (asa_open == FALSE) {+    asa_open = TRUE;+    ++number_asa_open;+#if ASA_PRINT+    if (number_asa_open == 1) {+      /* open the output file */+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+#if ASA_SAVE+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");+#else+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "w");+#endif+      }+#else /* USER_ASA_OUT */+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+#if ASA_SAVE+        ptr_asa_out = fopen (ASA_OUT, "a");+#else+        ptr_asa_out = fopen (ASA_OUT, "w");+#endif+      }+#endif /* USER_ASA_OUT */+    } else {+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");+      }+#else+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (ASA_OUT, "a");+      }+#endif+      fprintf (ptr_asa_out, "\n\n\t\t number_asa_open = %d\n",+               number_asa_open);+    }+#endif /* ASA_PRINT */+  } else {+    ++recursive_asa_open;+#if ASA_PRINT+    if (recursive_asa_open == 1) {+      /* open the output file */+#if ASA_SAVE+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");+      }+#else+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (ASA_OUT, "a");+      }+#endif+#else /* ASA_SAVE */+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "w");+      }+#else+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (ASA_OUT, "w");+      }+#endif+#endif /* ASA_SAVE */+    } else {+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");+      }+#else+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (ASA_OUT, "a");+      }+#endif+      fprintf (ptr_asa_out, "\n\n\t\t recursive_asa_open = %d\n",+               recursive_asa_open);+    }+#endif /* ASA_PRINT */+  }++#if ASA_PIPE_FILE+  ptr_asa_pipe = fopen ("asa_pipe", "a");+  fprintf (ptr_asa_pipe, "%s", "%generate");+  fprintf (ptr_asa_pipe, "\t%s", "accept");+  fprintf (ptr_asa_pipe, "\t%s", "best_cost");+  VFOR (index_v)+#if INT_ALLOC+    fprintf (ptr_asa_pipe, "\t%s-%d", "param", index_v);+#else+#if INT_LONG+    fprintf (ptr_asa_pipe, "\t%s-%ld", "param", index_v);+#else+    fprintf (ptr_asa_pipe, "\t%s-%d", "param", index_v);+#endif+#endif+  fprintf (ptr_asa_pipe, "\t%s", "cost_temp");+  VFOR (index_v)+#if INT_ALLOC+    fprintf (ptr_asa_pipe, "\t%s-%d", "param_temp", index_v);+#else+#if INT_LONG+    fprintf (ptr_asa_pipe, "\t%s-%ld", "param_temp", index_v);+#else+    fprintf (ptr_asa_pipe, "\t%s-%d", "param_temp", index_v);+#endif+#endif+  fprintf (ptr_asa_pipe, "\t%s", "last_cost");+  fprintf (ptr_asa_pipe, "\n");+  fflush (ptr_asa_pipe);+#endif /* ASA_PIPE_FILE */++#if ASA_PRINT+  /* print header information as defined by user */+  print_asa_options (ptr_asa_out, OPTIONS);++  fflush (ptr_asa_out);+#endif /* ASA_PRINT */++  /* set indices and counts to 0 */+  *best_number_generated_saved =+    *number_generated =+    *recent_number_generated = *recent_number_acceptances = 0;+  *index_cost_acceptances =+    *best_number_accepted_saved =+    *number_accepted = *number_acceptances_saved = 0;+  index_cost_repeat = 0;++  OPTIONS->N_Accepted = *number_accepted;+  OPTIONS->N_Generated = *number_generated;++#if ASA_SAMPLE+  OPTIONS->N_Generated = 0;+  OPTIONS->Average_Weights = 1.0;+#endif++  /* do not calculate curvatures initially */+  *curvature_flag = FALSE;++  /* allocate storage for all parameters */+  if ((current_generated_state->parameter =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): current_generated_state->parameter");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((last_saved_state->parameter =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): last_saved_state->parameter");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((best_generated_state->parameter =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): best_generated_state->parameter");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#if ASA_PARALLEL+  parallel_block_max = OPTIONS->Gener_Block_Max;+  parallel_generated = OPTIONS->Gener_Block;++  for (index_parallel = 0; index_parallel < parallel_block_max;+       ++index_parallel) {+    if ((gener_block_state[index_parallel].parameter =+         (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+      strcpy (exit_msg, "asa(): gener_block_state[index_parallel].parameter");+      Exit_ASA (exit_msg);+      *exit_status = CALLOC_FAILED;+      return (-1);+    }+  }+#endif++  OPTIONS->Best_Cost = &(best_generated_state->cost);+  OPTIONS->Best_Parameters = best_generated_state->parameter;+  OPTIONS->Last_Cost = &(last_saved_state->cost);+  OPTIONS->Last_Parameters = last_saved_state->parameter;++  if ((initial_user_parameter_temp =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): initial_user_parameter_temp");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((index_parameter_generations =+       (ALLOC_INT *) calloc (*number_parameters,+                             sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): index_parameter_generations");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }++  /* set all temperatures */+  if ((current_user_parameter_temp =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): current_user_parameter_temp");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#if USER_INITIAL_PARAMETERS_TEMPS+  VFOR (index_v)+    current_user_parameter_temp[index_v] =+    initial_user_parameter_temp[index_v] =+    OPTIONS->User_Parameter_Temperature[index_v];+#else+  VFOR (index_v)+    current_user_parameter_temp[index_v] =+    initial_user_parameter_temp[index_v] =+    OPTIONS->Initial_Parameter_Temperature;+#endif++  if ((temperature_scale_parameters =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): temperature_scale_parameters");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#if ASA_QUEUE+  if (OPTIONS->Queue_Size > 0) {+    queue_size_tmp = OPTIONS->Queue_Size;+  } else {+    queue_size_tmp = 1;+  }+  if ((save_queue_flag =+       (int *) calloc (queue_size_tmp, sizeof (int))) == NULL) {+    strcpy (exit_msg, "asa(): save_queue_flag");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((save_queue_cost =+       (double *) calloc (queue_size_tmp, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): save_queue_cost");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((save_queue_param =+       (double *) calloc ((*number_parameters) * queue_size_tmp,+                          sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): save_queue_param");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#endif /* ASA_QUEUE */++#if MULTI_MIN+  if ((multi_cost =+       (double *) calloc (OPTIONS->Multi_Number + 1,+                          sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): *multi_cost");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  multi_cost_qsort = multi_cost;+  if ((multi_sort =+       (int *) calloc (OPTIONS->Multi_Number + 1, sizeof (int))) == NULL) {+    strcpy (exit_msg, "asa(): *multi_sort");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((multi_params =+       (double **) calloc (OPTIONS->Multi_Number + 1,+                           sizeof (double *))) == NULL) {+    strcpy (exit_msg, "asa(): *multi_params");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  for (multi_index = 0; multi_index <= OPTIONS->Multi_Number; ++multi_index) {+    if ((multi_params[multi_index] =+         (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+      strcpy (exit_msg, "asa(): multi_params[multi_index]");+      Exit_ASA (exit_msg);+      *exit_status = CALLOC_FAILED;+      return (-1);+    }+  }+#endif /* MULTI_MIN */++#if USER_INITIAL_COST_TEMP+#if USER_ACCEPTANCE_TEST+  OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =+#endif+    *initial_cost_temperature = *current_cost_temperature =+    OPTIONS->User_Cost_Temperature[0];+#endif++  /* set parameters to the initial parameter values */+  VFOR (index_v)+    last_saved_state->parameter[index_v] =+    current_generated_state->parameter[index_v] =+    parameter_initial_final[index_v];+#if USER_ACCEPTANCE_TEST+  OPTIONS->Random_Seed = seed;+  OPTIONS->Random_Seed[0] = *seed;+  OPTIONS->User_Acceptance_Flag = TRUE;+  OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif++#if ASA_PRINT+#if INT_LONG+  fprintf (ptr_asa_out, "Initial Random Seed = %ld\n\n", *seed);+#else+  fprintf (ptr_asa_out, "Initial Random Seed = %d\n\n", *seed);+#endif+#endif /* ASA_PRINT */++  /* save initial user value of OPTIONS->Sequential_Parameters */+  *start_sequence = OPTIONS->Sequential_Parameters;++#if ASA_PRINT+  fprintf (ptr_asa_out,+#if INT_ALLOC+           "*number_parameters = %d\n\n", *number_parameters);+#else+#if INT_LONG+           "*number_parameters = %ld\n\n", *number_parameters);+#else+           "*number_parameters = %d\n\n", *number_parameters);+#endif+#endif++  /* print the min, max, current values, and types of parameters */+  fprintf (ptr_asa_out, "index_v parameter_minimum parameter_maximum\+ parameter_value parameter_type \n");++#if ASA_PRINT_INTERMED+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          " %-8d %-*.*g \t\t %-*.*g \t %-*.*g %-7d\n",+#else+#if INT_LONG+                          " %-8ld %-*.*g \t\t %-*.*g \t %-*.*g %-7d\n",+#else+                          " %-8d %-*.*g \t\t %-*.*g \t %-*.*g %-7d\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION, parameter_minimum[index_v],+                          G_FIELD, G_PRECISION, parameter_maximum[index_v],+                          G_FIELD, G_PRECISION,+                          current_generated_state->parameter[index_v],+                          parameter_type[index_v]);++  fprintf (ptr_asa_out, "\n\n");+#endif /* ASA_PRINT_INTERMED */+  /* Print out user-defined OPTIONS */++#if DELTA_PARAMETERS+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          "OPTIONS->User_Delta_Parameter[%d] = %*.*g\n",+#else+#if INT_LONG+                          "OPTIONS->User_Delta_Parameter[%ld] = %*.*g\n",+#else+                          "OPTIONS->User_Delta_Parameter[%d] = %*.*g\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION,+                          OPTIONS->User_Delta_Parameter[index_v]);+  fprintf (ptr_asa_out, "\n");+#endif /* DELTA_PARAMETERS */++#if QUENCH_PARAMETERS+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          "OPTIONS->User_Quench_Param_Scale[%d] = %*.*g\n",+#else+#if INT_LONG+                          "OPTIONS->User_Quench_Param_Scale[%ld] = %*.*g\n",+#else+                          "OPTIONS->User_Quench_Param_Scale[%d] = %*.*g\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION,+                          OPTIONS->User_Quench_Param_Scale[index_v]);+#endif /* QUENCH_PARAMETERS */++#if QUENCH_COST+  fprintf (ptr_asa_out,+           "\nOPTIONS->User_Quench_Cost_Scale = %*.*g\n\n",+           G_FIELD, G_PRECISION, OPTIONS->User_Quench_Cost_Scale[0]);+#endif /* QUENCH_COST */++#if USER_INITIAL_PARAMETERS_TEMPS+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          "OPTIONS->User_Parameter_Temperature[%d] = %*.*g\n",+#else+#if INT_LONG+                          "OPTIONS->User_Parameter_Temperature[%ld] = %*.*g\n",+#else+                          "OPTIONS->User_Parameter_Temperature[%d] = %*.*g\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION,+                          initial_user_parameter_temp[index_v]);+#endif /* USER_INITIAL_PARAMETERS_TEMPS */++#if RATIO_TEMPERATURE_SCALES+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          "OPTIONS->User_Temperature_Ratio[%d] = %*.*g\n",+#else+#if INT_LONG+                          "OPTIONS->User_Temperature_Ratio[%ld] = %*.*g\n",+#else+                          "OPTIONS->User_Temperature_Ratio[%d] = %*.*g\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION,+                          OPTIONS->User_Temperature_Ratio[index_v]);+#endif /* RATIO_TEMPERATURE_SCALES */++#if USER_INITIAL_COST_TEMP+  fprintf (ptr_asa_out,+           "OPTIONS->User_Cost_Temperature[0] = %*.*g\n",+           G_FIELD, G_PRECISION, *initial_cost_temperature);+#endif /* USER_INITIAL_COST_TEMP */++  fflush (ptr_asa_out);+#endif /* ASA_PRINT */++#if MULTI_MIN+#if ASA_PRINT+  fprintf (ptr_asa_out, "\n");+  fprintf (ptr_asa_out, "Multi_Number = %d\n", OPTIONS->Multi_Number);+  fprintf (ptr_asa_out, "Multi_Specify = %d\n", OPTIONS->Multi_Specify);+#if ASA_RESOLUTION+#else+  VFOR (index_v) {+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "Multi_Grid[%d] = %*.*g\n",+#else+#if INT_LONG+             "Multi_Grid[%ld] = %*.*g\n",+#else+             "Multi_Grid[%d] = %*.*g\n",+#endif+#endif+             index_v, G_FIELD, G_PRECISION, OPTIONS->Multi_Grid[index_v]);+  }+#endif /* ASA_RESOLUTION */+  fprintf (ptr_asa_out, "\n");+  fflush (ptr_asa_out);+#endif /* ASA_PRINT */+#endif /* MULTI_MIN */++#if ASA_PARALLEL+#if ASA_PRINT+  fprintf (ptr_asa_out,+#if INT_LONG+           "Initial ASA_PARALLEL OPTIONS->\n\t Gener_Block = %ld\n\+ \t Gener_Block_Max = %ld\n \t Gener_Mov_Avr= %d\n\n",+#else+           "ASA_PARALLEL OPTIONS->\n\t Gener_Block = %d\n\+ \t Gener_Block_Max = %d\n \t Gener_Mov_Avr= %d\n\n",+#endif+           OPTIONS->Gener_Block, OPTIONS->Gener_Block_Max,+           OPTIONS->Gener_Mov_Avr);+#endif+#endif /* ASA_PARALLEL */++#if ASA_SAMPLE+#if ASA_PRINT+  fprintf (ptr_asa_out, "OPTIONS->Limit_Weights = %*.*g\n\n",+           G_FIELD, G_PRECISION, OPTIONS->Limit_Weights);+#endif+#endif+  if (OPTIONS->Asa_Recursive_Level > asa_recursive_max)+    asa_recursive_max = OPTIONS->Asa_Recursive_Level;+#if ASA_SAVE+  if (OPTIONS->Asa_Recursive_Level > 0)+    sprintf (asa_save_comm, "asa_save_%d", OPTIONS->Asa_Recursive_Level);+  else+    sprintf (asa_save_comm, "asa_save");+  if ((ptr_save = fopen (asa_save_comm, "r")) == NULL) {+    asa_read = FALSE;+  } else {+#if ASA_PRINT+    fprintf (ptr_asa_out, "\n\n\trestart after ASA_SAVE\n\n");+#endif+    fclose (ptr_save);+    asa_read = TRUE;++    /* give some value to avoid any problems with other OPTIONS */+#if USER_ACCEPTANCE_TEST+    OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =+#endif+      current_generated_state->cost+      = *initial_cost_temperature = *current_cost_temperature = 3.1416;+  }+#endif++  tmp_var_int = cost_function_test (current_generated_state->cost,+                                    current_generated_state->parameter,+                                    parameter_minimum,+                                    parameter_maximum, number_parameters,+                                    xnumber_parameters);++  /* compute temperature scales */+  tmp_var_db1 = -F_LOG ((OPTIONS->Temperature_Ratio_Scale));+  tmp_var_db2 = F_LOG (OPTIONS->Temperature_Anneal_Scale);+  temperature_scale =+    tmp_var_db1 * F_EXP (-tmp_var_db2 / *xnumber_parameters);++  /* set here in case not used */+  tmp_var_db = ZERO;++#if QUENCH_PARAMETERS+#if RATIO_TEMPERATURE_SCALES+  VFOR (index_v) temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP+#if QUENCH_PARAMETERS_SCALE+    (-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])+#else+    (-(tmp_var_db2)+#endif+     / *xnumber_parameters)+    * OPTIONS->User_Temperature_Ratio[index_v];+#else+  VFOR (index_v) temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP+#if QUENCH_PARAMETERS_SCALE+    (-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])+#else+    (-(tmp_var_db2)+#endif+     / *xnumber_parameters);+#endif /* RATIO_TEMPERATURE_SCALES */+#else /* QUENCH_PARAMETERS */+#if RATIO_TEMPERATURE_SCALES+  VFOR (index_v)+    temperature_scale_parameters[index_v] =+    tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters)+    * OPTIONS->User_Temperature_Ratio[index_v];+#else+  VFOR (index_v)+    temperature_scale_parameters[index_v] =+    tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters);+#endif /* RATIO_TEMPERATURE_SCALES */+#endif /* QUENCH_PARAMETERS */++#if USER_ACCEPTANCE_TEST+  OPTIONS->Cost_Temp_Scale =+#endif+    *temperature_scale_cost =+#if QUENCH_COST+#if QUENCH_COST_SCALE+    tmp_var_db1 * F_EXP (-(tmp_var_db2 * OPTIONS->User_Quench_Cost_Scale[0])+#else+    tmp_var_db1 * F_EXP (-(tmp_var_db2)+#endif+                         / *xnumber_parameters) *+    OPTIONS->Cost_Parameter_Scale_Ratio;+#else /* QUENCH_COST */+    tmp_var_db1 * F_EXP (-(tmp_var_db2)+                         / *xnumber_parameters) *+    OPTIONS->Cost_Parameter_Scale_Ratio;+#endif /* QUENCH_COST */++  /* set the initial index of parameter generations to 1 */+  VFOR (index_v) index_parameter_generations[index_v] = 1;++  /* test user-defined options before calling cost function */+  tmp_var_int = asa_test_asa_options (seed,+                                      parameter_initial_final,+                                      parameter_minimum,+                                      parameter_maximum,+                                      tangents,+                                      curvature,+                                      number_parameters,+                                      parameter_type,+                                      valid_state_generated_flag,+                                      exit_status, ptr_asa_out, OPTIONS);+  if (tmp_var_int > 0) {+#if ASA_PRINT+    fprintf (ptr_asa_out, "total number invalid OPTIONS = %d\n", tmp_var_int);+    fflush (ptr_asa_out);+#endif+    *exit_status = INVALID_USER_INPUT;+    goto EXIT_ASA;+  }+#if USER_INITIAL_COST_TEMP+#else+#if ASA_SAVE+  if (asa_read == TRUE)+    OPTIONS->Number_Cost_Samples = 1;+#endif+  /* calculate the average cost over samplings of the cost function */+  if (OPTIONS->Number_Cost_Samples < -1) {+    tmp_var_db1 = ZERO;+    tmp_var_db2 = ZERO;+    tmp_var_int = -OPTIONS->Number_Cost_Samples;+  } else {+    tmp_var_db1 = ZERO;+    tmp_var_int = OPTIONS->Number_Cost_Samples;+  }++  OPTIONS->Locate_Cost = 0;     /* initial cost temp */++  for (index_cost_constraint = 0;+       index_cost_constraint < tmp_var_int; ++index_cost_constraint) {+    *number_invalid_generated_states = 0;+    repeated_invalid_states = 0;+    OPTIONS->Sequential_Parameters = *start_sequence - 1;+    do {+      ++(*number_invalid_generated_states);+      generate_new_state (user_random_generator,+                          seed,+                          parameter_minimum,+                          parameter_maximum, current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                          initial_user_parameter_temp,+                          temperature_scale_parameters,+#endif+                          number_parameters,+                          parameter_type,+                          current_generated_state, last_saved_state, OPTIONS);+      *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+      OPTIONS->User_Acceptance_Flag = TRUE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+      tmp_var_db =+        user_cost_function (current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum,+                            tangents,+                            curvature,+                            number_parameters,+                            parameter_type,+                            valid_state_generated_flag, exit_status, OPTIONS);+      if (cost_function_test+          (tmp_var_db, current_generated_state->parameter,+           parameter_minimum, parameter_maximum, number_parameters,+           xnumber_parameters) == 0) {+        *exit_status = INVALID_COST_FUNCTION;+        goto EXIT_ASA;+      }++      ++repeated_invalid_states;+      if (repeated_invalid_states > OPTIONS->Limit_Invalid_Generated_States) {+        *exit_status = TOO_MANY_INVALID_STATES;+        goto EXIT_ASA;+      }+    }+    while (*valid_state_generated_flag == FALSE);+    --(*number_invalid_generated_states);++    if (OPTIONS->Number_Cost_Samples < -1) {+      tmp_var_db1 += tmp_var_db;+      tmp_var_db2 += (tmp_var_db * tmp_var_db);+    } else {+      tmp_var_db1 += fabs (tmp_var_db);+    }+  }+  if (OPTIONS->Number_Cost_Samples < -1) {+    tmp_var_db1 /= (double) tmp_var_int;+    tmp_var_db2 /= (double) tmp_var_int;+    tmp_var_db = sqrt (fabs ((tmp_var_db2 - tmp_var_db1 * tmp_var_db1)+                             * ((double) tmp_var_int+                                / ((double) tmp_var_int - ONE))))+      + (double) EPS_DOUBLE;+  } else {+    tmp_var_db = tmp_var_db1 / tmp_var_int;+  }++#if USER_ACCEPTANCE_TEST+  OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =+#endif+    *initial_cost_temperature = *current_cost_temperature = tmp_var_db;+#endif /* USER_INITIAL_COST_TEMP */++  /* set all parameters to the initial parameter values */+  VFOR (index_v)+    best_generated_state->parameter[index_v] =+    last_saved_state->parameter[index_v] =+    current_generated_state->parameter[index_v] =+    parameter_initial_final[index_v];++  OPTIONS->Locate_Cost = 1;     /* initial cost value */++  /* if using user's initial parameters */+  if (OPTIONS->User_Initial_Parameters == TRUE) {+    *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+    OPTIONS->User_Acceptance_Flag = TRUE;+    OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+#if ASA_SAVE+    if (asa_read == FALSE)+#endif+      current_generated_state->cost =+        user_cost_function (current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum,+                            tangents,+                            curvature,+                            number_parameters,+                            parameter_type,+                            valid_state_generated_flag, exit_status, OPTIONS);+    if (cost_function_test+        (current_generated_state->cost, current_generated_state->parameter,+         parameter_minimum, parameter_maximum, number_parameters,+         xnumber_parameters) == 0) {+      *exit_status = INVALID_COST_FUNCTION;+      goto EXIT_ASA;+    }+#if ASA_PRINT+    if (*valid_state_generated_flag == FALSE)+      fprintf (ptr_asa_out, "user's initial parameters generated \+FALSE *valid_state_generated_flag\n");+#endif+  } else {+    /* let asa generate valid initial parameters */+    repeated_invalid_states = 0;+    OPTIONS->Sequential_Parameters = *start_sequence - 1;+    do {+      ++(*number_invalid_generated_states);+      generate_new_state (user_random_generator,+                          seed,+                          parameter_minimum,+                          parameter_maximum, current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                          initial_user_parameter_temp,+                          temperature_scale_parameters,+#endif+                          number_parameters,+                          parameter_type,+                          current_generated_state, last_saved_state, OPTIONS);+      *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+      OPTIONS->User_Acceptance_Flag = TRUE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+      current_generated_state->cost =+        user_cost_function (current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum,+                            tangents,+                            curvature,+                            number_parameters,+                            parameter_type,+                            valid_state_generated_flag, exit_status, OPTIONS);+      if (cost_function_test+          (current_generated_state->cost,+           current_generated_state->parameter, parameter_minimum,+           parameter_maximum, number_parameters, xnumber_parameters) == 0) {+        *exit_status = INVALID_COST_FUNCTION;+        goto EXIT_ASA;+      }+      ++repeated_invalid_states;+      if (repeated_invalid_states > OPTIONS->Limit_Invalid_Generated_States) {+        *exit_status = TOO_MANY_INVALID_STATES;+        goto EXIT_ASA;+      }+    }+    while (*valid_state_generated_flag == FALSE);+    --(*number_invalid_generated_states);+  }                             /* OPTIONS->User_Initial_Parameters */++  /* set all states to the last one generated */+  VFOR (index_v) {+#if DROPPED_PARAMETERS+    /* ignore parameters that have too small a range */+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+#endif+    best_generated_state->parameter[index_v] =+      last_saved_state->parameter[index_v] =+      current_generated_state->parameter[index_v];+  }++  /* set all costs to the last one generated */+  best_generated_state->cost = last_saved_state->cost =+    current_generated_state->cost;++  *accepted_to_generated_ratio = ONE;++  /* do not calculate curvatures initially */+  *curvature_flag = FALSE;++#if ASA_PRINT+  fprintf (ptr_asa_out,+           "temperature_scale = %*.*g\n",+           G_FIELD, G_PRECISION, temperature_scale);+#if RATIO_TEMPERATURE_SCALES+#if ASA_PRINT_INTERMED+  VFOR (index_v) {+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "temperature_scale_parameters[%d] = %*.*g\n",+#else+#if INT_LONG+             "temperature_scale_parameters[%ld] = %*.*g\n",+#else+             "temperature_scale_parameters[%d] = %*.*g\n",+#endif+#endif+             index_v,+             G_FIELD, G_PRECISION, temperature_scale_parameters[index_v]);+  }+#endif+#else+  fprintf (ptr_asa_out,+           "temperature_scale_parameters[0] = %*.*g\n",+           G_FIELD, G_PRECISION, temperature_scale_parameters[0]);+#endif /* RATIO_TEMPERATURE_SCALES */+  fprintf (ptr_asa_out,+           "*temperature_scale_cost = %*.*g\n",+           G_FIELD, G_PRECISION, *temperature_scale_cost);+  fprintf (ptr_asa_out, "\n\n");++#if ASA_PRINT_INTERMED+  print_state (parameter_minimum,+               parameter_maximum,+               tangents,+               curvature,+               current_cost_temperature,+               current_user_parameter_temp,+               accepted_to_generated_ratio,+               number_parameters,+               curvature_flag,+               number_accepted,+               index_cost_acceptances,+               number_generated,+               number_invalid_generated_states,+               last_saved_state, best_generated_state, ptr_asa_out, OPTIONS);+#endif+  fprintf (ptr_asa_out, "\n");++  fflush (ptr_asa_out);+#endif++#if ASA_SAMPLE+#if ASA_PRINT+  fprintf (ptr_asa_out,+           ":SAMPLE:   n_accept   cost        cost_temp    bias_accept    \+ aver_weight\n");+  fprintf (ptr_asa_out,+           ":SAMPLE:   index      param[]     temp[]       bias_gener[]   \+ range[]\n");+#endif+#endif++  /* reset the current cost and the number of generations performed */+  *number_invalid_generated_states = 0;+  *best_number_generated_saved =+    *number_generated = *recent_number_generated = 0;+  OPTIONS->N_Generated = *number_generated;+  VFOR (index_v) {+    /* ignore parameters that have too small a range */+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    index_parameter_generations[index_v] = 1;+  }+#if USER_ACCEPTANCE_TEST+  OPTIONS->User_Acceptance_Flag = FALSE;+  OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif++#if ASA_QUEUE+#if ASA_PRINT+#if INT_ALLOC+  fprintf (ptr_asa_out, "OPTIONS->Queue_Size = %d\n", OPTIONS->Queue_Size);+#else+#if INT_LONG+  fprintf (ptr_asa_out, "OPTIONS->Queue_Size = %ld\n", OPTIONS->Queue_Size);+#else+  fprintf (ptr_asa_out, "OPTIONS->Queue_Size = %d\n", OPTIONS->Queue_Size);+#endif+#endif+  VFOR (index_v) {+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "Queue_Resolution[%d] = %*.*g\n",+#else+#if INT_LONG+             "Queue_Resolution[%ld] = %*.*g\n",+#else+             "Queue_Resolution[%d] = %*.*g\n",+#endif+#endif+             index_v,+             G_FIELD, G_PRECISION, OPTIONS->Queue_Resolution[index_v]);+  }+#endif /* ASA_PRINT */++  /* fill arrays to check allocated memory */+  for (queue = 0; queue < queue_size_tmp; ++queue) {+    VFOR (index_v) {+      if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+        continue;+      }+      queue_v = index_v + queue * (LONG_INT) (*number_parameters);+      save_queue_param[queue_v] = current_generated_state->parameter[index_v];+    }+    save_queue_cost[queue] = current_generated_state->cost;+    save_queue_flag[queue] = *valid_state_generated_flag;+  }+  save_queue = save_queue_indx = 0;+#endif /* ASA_QUEUE */++#if ASA_RESOLUTION+#if ASA_PRINT+  VFOR (index_v) {+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "Coarse_Resolution[%d] = %*.*g\n",+#else+#if INT_LONG+             "Coarse_Resolution[%ld] = %*.*g\n",+#else+             "Coarse_Resolution[%d] = %*.*g\n",+#endif+#endif+             index_v,+             G_FIELD, G_PRECISION, OPTIONS->Coarse_Resolution[index_v]);+  }+#endif /* ASA_PRINT */+#endif /* ASA_RESOLUTION */++#if MULTI_MIN+  multi_sort[OPTIONS->Multi_Number] = OPTIONS->Multi_Number;+  multi_cost[OPTIONS->Multi_Number] = current_generated_state->cost;+  VFOR (index_v) {+    multi_params[OPTIONS->Multi_Number][index_v] =+      current_generated_state->parameter[index_v];+  }+  for (multi_index = 0; multi_index < OPTIONS->Multi_Number; ++multi_index) {+    multi_sort[multi_index] = multi_index;+    multi_cost[multi_index] = OPTIONS->Multi_Cost[multi_index] =+      current_generated_state->cost;+    VFOR (index_v) {+      multi_params[multi_index][index_v] =+        OPTIONS->Multi_Params[multi_index][index_v] =+        current_generated_state->parameter[index_v];+    }+  }+#endif /* MULTI_MIN */++  OPTIONS->Sequential_Parameters = *start_sequence - 1;++  /* MAIN ANNEALING LOOP */+  while (((*number_accepted <= OPTIONS->Limit_Acceptances)+          || (OPTIONS->Limit_Acceptances == 0))+         && ((*number_generated <= OPTIONS->Limit_Generated)+             || (OPTIONS->Limit_Generated == 0))) {++    tmp_var_db1 = -F_LOG ((OPTIONS->Temperature_Ratio_Scale));++    /* compute temperature scales */+    tmp_var_db2 = F_LOG (OPTIONS->Temperature_Anneal_Scale);+    temperature_scale = tmp_var_db1 *+      F_EXP (-tmp_var_db2 / *xnumber_parameters);++#if QUENCH_PARAMETERS+#if RATIO_TEMPERATURE_SCALES+    VFOR (index_v)+      temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP+#if QUENCH_PARAMETERS_SCALE+      (-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])+#else+      (-(tmp_var_db2)+#endif+       / *xnumber_parameters)+      * OPTIONS->User_Temperature_Ratio[index_v];+#else+    VFOR (index_v)+      temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP+#if QUENCH_PARAMETERS_SCALE+      (-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])+#else+      (-(tmp_var_db2)+#endif+       / *xnumber_parameters);+#endif /* RATIO_TEMPERATURE_SCALES */+#else /* QUENCH_PARAMETERS */+#if RATIO_TEMPERATURE_SCALES+    VFOR (index_v)+      temperature_scale_parameters[index_v] =+      tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters)+      * OPTIONS->User_Temperature_Ratio[index_v];+#else+    VFOR (index_v)+      temperature_scale_parameters[index_v] =+      tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters);+#endif /* RATIO_TEMPERATURE_SCALES */+#endif /* QUENCH_PARAMETERS */++#if USER_ACCEPTANCE_TEST+    OPTIONS->Cost_Temp_Scale =+#endif+      *temperature_scale_cost =+#if QUENCH_COST+#if QUENCH_COST_SCALE+      tmp_var_db1 * F_EXP (-(tmp_var_db2 * OPTIONS->User_Quench_Cost_Scale[0])+#else+      tmp_var_db1 * F_EXP (-(tmp_var_db2)+#endif+                           / *xnumber_parameters) *+      OPTIONS->Cost_Parameter_Scale_Ratio;+#else /* QUENCH_COST */+      tmp_var_db1 * F_EXP (-(tmp_var_db2)+                           / *xnumber_parameters) *+      OPTIONS->Cost_Parameter_Scale_Ratio;+#endif /* QUENCH_COST */++    /* CALCULATE NEW TEMPERATURES */++    /* calculate new parameter temperatures */+    VFOR (index_v) {+      /* skip parameters with too small a range */+      if (PARAMETER_RANGE_TOO_SMALL (index_v))+        continue;++      log_new_temperature_ratio =+        -temperature_scale_parameters[index_v] *+        F_POW ((double) index_parameter_generations[index_v],+#if QUENCH_PARAMETERS+               OPTIONS->User_Quench_Param_Scale[index_v]+#else /* QUENCH_PARAMETERS */+               ONE+#endif /* QUENCH_PARAMETERS */+               / *xnumber_parameters);+      /* check (and correct) for too large an exponent */+      log_new_temperature_ratio = EXPONENT_CHECK (log_new_temperature_ratio);+      current_user_parameter_temp[index_v] =+        initial_user_parameter_temp[index_v]+        * F_EXP (log_new_temperature_ratio);++#if NO_PARAM_TEMP_TEST+      if (current_user_parameter_temp[index_v] < (double) EPS_DOUBLE)+        current_user_parameter_temp[index_v] = (double) EPS_DOUBLE;+#else+      /* check for too small a parameter temperature */+      if (current_user_parameter_temp[index_v] < (double) EPS_DOUBLE) {+        *exit_status = P_TEMP_TOO_SMALL;+        *index_exit_v = index_v;+        goto EXIT_ASA;+      }+#endif+    }++    /* calculate new cost temperature */+    log_new_temperature_ratio =+      -*temperature_scale_cost * F_POW ((double) *index_cost_acceptances,+#if QUENCH_COST+                                        OPTIONS->User_Quench_Cost_Scale[0]+#else+                                        ONE+#endif+                                        / *xnumber_parameters);+    log_new_temperature_ratio = EXPONENT_CHECK (log_new_temperature_ratio);+#if USER_ACCEPTANCE_TEST+    OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =+#endif+      *current_cost_temperature = *initial_cost_temperature+      * F_EXP (log_new_temperature_ratio);++#if NO_COST_TEMP_TEST+    if (*current_cost_temperature < (double) EPS_DOUBLE)+#if USER_ACCEPTANCE_TEST+      OPTIONS->Cost_Temp_Curr =+#endif+        *current_cost_temperature = (double) EPS_DOUBLE;+#else+    /* check for too small a cost temperature */+    if (*current_cost_temperature < (double) EPS_DOUBLE) {+      *exit_status = C_TEMP_TOO_SMALL;+      goto EXIT_ASA;+    }+#endif++#if ASA_SAVE+    if (asa_read == TRUE && OPTIONS->Asa_Recursive_Level == asa_recursive_max) {+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "asa_save_%d", OPTIONS->Asa_Recursive_Level);+      else+        sprintf (asa_save_comm, "asa_save");+      ptr_save = fopen (asa_save_comm, "r");++      fread (number_parameters, sizeof (ALLOC_INT), 1, ptr_save);+      fread (xnumber_parameters, sizeof (double), 1, ptr_save);+      fread (parameter_minimum, sizeof (double),+             *number_parameters, ptr_save);+      fread (parameter_maximum, sizeof (double),+             *number_parameters, ptr_save);+      fread (tangents, sizeof (double), *number_parameters, ptr_save);+      fread (current_user_parameter_temp, sizeof (double),+             *number_parameters, ptr_save);+      fread (initial_user_parameter_temp, sizeof (double),+             *number_parameters, ptr_save);+      fread (temperature_scale_parameters, sizeof (double),+             *number_parameters, ptr_save);++      fread (parameter_type, sizeof (int), *number_parameters, ptr_save);+      fread (&index_cost_repeat, sizeof (int), 1, ptr_save);+      fread (&asa_open, sizeof (int), 1, ptr_save);+      fread (&number_asa_open, sizeof (int), 1, ptr_save);+      fread (&recursive_asa_open, sizeof (int), 1, ptr_save);++      fread (current_cost_temperature, sizeof (double), 1, ptr_save);+      fread (initial_cost_temperature, sizeof (double), 1, ptr_save);+      fread (temperature_scale_cost, sizeof (double), 1, ptr_save);+      fread (accepted_to_generated_ratio, sizeof (double), 1, ptr_save);++      fread (curvature_flag, sizeof (int), 1, ptr_save);++      fread (seed, sizeof (LONG_INT), 1, ptr_save);+      fread (number_generated, sizeof (LONG_INT), 1, ptr_save);+      fread (number_accepted, sizeof (LONG_INT), 1, ptr_save);+      fread (number_acceptances_saved, sizeof (LONG_INT), 1, ptr_save);+      fread (recent_number_acceptances, sizeof (LONG_INT), 1, ptr_save);+      fread (recent_number_generated, sizeof (LONG_INT), 1, ptr_save);+      fread (number_invalid_generated_states, sizeof (LONG_INT), 1, ptr_save);+      fread (index_cost_acceptances, sizeof (LONG_INT), 1, ptr_save);+      fread (best_number_generated_saved, sizeof (LONG_INT), 1, ptr_save);+      fread (best_number_accepted_saved, sizeof (LONG_INT), 1, ptr_save);++      fread (index_parameter_generations, sizeof (LONG_INT),+             *number_parameters, ptr_save);++      fread (current_generated_state->parameter,+             sizeof (double), *number_parameters, ptr_save);+      fread (last_saved_state->parameter,+             sizeof (double), *number_parameters, ptr_save);+      fread (best_generated_state->parameter,+             sizeof (double), *number_parameters, ptr_save);+      fread (&(current_generated_state->cost), sizeof (double), 1, ptr_save);+      fread (&(last_saved_state->cost), sizeof (double), 1, ptr_save);+      fread (&(best_generated_state->cost), sizeof (double), 1, ptr_save);++      fread (&(OPTIONS->Limit_Acceptances), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Limit_Generated), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Limit_Invalid_Generated_States), sizeof (int),+             1, ptr_save);+      fread (&(OPTIONS->Accepted_To_Generated_Ratio), sizeof (double),+             1, ptr_save);+      fread (&(OPTIONS->Cost_Precision), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->Maximum_Cost_Repeat), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Number_Cost_Samples), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Temperature_Ratio_Scale), sizeof (double),+             1, ptr_save);+      fread (&(OPTIONS->Cost_Parameter_Scale_Ratio), sizeof (double),+             1, ptr_save);+      fread (&(OPTIONS->Temperature_Anneal_Scale), sizeof (double),+             1, ptr_save);+      fread (&(OPTIONS->Include_Integer_Parameters), sizeof (int),+             1, ptr_save);+      fread (&(OPTIONS->User_Initial_Parameters), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Sequential_Parameters), sizeof (ALLOC_INT), 1,+             ptr_save);+      fread (&(OPTIONS->Initial_Parameter_Temperature), sizeof (double), 1,+             ptr_save);+      fread (&(OPTIONS->Acceptance_Frequency_Modulus), sizeof (int), 1,+             ptr_save);+      fread (&(OPTIONS->Generated_Frequency_Modulus), sizeof (int), 1,+             ptr_save);+      fread (&(OPTIONS->Reanneal_Cost), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Reanneal_Parameters), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Delta_X), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->User_Tangents), sizeof (int), 1, ptr_save);++#if USER_INITIAL_COST_TEMP+      fread (&(OPTIONS->User_Cost_Temperature), sizeof (double), 1, ptr_save);+#endif+#if RATIO_TEMPERATURE_SCALES+      fread (OPTIONS->User_Temperature_Ratio, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if USER_INITIAL_PARAMETERS_TEMPS+      fread (OPTIONS->User_Parameter_Temperature, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if DELTA_PARAMETERS+      fread (OPTIONS->User_Delta_Parameter, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if QUENCH_PARAMETERS+      fread (OPTIONS->User_Quench_Param_Scale, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if QUENCH_COST+      fread (OPTIONS->User_Quench_Cost_Scale, sizeof (double), 1, ptr_save);+#endif+      fread (&(OPTIONS->N_Accepted), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->N_Generated), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Locate_Cost), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Immediate_Exit), sizeof (int), 1, ptr_save);+#if OPTIONAL_DATA_DBL+      fread (&(OPTIONS->Asa_Data_Dim_Dbl), sizeof (ALLOC_INT), 1, ptr_save);+      fread (OPTIONS->Asa_Data_Dbl, sizeof (double),+             OPTIONS->Asa_Data_Dim_Dbl, ptr_save);+#endif+      fread (&(OPTIONS->Random_Array_Dim), sizeof (ALLOC_INT), 1, ptr_save);+      fread (OPTIONS->Random_Array, sizeof (double),+             OPTIONS->Random_Array_Dim, ptr_save);+      fread (&(OPTIONS->Asa_Recursive_Level), sizeof (int), 1, ptr_save);+#if OPTIONAL_DATA_INT+      fread (&(OPTIONS->Asa_Data_Dim_Int), sizeof (ALLOC_INT), 1, ptr_save);+      fread (OPTIONS->Asa_Data_Int, sizeof (LONG_INT),+             OPTIONS->Asa_Data_Dim_Int, ptr_save);+#endif+#if OPTIONAL_DATA_PTR+      fread (&(OPTIONS->Asa_Data_Dim_Ptr), sizeof (ALLOC_INT), 1, ptr_save);+      if (OPTIONS->Asa_Recursive_Level == 0)+        fread (OPTIONS->Asa_Data_Ptr, sizeof (OPTIONAL_PTR_TYPE),+               OPTIONS->Asa_Data_Dim_Ptr, ptr_save);+#if ASA_TEMPLATE_SELFOPT+      if (OPTIONS->Asa_Recursive_Level == 1)+        fread (OPTIONS->Asa_Data_Ptr, sizeof (RECUR_OPTIONAL_PTR_TYPE),+               OPTIONS->Asa_Data_Dim_Ptr, ptr_save);+#endif+#endif+#if USER_ASA_OUT+      fread (OPTIONS->Asa_Out_File, sizeof (char), 1, ptr_save);+#endif+#if USER_COST_SCHEDULE+      fread (&(OPTIONS->Cost_Schedule), sizeof (char), 1, ptr_save);+#endif+#if USER_ACCEPT_ASYMP_EXP+      fread (&(OPTIONS->Asymp_Exp_Param), sizeof (double), 1, ptr_save);+#endif+#if USER_ACCEPTANCE_TEST+      fread (&(OPTIONS->Acceptance_Test), sizeof (char), 1, ptr_save);+      fread (&(OPTIONS->User_Acceptance_Flag), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Cost_Acceptance_Flag), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Cost_Temp_Curr), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->Cost_Temp_Init), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->Cost_Temp_Scale), sizeof (double), 1, ptr_save);+#endif+#if USER_GENERATING_FUNCTION+      fread (&(OPTIONS->Generating_Distrib), sizeof (char), 1, ptr_save);+#endif+#if USER_REANNEAL_COST+      fread (&(OPTIONS->Reanneal_Cost_Function), sizeof (char), 1, ptr_save);+#endif+#if USER_REANNEAL_PARAMETERS+      fread (&(OPTIONS->Reanneal_Params_Function), sizeof (char),+             1, ptr_save);+#endif+#if ASA_SAMPLE+      fread (&(OPTIONS->Bias_Acceptance), sizeof (double), 1, ptr_save);+      fread (OPTIONS->Bias_Generated, sizeof (double),+             *number_parameters, ptr_save);+      fread (&(OPTIONS->Average_Weights), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->Limit_Weights), sizeof (double), 1, ptr_save);+#endif+#if ASA_QUEUE+      fread (save_queue, sizeof (LONG_INT), 1, ptr_save);+      fread (save_queue_indx, sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Queue_Size), sizeof (ALLOC_INT), 1, ptr_save);+      fread (save_queue_flag, sizeof (int), save_queue, ptr_save);+      fread (save_queue_cost, sizeof (double), save_queue, ptr_save);+      fread (save_queue_param, sizeof (double),+             (*number_parameters) * (OPTIONS->Queue_Size), ptr_save);+#if ASA_RESOLUTION+#else+      fread (OPTIONS->Queue_Resolution, sizeof (double),+             *number_parameters, ptr_save);+#endif+#endif+#if ASA_RESOLUTION+      fread (OPTIONS->Coarse_Resolution, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if FITLOC+      fread (&(OPTIONS->Fit_Local), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Iter_Max), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Penalty), sizeof (double), 1, ptr_save);+#endif+#if MULTI_MIN+      fread (OPTIONS->Multi_Number, sizeof (int), 1, ptr_save);+      fread (OPTIONS->Multi_Grid,+             sizeof (double), *number_parameters, ptr_save);+      fread (&(OPTIONS->Multi_Specify), sizeof (int), 1, ptr_save);+      for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+           ++multi_index) {+        fread (&(OPTIONS->Multi_Cost[multi_index]), sizeof (double), 1,+               ptr_save);+        fread (&(OPTIONS->Multi_Params[multi_index]), sizeof (double),+               *number_parameters, ptr_save);+      }+#endif+#if ASA_PARALLEL+      fread (&parallel_generated, sizeof (LONG_INT), 1, ptr_save);+      fread (&parallel_block_max, sizeof (LONG_INT), 1, ptr_save);+      for (index_parallel = 0; index_parallel < parallel_block_max;+           ++index_parallel) {+        fread (gener_block_state[index_parallel].parameter,+               sizeof (double), *number_parameters, ptr_save);+        fread (&(gener_block_state[index_parallel].cost),+               sizeof (double), 1, ptr_save);+#if USER_ACCEPTANCE_TEST+        fread (&+               (gener_block_state[index_parallel].par_user_accept_flag),+               sizeof (int), 1, ptr_save);+        fread (&+               (gener_block_state[index_parallel].par_cost_accept_flag),+               sizeof (int), 1, ptr_save);+#endif+      }+      fread (&(OPTIONS->Gener_Mov_Avr), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Gener_Block), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Gener_Block_Max), sizeof (LONG_INT), 1, ptr_save);+#endif++      fclose (ptr_save);++      asa_read = FALSE;+#if ASA_PRINT+      print_state (parameter_minimum,+                   parameter_maximum,+                   tangents,+                   curvature,+                   current_cost_temperature,+                   current_user_parameter_temp,+                   accepted_to_generated_ratio,+                   number_parameters,+                   curvature_flag,+                   number_accepted,+                   index_cost_acceptances,+                   number_generated,+                   number_invalid_generated_states,+                   last_saved_state,+                   best_generated_state, ptr_asa_out, OPTIONS);+#endif /* ASA_PRINT */++#include "asa_opt"+#if ASA_SAVE_OPT+      if ((ptr_save_opt = fopen ("asa_save_opt", "r")) == NULL) {+#if INCL_STDOUT+        printf ("\n\n*** WARNING fopen asa_save_opt failed *** \n\n");+#endif /* INCL_STDOUT */+#if ASA_PRINT+        fprintf (ptr_asa_out,+                 "\n\n*** WARNING fopen asa_save_opt failed *** \n\n");+        fflush (ptr_asa_out);+#endif+      } else {+        fscanf (ptr_save_opt, "%s%s%s%s%s",+                read_if, read_FALSE, read_comm1, read_ASA_SAVE, read_comm2);+        if (strcmp (read_if, "#if") || strcmp (read_FALSE, "FALSE")+            || strcmp (read_comm1, "/*")+            || strcmp (read_ASA_SAVE, "ASA_SAVE")+            || strcmp (read_comm2, "*/")) {+#if INCL_STDOUT+          printf ("\n\n*** EXIT not asa_save_opt for this version *** \n\n");+#endif /* INCL_STDOUT */+#if ASA_PRINT+          fprintf (ptr_asa_out,+                   "\n\n*** not asa_save_opt for this version *** \n\n");+          fflush (ptr_asa_out);+#endif+          *exit_status = INVALID_USER_INPUT;+          goto EXIT_ASA;+        }+#if INT_LONG+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%ld", &read_long);+        OPTIONS->Limit_Acceptances = read_long;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%ld", &read_long);+        OPTIONS->Limit_Generated = read_long;+#else+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Limit_Acceptances = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Limit_Generated = read_int;+#endif+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Limit_Invalid_Generated_States = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Accepted_To_Generated_Ratio = read_double;++        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Cost_Precision = read_double;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Maximum_Cost_Repeat = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Number_Cost_Samples = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Temperature_Ratio_Scale = read_double;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Cost_Parameter_Scale_Ratio = read_double;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Temperature_Anneal_Scale = read_double;++        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Include_Integer_Parameters = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->User_Initial_Parameters = read_int;+#if INT_ALLOC+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Sequential_Parameters = read_int;+#else+#if INT_LONG+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%ld", &read_long);+        OPTIONS->Sequential_Parameters = read_long;+#else+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Sequential_Parameters = read_int;+#endif+#endif+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Initial_Parameter_Temperature = read_double;++        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Acceptance_Frequency_Modulus = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Generated_Frequency_Modulus = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Reanneal_Cost = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Reanneal_Parameters = read_int;++        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Delta_X = read_double;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->User_Tangents = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Curvature_0 = read_int;++        fclose (ptr_save_opt);+      }+#endif /* ASA_SAVE_OPT */++      goto SAVED_ASA;+    }+#endif /* ASA_SAVE */++    /* GENERATE NEW PARAMETERS */++    /* generate a new valid set of parameters */+#if ASA_PARALLEL+    /* *** ENTER CODE TO SPAWN OFF PARALLEL GENERATED STATES *** */++    /* check if need more memory allocated to gener_block_state */+    if (OPTIONS->Gener_Block_Max > parallel_block_max) {+      for (index_parallel = 0; index_parallel < parallel_block_max;+           ++index_parallel) {+        free (gener_block_state[index_parallel].parameter);+      }+      free (gener_block_state);++      if ((gener_block_state =+           (STATE *) calloc (OPTIONS->Gener_Block_Max,+                             sizeof (STATE))) == NULL) {+        strcpy (exit_msg, "asa(): gener_block_state");+        Exit_ASA (exit_msg);+        *exit_status = CALLOC_FAILED;+        return (-1);+      }++      parallel_block_max = OPTIONS->Gener_Block_Max;++      for (index_parallel = 0; index_parallel < parallel_block_max;+           ++index_parallel) {+        if ((gener_block_state[index_parallel].parameter =+             (double *) calloc (*number_parameters,+                                sizeof (double))) == NULL) {+          strcpy (exit_msg,+                  "asa(): gener_block_state[index_parallel].parameter");+          Exit_ASA (exit_msg);+          *exit_status = CALLOC_FAILED;+          return (-1);+        }+      }+    }+#if ASA_TEMPLATE_PARALLEL+    for (index_parallel = 0; index_parallel < OPTIONS->Gener_Block;+         ++index_parallel) {+#endif /* ASA_TEMPLATE_PARALLEL */+#endif /* ASA_PARALLEL */++      if (OPTIONS->Locate_Cost < 0) {+        OPTIONS->Locate_Cost = 12;      /* generate new state from new best */+      } else {+        OPTIONS->Locate_Cost = 2;       /* generate new state */+      }++      repeated_invalid_states = 0;+      do {+        ++(*number_invalid_generated_states);+        generate_new_state (user_random_generator,+                            seed,+                            parameter_minimum,+                            parameter_maximum, current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                            initial_user_parameter_temp,+                            temperature_scale_parameters,+#endif+                            number_parameters,+                            parameter_type,+                            current_generated_state,+                            last_saved_state, OPTIONS);++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = FALSE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+#if ASA_QUEUE+        /* Binary trees do not seem necessary since we are assuming+           that the cost function calculation is the bottleneck.+           However, see the MISC.DIR/asa_contrib file for+           source code for doubly-linked and hashed lists. */+        if (OPTIONS->Queue_Size == 0) {+          queue_new = 1;+        } else {+          queue_new = 1;+          for (queue = 0; queue < save_queue; ++queue) {+            save_queue_test = 0;+            VFOR (index_v) {+              if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+                ++save_queue_test;+              } else {+                queue_v = index_v + queue * (LONG_INT) (*number_parameters);+                if (fabs+                    (current_generated_state->parameter[index_v] -+                     save_queue_param[queue_v]) <=+                    (OPTIONS->Queue_Resolution[index_v] + EPS_DOUBLE)) {+                  ++save_queue_test;+                }+              }+            }+            if (save_queue_test == *number_parameters) {+              tmp_var_db = save_queue_cost[queue];+              *valid_state_generated_flag = save_queue_flag[queue];+              queue_new = 0;+              --(*number_generated);+#if ASA_PRINT_MORE+#if INT_LONG+              fprintf (ptr_asa_out, "ASA_QUEUE: %ld \t %*.*g\n",+                       OPTIONS->N_Generated,+                       G_FIELD, G_PRECISION, tmp_var_db);+#else+              fprintf (ptr_asa_out, "ASA_QUEUE: %d \t %*.*g\n",+                       OPTIONS->N_Generated,+                       G_FIELD, G_PRECISION, tmp_var_db);+#endif+#endif+              break;+            }+          }+        }+        if (queue_new == 1) {+          tmp_var_db =+            user_cost_function (current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum,+                                tangents,+                                curvature,+                                number_parameters,+                                parameter_type,+                                valid_state_generated_flag,+                                exit_status, OPTIONS);+          if (cost_function_test (tmp_var_db,+                                  current_generated_state->parameter,+                                  parameter_minimum,+                                  parameter_maximum,+                                  number_parameters,+                                  xnumber_parameters) == 0) {+            *exit_status = INVALID_COST_FUNCTION;+            goto EXIT_ASA;+          }+          if (OPTIONS->Queue_Size > 0) {        /* in case recursive use */+            VFOR (index_v) {+              if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+                continue;+              }+              queue_v = index_v + save_queue_indx+                * (LONG_INT) (*number_parameters);+              save_queue_param[queue_v] =+                current_generated_state->parameter[index_v];+            }+            save_queue_cost[save_queue_indx] = tmp_var_db;+            save_queue_flag[save_queue_indx]+              = *valid_state_generated_flag;++            ++save_queue;+            if (save_queue == (LONG_INT) OPTIONS->Queue_Size)+              --save_queue;++            ++save_queue_indx;+            if (save_queue_indx == (LONG_INT) OPTIONS->Queue_Size)+              save_queue_indx = 0;+          }+        }+#else /* ASA_QUEUE */+        tmp_var_db =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (tmp_var_db,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION;+          goto EXIT_ASA;+        }+#endif /* ASA_QUEUE */+        current_generated_state->cost = tmp_var_db;+        ++repeated_invalid_states;+        if (repeated_invalid_states > OPTIONS->Limit_Invalid_Generated_States) {+          *exit_status = TOO_MANY_INVALID_STATES;+          goto EXIT_ASA;+        }+      }+      while (*valid_state_generated_flag == FALSE);+      --(*number_invalid_generated_states);+#if ASA_PARALLEL+      gener_block_state[index_parallel].cost = current_generated_state->cost;+#if USER_ACCEPTANCE_TEST+      gener_block_state[index_parallel].par_user_accept_flag =+        OPTIONS->User_Acceptance_Flag;+      gener_block_state[index_parallel].par_cost_accept_flag =+        OPTIONS->Cost_Acceptance_Flag;+#endif+      VFOR (index_v) {+        /* ignore parameters with too small a range */+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+        gener_block_state[index_parallel].parameter[index_v] =+          current_generated_state->parameter[index_v];+      }+#if ASA_TEMPLATE_PARALLEL+    }+#endif /* ASA_TEMPLATE_PARALLEL */+    /* *** EXIT CODE SPAWNING OFF PARALLEL GENERATED STATES *** */+#endif /* ASA_PARALLEL */++    /* ACCEPT/REJECT NEW PARAMETERS */++#if ASA_PARALLEL+    for (sort_index = 0; sort_index < OPTIONS->Gener_Block; ++sort_index)+      parallel_sort[sort_index] = sort_index;+    qsort (parallel_sort, OPTIONS->Gener_Block, sizeof (LONG_INT),+           sort_parallel);++    for (sort_index = 0; sort_index < OPTIONS->Gener_Block; ++sort_index) {+      index_parallel = parallel_sort[sort_index];+      current_generated_state->cost = gener_block_state[index_parallel].cost;+#if USER_ACCEPTANCE_TEST+      OPTIONS->User_Acceptance_Flag =+        gener_block_state[index_parallel].par_user_accept_flag;+      OPTIONS->Cost_Acceptance_Flag =+        gener_block_state[index_parallel].par_cost_accept_flag;+#endif+      VFOR (index_v) {+        /* ignore parameters with too small a range */+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+        current_generated_state->parameter[index_v] =+          gener_block_state[index_parallel].parameter[index_v];+      }+#endif /* ASA_PARALLEL */+      /* decide to accept/reject the new state */+      accept_new_state (user_random_generator,+                        seed,+                        parameter_minimum,+                        parameter_maximum, current_cost_temperature,+#if ASA_SAMPLE+                        current_user_parameter_temp,+#endif+                        number_parameters,+                        recent_number_acceptances,+                        number_accepted,+                        index_cost_acceptances,+                        number_acceptances_saved,+                        recent_number_generated,+                        number_generated,+                        index_parameter_generations,+                        current_generated_state, last_saved_state,+#if ASA_SAMPLE+                        ptr_asa_out,+#endif+                        OPTIONS);++#if ASA_PARALLEL+#else+#if ASA_PIPE_FILE+#if INT_ALLOC+      fprintf (ptr_asa_pipe, "%d", *number_generated);+#else+#if INT_LONG+      fprintf (ptr_asa_pipe, "%ld", *number_generated);+#else+      fprintf (ptr_asa_pipe, "%d", *number_generated);+#endif+#endif+#if INT_ALLOC+      fprintf (ptr_asa_pipe, "\t%d", *number_accepted);+#else+#if INT_LONG+      fprintf (ptr_asa_pipe, "\t%ld", *number_accepted);+#else+      fprintf (ptr_asa_pipe, "\t%d", *number_accepted);+#endif+#endif+      fprintf (ptr_asa_pipe, "\t%g", best_generated_state->cost);+      VFOR (index_v)+        fprintf (ptr_asa_pipe, "\t%g",+                 best_generated_state->parameter[index_v]);+      fprintf (ptr_asa_pipe, "\t%g", *current_cost_temperature);+      VFOR (index_v)+        fprintf (ptr_asa_pipe, "\t%g", current_user_parameter_temp[index_v]);+      fprintf (ptr_asa_pipe, "\t%g", last_saved_state->cost);+      fprintf (ptr_asa_pipe, "\n");+      fflush (ptr_asa_pipe);+#endif /* ASA_PIPE_FILE */+#if INCL_STDOUT+#if ASA_PIPE+#if INT_ALLOC+      printf ("%d", *number_generated);+#else+#if INT_LONG+      printf ("%ld", *number_generated);+#else+      printf ("%d", *number_generated);+#endif+#endif+#if INT_ALLOC+      printf ("\t%d", *number_accepted);+#else+#if INT_LONG+      printf ("\t%ld", *number_accepted);+#else+      printf ("\t%d", *number_accepted);+#endif+#endif+      printf ("\t%g", best_generated_state->cost);+      VFOR (index_v)+        printf ("\t%g", best_generated_state->parameter[index_v]);+      printf ("\t%g", *current_cost_temperature);+      VFOR (index_v)+        printf ("\t%g", current_user_parameter_temp[index_v]);+      printf ("\n");+#endif /* ASA_PIPE */+#endif /* INCL_STDOUT */+#endif /* ASA_PARALLEL */++      /* calculate the ratio of acceptances to generated states */+      *accepted_to_generated_ratio =+        (double) (*recent_number_acceptances + 1) /+        (double) (*recent_number_generated + 1);++#if MULTI_MIN+      if (((OPTIONS->Multi_Specify == 0)+           && (current_generated_state->cost <= best_generated_state->cost))+          || ((OPTIONS->Multi_Specify == 1)+              && (current_generated_state->cost <+                  best_generated_state->cost))) {+#if ASA_RESOLUTION+        VFOR (index_v) {+          if (OPTIONS->Multi_Grid[index_v] <+              OPTIONS->Coarse_Resolution[index_v])+            OPTIONS->Multi_Grid[index_v] =+              OPTIONS->Coarse_Resolution[index_v];+        }+#endif /* ASA_RESOLUTION */+        VFOR (index_v) {+          if (OPTIONS->Multi_Grid[index_v] < EPS_DOUBLE)+            OPTIONS->Multi_Grid[index_v] = EPS_DOUBLE;+        }++        multi_test = 0;+        for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+             ++multi_index) {+          multi_test_cmp = 0;+          multi_test_dim = 0;+          VFOR (index_v) {+            if (PARAMETER_RANGE_TOO_SMALL (index_v))+              continue;+            ++multi_test_dim;+            if (fabs (current_generated_state->parameter[index_v]+                      - OPTIONS->Multi_Params[multi_index][index_v])+                < OPTIONS->Multi_Grid[index_v])+              ++multi_test_cmp;+          }+          if (multi_test_cmp == multi_test_dim)+            multi_test = 1;+          if (OPTIONS->Multi_Specify == 1)+            break;+        }++        if (multi_test == 0) {+          multi_cost[OPTIONS->Multi_Number] = current_generated_state->cost;+          VFOR (index_v) {+            multi_params[OPTIONS->Multi_Number][index_v] =+              current_generated_state->parameter[index_v];+          }+          for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+               ++multi_index) {+            multi_cost[multi_index] = OPTIONS->Multi_Cost[multi_index];+            VFOR (index_v) {+              multi_params[multi_index][index_v] =+                OPTIONS->Multi_Params[multi_index][index_v];+            }+          }++          qsort (multi_sort, OPTIONS->Multi_Number + 1, sizeof (int),+                 multi_compare);+          for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+               ++multi_index) {+            OPTIONS->Multi_Cost[multi_index] =+              multi_cost[multi_sort[multi_index]];+            VFOR (index_v) {+              OPTIONS->Multi_Params[multi_index][index_v] =+                multi_params[multi_sort[multi_index]][index_v];+            }+          }+        }+      }+#endif /* MULTI_MIN */++      /* CHECK FOR NEW MINIMUM */++      if (current_generated_state->cost < best_generated_state->cost) {+        /* NEW MINIMUM FOUND */++        OPTIONS->Locate_Cost = -1;++        /* reset the recent acceptances and generated counts */+#if ASA_PARALLEL+        parallel_generated = *recent_number_generated;+#endif+        *recent_number_acceptances = *recent_number_generated = 0;+        *best_number_generated_saved = *number_generated;+        *best_number_accepted_saved = *number_accepted;+        index_cost_repeat = 0;++        /* copy the current state into the best_generated state */+        best_generated_state->cost = current_generated_state->cost;+        VFOR (index_v) {+#if DROPPED_PARAMETERS+          /* ignore parameters that have too small a range */+          if (PARAMETER_RANGE_TOO_SMALL (index_v))+            continue;+#endif+          best_generated_state->parameter[index_v] =+            current_generated_state->parameter[index_v];+        }++        /* printout the new minimum state and value */+#if ASA_PRINT+        fprintf (ptr_asa_out,+#if INT_LONG+                 "best...->cost=%-*.*g  \+*number_accepted=%ld  *number_generated=%ld\n", G_FIELD, G_PRECISION, best_generated_state->cost,+#else+                 "best...->cost=%-*.*g  \+*number_accepted=%d  *number_generated=%d\n", G_FIELD, G_PRECISION, best_generated_state->cost,+#endif /* INT_LONG */+                 *number_accepted, *number_generated);+#if ASA_PARALLEL+        /* print OPTIONS->Gener_Block just used */+        fprintf (ptr_asa_out,+#if INT_LONG+                 "OPTIONS->Gener_Block = %ld\n",+#else+                 "OPTIONS->Gener_Block = %d\n",+#endif /* INT_LONG */+                 OPTIONS->Gener_Block);+#endif /* ASA_PARALLEL */+#if ASA_PRINT_MORE+#if INT_ALLOC+        fprintf (ptr_asa_out, "Present Random Seed = %d\n\n", *seed);+#else+#if INT_LONG+        fprintf (ptr_asa_out, "Present Random Seed = %ld\n\n", *seed);+#else+        fprintf (ptr_asa_out, "Present Random Seed = %d\n\n", *seed);+#endif+#endif+        print_state (parameter_minimum,+                     parameter_maximum,+                     tangents,+                     curvature,+                     current_cost_temperature,+                     current_user_parameter_temp,+                     accepted_to_generated_ratio,+                     number_parameters,+                     curvature_flag,+                     number_accepted,+                     index_cost_acceptances,+                     number_generated,+                     number_invalid_generated_states,+                     last_saved_state,+                     best_generated_state, ptr_asa_out, OPTIONS);+#endif /* ASA_PRINT_MORE */+        fflush (ptr_asa_out);+#endif /* ASA_PRINT */++#if ASA_PARALLEL+        /* leave index_parallel loop after new minimum */+        break;+#endif /* ASA_PARALLEL */+      }+#if ASA_PARALLEL+    }+#endif /* ASA_PARALLEL */++#if ASA_PARALLEL+    if (OPTIONS->Gener_Mov_Avr > 0) {+      OPTIONS->Gener_Block = (LONG_INT)+        ((((double) OPTIONS->Gener_Mov_Avr - ONE)+          * (double) (OPTIONS->Gener_Block) + (double) parallel_generated)+         / (double) (OPTIONS->Gener_Mov_Avr));+      OPTIONS->Gener_Block = MIN (OPTIONS->Gener_Block, parallel_block_max);+    }+#endif /* ASA_PARALLEL */++#if ASA_SAVE+    /* These writes are put here with these tests, instead of just+       after a new best state is found, to prevent any confusion with+       any parallel code that might be added by users. */+    if (*recent_number_acceptances == 0+        && *recent_number_generated == 0+        && *best_number_generated_saved == *number_generated+        && *best_number_accepted_saved == *number_accepted+        && OPTIONS->Asa_Recursive_Level == asa_recursive_max+        && index_cost_repeat == 0) {+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "asa_save_%d", OPTIONS->Asa_Recursive_Level);+      else+        sprintf (asa_save_comm, "asa_save");+      ptr_save = fopen (asa_save_comm, "w");++      fwrite (number_parameters, sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (xnumber_parameters, sizeof (double), 1, ptr_save);+      fwrite (parameter_minimum, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (parameter_maximum, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (tangents, sizeof (double), *number_parameters, ptr_save);+      fwrite (current_user_parameter_temp, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (initial_user_parameter_temp, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (temperature_scale_parameters, sizeof (double),+              *number_parameters, ptr_save);++      fwrite (parameter_type, sizeof (int), *number_parameters, ptr_save);+      fwrite (&index_cost_repeat, sizeof (int), 1, ptr_save);+      fwrite (&asa_open, sizeof (int), 1, ptr_save);+      fwrite (&number_asa_open, sizeof (int), 1, ptr_save);+      fwrite (&recursive_asa_open, sizeof (int), 1, ptr_save);++      fwrite (current_cost_temperature, sizeof (double), 1, ptr_save);+      fwrite (initial_cost_temperature, sizeof (double), 1, ptr_save);+      fwrite (temperature_scale_cost, sizeof (double), 1, ptr_save);+      fwrite (accepted_to_generated_ratio, sizeof (double), 1, ptr_save);++      fwrite (curvature_flag, sizeof (int), 1, ptr_save);++      fwrite (seed, sizeof (LONG_INT), 1, ptr_save);+      fwrite (number_generated, sizeof (LONG_INT), 1, ptr_save);+      fwrite (number_accepted, sizeof (LONG_INT), 1, ptr_save);+      fwrite (number_acceptances_saved, sizeof (LONG_INT), 1, ptr_save);+      fwrite (recent_number_acceptances, sizeof (LONG_INT), 1, ptr_save);+      fwrite (recent_number_generated, sizeof (LONG_INT), 1, ptr_save);+      fwrite (number_invalid_generated_states, sizeof (LONG_INT),+              1, ptr_save);+      fwrite (index_cost_acceptances, sizeof (LONG_INT), 1, ptr_save);+      fwrite (best_number_generated_saved, sizeof (LONG_INT), 1, ptr_save);+      fwrite (best_number_accepted_saved, sizeof (LONG_INT), 1, ptr_save);++      fwrite (index_parameter_generations, sizeof (LONG_INT),+              *number_parameters, ptr_save);++      fwrite (current_generated_state->parameter,+              sizeof (double), *number_parameters, ptr_save);+      fwrite (last_saved_state->parameter,+              sizeof (double), *number_parameters, ptr_save);+      fwrite (best_generated_state->parameter,+              sizeof (double), *number_parameters, ptr_save);+      fwrite (&(current_generated_state->cost), sizeof (double), 1, ptr_save);+      fwrite (&(last_saved_state->cost), sizeof (double), 1, ptr_save);+      fwrite (&(best_generated_state->cost), sizeof (double), 1, ptr_save);++      fwrite (&(OPTIONS->Limit_Acceptances), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Limit_Generated), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Limit_Invalid_Generated_States), sizeof (int),+              1, ptr_save);+      fwrite (&(OPTIONS->Accepted_To_Generated_Ratio), sizeof (double),+              1, ptr_save);+      fwrite (&(OPTIONS->Cost_Precision), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->Maximum_Cost_Repeat), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Number_Cost_Samples), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Temperature_Ratio_Scale), sizeof (double),+              1, ptr_save);+      fwrite (&(OPTIONS->Cost_Parameter_Scale_Ratio), sizeof (double),+              1, ptr_save);+      fwrite (&(OPTIONS->Temperature_Anneal_Scale), sizeof (double),+              1, ptr_save);+      fwrite (&(OPTIONS->Include_Integer_Parameters), sizeof (int),+              1, ptr_save);+      fwrite (&(OPTIONS->User_Initial_Parameters), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Sequential_Parameters), sizeof (ALLOC_INT), 1,+              ptr_save);+      fwrite (&(OPTIONS->Initial_Parameter_Temperature), sizeof (double), 1,+              ptr_save);+      fwrite (&(OPTIONS->Acceptance_Frequency_Modulus), sizeof (int), 1,+              ptr_save);+      fwrite (&(OPTIONS->Generated_Frequency_Modulus), sizeof (int), 1,+              ptr_save);+      fwrite (&(OPTIONS->Reanneal_Cost), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Reanneal_Parameters), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Delta_X), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->User_Tangents), sizeof (int), 1, ptr_save);++#if USER_INITIAL_COST_TEMP+      fwrite (&(OPTIONS->User_Cost_Temperature), sizeof (double),+              1, ptr_save);+#endif+#if RATIO_TEMPERATURE_SCALES+      fwrite (OPTIONS->User_Temperature_Ratio, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if USER_INITIAL_PARAMETERS_TEMPS+      fwrite (OPTIONS->User_Parameter_Temperature, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if DELTA_PARAMETERS+      fwrite (OPTIONS->User_Delta_Parameter, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if QUENCH_PARAMETERS+      fwrite (OPTIONS->User_Quench_Param_Scale, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if QUENCH_COST+      fwrite (OPTIONS->User_Quench_Cost_Scale, sizeof (double), 1, ptr_save);+#endif+      fwrite (&(OPTIONS->N_Accepted), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->N_Generated), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Locate_Cost), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Immediate_Exit), sizeof (int), 1, ptr_save);+#if OPTIONAL_DATA_DBL+      fwrite (&(OPTIONS->Asa_Data_Dim_Dbl), sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (OPTIONS->Asa_Data_Dbl, sizeof (double),+              OPTIONS->Asa_Data_Dim_Dbl, ptr_save);+#endif+      fwrite (&(OPTIONS->Random_Array_Dim), sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (OPTIONS->Random_Array, sizeof (double),+              OPTIONS->Random_Array_Dim, ptr_save);+      fwrite (&(OPTIONS->Asa_Recursive_Level), sizeof (int), 1, ptr_save);+#if OPTIONAL_DATA_INT+      fwrite (&(OPTIONS->Asa_Data_Dim_Int), sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (OPTIONS->Asa_Data_Int, sizeof (LONG_INT),+              OPTIONS->Asa_Data_Dim_Int, ptr_save);+#endif+#if OPTIONAL_DATA_PTR+      fwrite (&(OPTIONS->Asa_Data_Dim_Ptr), sizeof (ALLOC_INT), 1, ptr_save);+      if (OPTIONS->Asa_Recursive_Level == 0)+        fwrite (OPTIONS->Asa_Data_Ptr, sizeof (OPTIONAL_PTR_TYPE),+                OPTIONS->Asa_Data_Dim_Ptr, ptr_save);+#if ASA_TEMPLATE_SELFOPT+      if (OPTIONS->Asa_Recursive_Level == 1)+        fwrite (OPTIONS->Asa_Data_Ptr, sizeof (RECUR_OPTIONAL_PTR_TYPE),+                OPTIONS->Asa_Data_Dim_Ptr, ptr_save);+#endif+#endif+#if USER_ASA_OUT+      fwrite (OPTIONS->Asa_Out_File, sizeof (char), 1, ptr_save);+#endif+#if USER_COST_SCHEDULE+      fwrite (&(OPTIONS->Cost_Schedule), sizeof (char), 1, ptr_save);+#endif+#if USER_ACCEPT_ASYMP_EXP+      fwrite (&(OPTIONS->Asymp_Exp_Param), sizeof (double), 1, ptr_save);+#endif+#if USER_ACCEPTANCE_TEST+      fwrite (&(OPTIONS->Acceptance_Test), sizeof (char), 1, ptr_save);+      fwrite (&(OPTIONS->User_Acceptance_Flag), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Cost_Acceptance_Flag), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Cost_Temp_Curr), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->Cost_Temp_Init), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->Cost_Temp_Scale), sizeof (double), 1, ptr_save);+#endif+#if USER_GENERATING_FUNCTION+      fwrite (&(OPTIONS->Generating_Distrib), sizeof (char), 1, ptr_save);+#endif+#if USER_REANNEAL_COST+      fwrite (&(OPTIONS->Reanneal_Cost_Function), sizeof (char), 1, ptr_save);+#endif+#if USER_REANNEAL_PARAMETERS+      fwrite (&(OPTIONS->Reanneal_Params_Function), sizeof (char),+              1, ptr_save);+#endif+#if ASA_SAMPLE+      fwrite (&(OPTIONS->Bias_Acceptance), sizeof (double), 1, ptr_save);+      fwrite (OPTIONS->Bias_Generated, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (&(OPTIONS->Average_Weights), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->Limit_Weights), sizeof (double), 1, ptr_save);+#endif+#if ASA_QUEUE+      fwrite (save_queue, sizeof (LONG_INT), 1, ptr_save);+      fwrite (save_queue_indx, sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Queue_Size), sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (save_queue_flag, sizeof (int), save_queue, ptr_save);+      fwrite (save_queue_cost, sizeof (double), save_queue, ptr_save);+      fwrite (save_queue_param, sizeof (double),+              (*number_parameters) * (OPTIONS->Queue_Size), ptr_save);+#if ASA_RESOLUTION+#else+      fwrite (OPTIONS->Queue_Resolution, sizeof (double),+              *number_parameters, ptr_save);+#endif+#endif+#if ASA_RESOLUTION+      fwrite (OPTIONS->Coarse_Resolution, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if FITLOC+      fwrite (&(OPTIONS->Fit_Local), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Iter_Max), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Penalty), sizeof (double), 1, ptr_save);+#endif+#if MULTI_MIN+      fwrite (OPTIONS->Multi_Number, sizeof (int), 1, ptr_save);+      fwrite (OPTIONS->Multi_Grid,+              sizeof (double), *number_parameters, ptr_save);+      fwrite (&(OPTIONS->Multi_Specify), sizeof (int), 1, ptr_save);+      for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+           ++multi_index) {+        fwrite (&(OPTIONS->Multi_Cost[multi_index]), sizeof (double), 1,+                ptr_save);+        fwrite (&(OPTIONS->Multi_Params[multi_index]), sizeof (double),+                *number_parameters, ptr_save);+      }+#endif+#if ASA_PARALLEL+      fwrite (&parallel_generated, sizeof (LONG_INT), 1, ptr_save);+      fwrite (&parallel_block_max, sizeof (LONG_INT), 1, ptr_save);+      for (index_parallel = 0; index_parallel < parallel_block_max;+           ++index_parallel) {+        fwrite (gener_block_state[index_parallel].parameter,+                sizeof (double), *number_parameters, ptr_save);+        fwrite (&(gener_block_state[index_parallel].cost),+                sizeof (double), 1, ptr_save);+#if USER_ACCEPTANCE_TEST+        fwrite (&+                (gener_block_state[index_parallel].+                 par_user_accept_flag), sizeof (int), 1, ptr_save);+        fwrite (&+                (gener_block_state[index_parallel].+                 par_cost_accept_flag), sizeof (int), 1, ptr_save);+#endif+      }+      fwrite (&(OPTIONS->Gener_Mov_Avr), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Gener_Block), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Gener_Block_Max), sizeof (LONG_INT), 1, ptr_save);+#endif++      fclose (ptr_save);++    SAVED_ASA:+      ;++#if SYSTEM_CALL+#if ASA_SAVE_BACKUP+#if INT_LONG+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "/bin/cp asa_save_%d asa_save_%d.%ld",+                 OPTIONS->Asa_Recursive_Level,+                 OPTIONS->Asa_Recursive_Level, OPTIONS->N_Accepted);+      else+        sprintf (asa_save_comm, "/bin/cp asa_save asa_save.%ld",+                 OPTIONS->N_Accepted);+#else+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "/bin/cp asa_save_%d asa_save_%d.%d",+                 OPTIONS->Asa_Recursive_Level,+                 OPTIONS->Asa_Recursive_Level, OPTIONS->N_Accepted);+      else+        sprintf (asa_save_comm, "/bin/cp asa_save asa_save.%d",+                 OPTIONS->N_Accepted);+#endif+      ptr_comm = popen (asa_save_comm, "r");+      pclose (ptr_comm);+#else /* ASA_SAVE_BACKUP */+      /* extra protection in case run aborts during write */+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "/bin/cp asa_save_%d asa_save_%d.old",+                 OPTIONS->Asa_Recursive_Level, OPTIONS->Asa_Recursive_Level);+      else+        sprintf (asa_save_comm, "/bin/cp asa_save asa_save.old");+      ptr_comm = popen (asa_save_comm, "r");+      pclose (ptr_comm);+#endif /* ASA_SAVE_BACKUP */+#endif /* SYSTEM_CALL */+    }+#endif /* ASA_SAVE */++    if (OPTIONS->Immediate_Exit == TRUE) {+      *exit_status = IMMEDIATE_EXIT;+      goto EXIT_ASA;+    }++    /* PERIODIC TESTING/REANNEALING/PRINTING SECTION */++    if (OPTIONS->Acceptance_Frequency_Modulus == 0)+      tmp_var_int1 = FALSE;+    else if ((int) (*number_accepted %+                    ((LONG_INT) OPTIONS->Acceptance_Frequency_Modulus)) == 0+             && *number_acceptances_saved == *number_accepted)+      tmp_var_int1 = TRUE;+    else+      tmp_var_int1 = FALSE;++    if (OPTIONS->Generated_Frequency_Modulus == 0)+      tmp_var_int2 = FALSE;+    else if ((int) (*number_generated %+                    ((LONG_INT) OPTIONS->Generated_Frequency_Modulus)) == 0)+      tmp_var_int2 = TRUE;+    else+      tmp_var_int2 = FALSE;++    if (tmp_var_int1 == TRUE || tmp_var_int2 == TRUE+        || (*accepted_to_generated_ratio+            < OPTIONS->Accepted_To_Generated_Ratio)) {+      if (*accepted_to_generated_ratio+          < (OPTIONS->Accepted_To_Generated_Ratio))+        *recent_number_acceptances = *recent_number_generated = 0;++      /* if best.cost repeats OPTIONS->Maximum_Cost_Repeat then exit */+      if (OPTIONS->Maximum_Cost_Repeat != 0) {+        if (fabs (last_saved_state->cost - best_generated_state->cost)+            < OPTIONS->Cost_Precision) {+          ++index_cost_repeat;+          if (index_cost_repeat == (OPTIONS->Maximum_Cost_Repeat)) {+            *exit_status = COST_REPEATING;+            goto EXIT_ASA;+          }+        } else {+          index_cost_repeat = 0;+        }+      }++      if (OPTIONS->Reanneal_Parameters == TRUE) {+        OPTIONS->Locate_Cost = 3;       /* reanneal parameters */++        /* calculate tangents, not curvatures, to reanneal */+        *curvature_flag = FALSE;+        cost_derivatives (user_cost_function,+                          parameter_minimum,+                          parameter_maximum,+                          tangents,+                          curvature,+                          maximum_tangent,+                          number_parameters,+                          parameter_type,+                          exit_status,+                          curvature_flag,+                          valid_state_generated_flag,+                          number_invalid_generated_states,+                          current_generated_state,+                          best_generated_state, ptr_asa_out, OPTIONS);+        if (*exit_status == INVALID_COST_FUNCTION_DERIV) {+          goto EXIT_ASA;+        }+      }+#if USER_REANNEAL_COST+#else+      if (OPTIONS->Reanneal_Cost == 0 || OPTIONS->Reanneal_Cost == 1) {+        ;+      } else {+        immediate_flag = OPTIONS->Immediate_Exit;++        if (OPTIONS->Reanneal_Cost < -1) {+          tmp_var_int = -OPTIONS->Reanneal_Cost;+        } else {+          tmp_var_int = OPTIONS->Reanneal_Cost;+        }+        tmp_var_db1 = ZERO;+        tmp_var_db2 = ZERO;++        for (index_cost_constraint = 0;+             index_cost_constraint < tmp_var_int; ++index_cost_constraint) {+          OPTIONS->Locate_Cost = 4;     /* reanneal cost */++          *number_invalid_generated_states = 0;+          repeated_invalid_states = 0;+          OPTIONS->Sequential_Parameters = *start_sequence - 1;+          do {+            ++(*number_invalid_generated_states);+            generate_new_state (user_random_generator,+                                seed,+                                parameter_minimum,+                                parameter_maximum,+                                current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                                initial_user_parameter_temp,+                                temperature_scale_parameters,+#endif+                                number_parameters,+                                parameter_type,+                                current_generated_state,+                                last_saved_state, OPTIONS);+            *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+            OPTIONS->User_Acceptance_Flag = TRUE;+            OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif++#if ASA_QUEUE+            if (OPTIONS->Queue_Size == 0) {+              queue_new = 1;+            } else {+              queue_new = 1;+              for (queue = 0; queue < save_queue; ++queue) {+                save_queue_test = 0;+                VFOR (index_v) {+                  if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+                    ++save_queue_test;+                  } else {+                    queue_v = index_v + queue+                      * (LONG_INT) (*number_parameters);+                    if (fabs+                        (current_generated_state->+                         parameter[index_v] -+                         save_queue_param[queue_v]) <+                        (OPTIONS->Queue_Resolution[index_v] + EPS_DOUBLE)) {+                      ++save_queue_test;+                    }+                  }+                }+                if (save_queue_test == *number_parameters) {+                  tmp_var_db = save_queue_cost[queue];+                  *valid_state_generated_flag = save_queue_flag[queue];+                  queue_new = 0;+#if ASA_PRINT_MORE+#if INT_LONG+                  fprintf (ptr_asa_out,+                           "ASA_QUEUE: %ld \t %*.*g\n",+                           OPTIONS->N_Generated, G_FIELD,+                           G_PRECISION, tmp_var_db);+#else+                  fprintf (ptr_asa_out,+                           "ASA_QUEUE: %d \t %*.*g\n",+                           OPTIONS->N_Generated, G_FIELD,+                           G_PRECISION, tmp_var_db);+#endif+#endif+                  break;+                }+              }+            }+            if (queue_new == 1) {+              tmp_var_db =+                user_cost_function (current_generated_state->+                                    parameter, parameter_minimum,+                                    parameter_maximum, tangents,+                                    curvature, number_parameters,+                                    parameter_type,+                                    valid_state_generated_flag,+                                    exit_status, OPTIONS);+              if (cost_function_test+                  (tmp_var_db, current_generated_state->parameter,+                   parameter_minimum, parameter_maximum,+                   number_parameters, xnumber_parameters) == 0) {+                *exit_status = INVALID_COST_FUNCTION;+                goto EXIT_ASA;+              }+              if (OPTIONS->Queue_Size > 0) {+                VFOR (index_v) {+                  if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+                    continue;+                  }+                  queue_v = index_v + save_queue+                    * (LONG_INT) (*number_parameters);+                  save_queue_param[queue_v] =+                    current_generated_state->parameter[index_v];+                }+                save_queue_cost[save_queue] = tmp_var_db;+                save_queue_flag[save_queue]+                  = *valid_state_generated_flag;++                ++save_queue;+                if (save_queue == (LONG_INT) OPTIONS->Queue_Size)+                  --save_queue;++                ++save_queue_indx;+                if (save_queue_indx == (LONG_INT) OPTIONS->Queue_Size)+                  save_queue_indx = 0;+              }+            }+#else /* ASA_QUEUE */+            tmp_var_db =+              user_cost_function (current_generated_state->+                                  parameter, parameter_minimum,+                                  parameter_maximum, tangents,+                                  curvature, number_parameters,+                                  parameter_type,+                                  valid_state_generated_flag,+                                  exit_status, OPTIONS);+            if (cost_function_test+                (tmp_var_db, current_generated_state->parameter,+                 parameter_minimum, parameter_maximum,+                 number_parameters, xnumber_parameters) == 0) {+              *exit_status = INVALID_COST_FUNCTION;+              goto EXIT_ASA;+            }+#endif /* ASA_QUEUE */+            ++repeated_invalid_states;+            if (repeated_invalid_states >+                OPTIONS->Limit_Invalid_Generated_States) {+              *exit_status = TOO_MANY_INVALID_STATES;+              goto EXIT_ASA;+            }+          }+          while (*valid_state_generated_flag == FALSE);+          --(*number_invalid_generated_states);++          tmp_var_db1 += tmp_var_db;+          tmp_var_db2 += (tmp_var_db * tmp_var_db);+        }+        tmp_var_db1 /= (double) tmp_var_int;+        tmp_var_db2 /= (double) tmp_var_int;+        tmp_var_db =+          sqrt (fabs+                ((tmp_var_db2 -+                  tmp_var_db1 * tmp_var_db1) * ((double) tmp_var_int /+                                                ((double) tmp_var_int -+                                                 ONE))));+        if (OPTIONS->Reanneal_Cost < -1) {+          *current_cost_temperature = *initial_cost_temperature =+            tmp_var_db + (double) EPS_DOUBLE;+        } else {+          *initial_cost_temperature = tmp_var_db + (double) EPS_DOUBLE;+        }+        OPTIONS->Immediate_Exit = immediate_flag;+      }+#endif /* USER_REANNEAL_COST */++      reanneal (parameter_minimum,+                parameter_maximum,+                tangents,+                maximum_tangent,+                current_cost_temperature,+                initial_cost_temperature,+                temperature_scale_cost,+                current_user_parameter_temp,+                initial_user_parameter_temp,+                temperature_scale_parameters,+                number_parameters,+                parameter_type,+                index_cost_acceptances,+                index_parameter_generations,+                last_saved_state, best_generated_state, OPTIONS);+#if ASA_PRINT_INTERMED+#if ASA_PRINT+      print_state (parameter_minimum,+                   parameter_maximum,+                   tangents,+                   curvature,+                   current_cost_temperature,+                   current_user_parameter_temp,+                   accepted_to_generated_ratio,+                   number_parameters,+                   curvature_flag,+                   number_accepted,+                   index_cost_acceptances,+                   number_generated,+                   number_invalid_generated_states,+                   last_saved_state,+                   best_generated_state, ptr_asa_out, OPTIONS);++      fprintf (ptr_asa_out, "\n");+      fflush (ptr_asa_out);+#endif+#endif+    }+  }++  /* FINISHED ANNEALING and MINIMIZATION */++  *exit_status = NORMAL_EXIT;+EXIT_ASA:++  asa_exit_value = asa_exit (user_cost_function,+                             &final_cost,+                             parameter_initial_final,+                             parameter_minimum,+                             parameter_maximum,+                             tangents,+                             curvature,+                             maximum_tangent,+                             current_cost_temperature,+                             initial_user_parameter_temp,+                             current_user_parameter_temp,+                             accepted_to_generated_ratio,+                             number_parameters,+                             parameter_type,+                             valid_state_generated_flag,+                             exit_status,+                             index_exit_v,+                             start_sequence,+                             number_accepted,+                             best_number_accepted_saved,+                             index_cost_acceptances,+                             number_generated,+                             number_invalid_generated_states,+                             index_parameter_generations,+                             best_number_generated_saved,+                             current_generated_state,+                             last_saved_state,+                             best_generated_state, ptr_asa_out, OPTIONS);+  if (asa_exit_value == 9) {+    *exit_status = CALLOC_FAILED;+    return (-1);+  }++  free (curvature_flag);+  free (maximum_tangent);+  free (accepted_to_generated_ratio);+  free (temperature_scale_cost);+  free (current_cost_temperature);+  free (initial_cost_temperature);+  free (number_generated);+  free (best_number_generated_saved);+  free (recent_number_generated);+  free (number_accepted);+  free (recent_number_acceptances);+  free (index_cost_acceptances);+  free (number_acceptances_saved);+  free (best_number_accepted_saved);+  free (number_invalid_generated_states);+  free (current_generated_state->parameter);+  free (last_saved_state->parameter);+  free (best_generated_state->parameter);+  free (current_generated_state);+  free (last_saved_state);+  free (best_generated_state);+#if ASA_QUEUE+  free (save_queue_flag);+  free (save_queue_cost);+  free (save_queue_param);+#endif+#if MULTI_MIN+  for (multi_index = 0; multi_index <= OPTIONS->Multi_Number; ++multi_index)+    free (multi_params[multi_index]);+  free (multi_params);+  free (multi_sort);+  free (multi_cost);+#endif+#if ASA_PARALLEL+  for (index_parallel = 0; index_parallel < parallel_block_max;+       ++index_parallel) {+    free (gener_block_state[index_parallel].parameter);+  }+  free (gener_block_state);+  free (parallel_sort);+#endif+#if ASA_PIPE_FILE+  fclose (ptr_asa_pipe);+#endif+  free (initial_user_parameter_temp);+  free (index_exit_v);+  free (start_sequence);+  free (index_parameter_generations);+  free (current_user_parameter_temp);+  free (temperature_scale_parameters);+  if (recursive_asa_open == 0)+    asa_open = FALSE;+  return (final_cost);+}++/***********************************************************************+* asa_exit+*	This procedures copies the best parameters and cost into+*       final_cost and parameter_initial_final+***********************************************************************/+#if HAVE_ANSI+int+asa_exit (double (*user_cost_function)++           +          (double *, double *, double *, double *, double *, ALLOC_INT *,+           int *, int *, int *, USER_DEFINES *), double *final_cost,+          double *parameter_initial_final, double *parameter_minimum,+          double *parameter_maximum, double *tangents, double *curvature,+          double *maximum_tangent, double *current_cost_temperature,+          double *initial_user_parameter_temp,+          double *current_user_parameter_temp,+          double *accepted_to_generated_ratio,+          ALLOC_INT * number_parameters, int *parameter_type,+          int *valid_state_generated_flag, int *exit_status,+          ALLOC_INT * index_exit_v, ALLOC_INT * start_sequence,+          LONG_INT * number_accepted,+          LONG_INT * best_number_accepted_saved,+          LONG_INT * index_cost_acceptances, LONG_INT * number_generated,+          LONG_INT * number_invalid_generated_states,+          LONG_INT * index_parameter_generations,+          LONG_INT * best_number_generated_saved,+          STATE * current_generated_state, STATE * last_saved_state,+          STATE * best_generated_state, FILE * ptr_asa_out,+          USER_DEFINES * OPTIONS)+#else+int++asa_exit (user_cost_function,+          final_cost,+          parameter_initial_final,+          parameter_minimum,+          parameter_maximum,+          tangents,+          curvature,+          maximum_tangent,+          current_cost_temperature,+          initial_user_parameter_temp,+          current_user_parameter_temp,+          accepted_to_generated_ratio,+          number_parameters,+          parameter_type,+          valid_state_generated_flag,+          exit_status,+          index_exit_v,+          start_sequence,+          number_accepted,+          best_number_accepted_saved,+          index_cost_acceptances,+          number_generated,+          number_invalid_generated_states,+          index_parameter_generations,+          best_number_generated_saved,+          current_generated_state,+          last_saved_state, best_generated_state, ptr_asa_out, OPTIONS)+     double (*user_cost_function) ();+     double *final_cost;+     double *parameter_initial_final;+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *curvature;+     double *maximum_tangent;+     double *current_cost_temperature;+     double *initial_user_parameter_temp;+     double *current_user_parameter_temp;+     double *accepted_to_generated_ratio;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     int *valid_state_generated_flag;+     int *exit_status;+     ALLOC_INT *index_exit_v;+     ALLOC_INT *start_sequence;+     LONG_INT *number_accepted;+     LONG_INT *best_number_accepted_saved;+     LONG_INT *index_cost_acceptances;+     LONG_INT *number_generated;+     LONG_INT *number_invalid_generated_states;+     LONG_INT *index_parameter_generations;+     LONG_INT *best_number_generated_saved;+     STATE *current_generated_state;+     STATE *last_saved_state;+     STATE *best_generated_state;+     FILE *ptr_asa_out;+     USER_DEFINES *OPTIONS;+#endif+{+  ALLOC_INT index_v;            /* iteration index */+  int curvatureFlag;+  int exit_exit_status, tmp_locate;+#if MULTI_MIN+  int multi_index;+#endif++  tmp_locate = OPTIONS->Locate_Cost;++  /* return final function minimum and associated parameters */+  *final_cost = best_generated_state->cost;+  VFOR (index_v) {+    parameter_initial_final[index_v] =+      best_generated_state->parameter[index_v];+  }++  OPTIONS->N_Accepted = *best_number_accepted_saved;+  OPTIONS->N_Generated = *best_number_generated_saved;++#if MULTI_MIN+  for (multi_index = 0; multi_index < OPTIONS->Multi_Number; ++multi_index) {+    best_generated_state->cost = OPTIONS->Multi_Cost[multi_index];+    VFOR (index_v) {+      best_generated_state->parameter[index_v] =+        OPTIONS->Multi_Params[multi_index][index_v];+    }+#if ASA_PRINT+    fprintf (ptr_asa_out, "\n\t\t multi_index = %d\n", multi_index);+#endif /* ASA_PRINT */+#endif /* MULTI_MIN */+    if (*exit_status != TOO_MANY_INVALID_STATES+        && *exit_status != IMMEDIATE_EXIT+        && *exit_status != INVALID_USER_INPUT+        && *exit_status != INVALID_COST_FUNCTION+        && *exit_status != INVALID_COST_FUNCTION_DERIV) {+      if (OPTIONS->Curvature_0 != TRUE)+        OPTIONS->Locate_Cost = 5;       /* calc curvatures while exiting asa */++      /* calculate curvatures and tangents at best point */+      curvatureFlag = TRUE;+      cost_derivatives (user_cost_function,+                        parameter_minimum,+                        parameter_maximum,+                        tangents,+                        curvature,+                        maximum_tangent,+                        number_parameters,+                        parameter_type,+                        &exit_exit_status,+                        &curvatureFlag,+                        valid_state_generated_flag,+                        number_invalid_generated_states,+                        current_generated_state,+                        best_generated_state, ptr_asa_out, OPTIONS);+    }+#if ASA_PRINT+    if (exit_exit_status == INVALID_COST_FUNCTION_DERIV)+      fprintf (ptr_asa_out, "\n\n  in asa_exit: INVALID_COST_FUNCTION_DERIV");++    if (*exit_status != INVALID_USER_INPUT+        && *exit_status != INVALID_COST_FUNCTION+        && *exit_status != INVALID_COST_FUNCTION_DERIV)+      print_state (parameter_minimum,+                   parameter_maximum,+                   tangents,+                   curvature,+                   current_cost_temperature,+                   current_user_parameter_temp,+                   accepted_to_generated_ratio,+                   number_parameters,+                   &curvatureFlag,+                   number_accepted,+                   index_cost_acceptances,+                   number_generated,+                   number_invalid_generated_states,+                   last_saved_state,+                   best_generated_state, ptr_asa_out, OPTIONS);+#endif /* ASA_PRINT */++#if MULTI_MIN+  }+  best_generated_state->cost = OPTIONS->Multi_Cost[0];+  VFOR (index_v) {+    best_generated_state->parameter[index_v] =+      OPTIONS->Multi_Params[0][index_v];+  }+#endif /* MULTI_MIN */++#if ASA_PRINT+  switch (*exit_status) {+  case NORMAL_EXIT:+    fprintf (ptr_asa_out,+             "\n\n NORMAL_EXIT exit_status = %d\n", *exit_status);+    break;+  case P_TEMP_TOO_SMALL:+    fprintf (ptr_asa_out,+             "\n\n P_TEMP_TOO_SMALL exit_status = %d\n", *exit_status);+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "current_user_parameter_temp[%d] too small = %*.*g\n",+#else+#if INT_LONG+             "current_user_parameter_temp[%ld] too small = %*.*g\n",+#else+             "current_user_parameter_temp[%d] too small = %*.*g\n",+#endif+#endif+             *index_exit_v,+             G_FIELD, G_PRECISION,+             current_user_parameter_temp[*index_exit_v]);+    break;+  case C_TEMP_TOO_SMALL:+    fprintf (ptr_asa_out,+             "\n\n C_TEMP_TOO_SMALL exit_status = %d\n", *exit_status);+    fprintf (ptr_asa_out,+             "*current_cost_temperature too small = %*.*g\n",+             G_FIELD, G_PRECISION, *current_cost_temperature);+    break;+  case COST_REPEATING:+    fprintf (ptr_asa_out,+             "\n\n COST_REPEATING exit_status = %d\n", *exit_status);+    break;+  case TOO_MANY_INVALID_STATES:+    fprintf (ptr_asa_out,+             "\n\n  TOO_MANY_INVALID_STATES exit_status = %d\n",+             *exit_status);+    break;+  case IMMEDIATE_EXIT:+    fprintf (ptr_asa_out,+             "\n\n  IMMEDIATE_EXIT exit_status = %d\n", *exit_status);+    break;+  case INVALID_USER_INPUT:+    fprintf (ptr_asa_out,+             "\n\n  INVALID_USER_INPUT exit_status = %d\n", *exit_status);+    break;+  case INVALID_COST_FUNCTION:+    fprintf (ptr_asa_out,+             "\n\n  INVALID_COST_FUNCTION exit_status = %d\n", *exit_status);+    break;+  case INVALID_COST_FUNCTION_DERIV:+    fprintf (ptr_asa_out,+             "\n\n  INVALID_COST_FUNCTION_DERIV exit_status = %d\n",+             *exit_status);+    break;+  default:+    fprintf (ptr_asa_out, "\n\n ERR: no exit code available = %d\n",+             *exit_status);+  }++  switch (OPTIONS->Locate_Cost) {+  case 0:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, initial cost temperature\n",+             OPTIONS->Locate_Cost);+    break;+  case 1:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, initial cost value\n", OPTIONS->Locate_Cost);+    break;+  case 2:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, new generated state\n",+             OPTIONS->Locate_Cost);+    break;+  case 12:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, new generated state just after a new best state\n",+             OPTIONS->Locate_Cost);+    break;+  case 3:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, cost derivatives, reannealing parameters\n",+             OPTIONS->Locate_Cost);+    break;+  case 4:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, reannealing cost temperature\n",+             OPTIONS->Locate_Cost);+    break;+  case 5:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, calculating curvatures while exiting asa ()\n",+             OPTIONS->Locate_Cost);+    break;+  case -1:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, exited main asa () loop by user-defined OPTIONS\n",+             OPTIONS->Locate_Cost);+    break;+  default:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, no index available for Locate_Cost\n",+             OPTIONS->Locate_Cost);+  }++  if (*exit_status != INVALID_USER_INPUT+      && *exit_status != INVALID_COST_FUNCTION+      && *exit_status != INVALID_COST_FUNCTION_DERIV) {+    fprintf (ptr_asa_out,+             "final_cost = best_generated_state->cost = %-*.*g\n",+             G_FIELD, G_PRECISION, *final_cost);+#if INT_LONG+    fprintf (ptr_asa_out,+             "*number_accepted at best_generated_state->cost = %ld\n",+             *best_number_accepted_saved);+    fprintf (ptr_asa_out,+             "*number_generated at best_generated_state->cost = %ld\n",+             *best_number_generated_saved);+#else+    fprintf (ptr_asa_out,+             "*number_accepted at best_generated_state->cost = %d\n",+             *best_number_accepted_saved);+    fprintf (ptr_asa_out,+             "*number_generated at best_generated_state->cost = %d\n",+             *best_number_generated_saved);+#endif+  }+#endif++#if ASA_TEMPLATE_SELFOPT+  if (OPTIONS->Asa_Data_Dbl[0] > (double) MIN_DOUBLE)+    OPTIONS->Asa_Data_Dbl[1] = (double) (*best_number_generated_saved);+#endif++  /* reset OPTIONS->Sequential_Parameters */+  OPTIONS->Sequential_Parameters = *start_sequence;++#if ASA_PRINT+#if TIME_CALC+  /* print ending time */+  print_time ("asa_end", ptr_asa_out);+#endif+  fprintf (ptr_asa_out, "\n\n\n");+  fflush (ptr_asa_out);+  ptr_asa_out != stdout && fclose (ptr_asa_out);+#endif++  return (0);+}++/***********************************************************************+* generate_new_state+*       Generates a valid new state from the old state+***********************************************************************/+#if HAVE_ANSI+void++generate_new_state (double (*user_random_generator) (LONG_INT *),+                    LONG_INT * seed,+                    double *parameter_minimum,+                    double *parameter_maximum,+                    double *current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                    double *initial_user_parameter_temp,+                    double *temperature_scale_parameters,+#endif+                    ALLOC_INT * number_parameters,+                    int *parameter_type,+                    STATE * current_generated_state,+                    STATE * last_saved_state, USER_DEFINES * OPTIONS)+#else+void++generate_new_state (user_random_generator,+                    seed,+                    parameter_minimum,+                    parameter_maximum, current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                    initial_user_parameter_temp, temperature_scale_parameters,+#endif+                    number_parameters,+                    parameter_type,+                    current_generated_state, last_saved_state, OPTIONS)+     double (*user_random_generator) ();+     LONG_INT *seed;+     double *parameter_minimum;+     double *parameter_maximum;+     double *current_user_parameter_temp;+#if USER_GENERATING_FUNCTION+     double *initial_user_parameter_temp;+     double *temperature_scale_parameters;+#endif+     ALLOC_INT *number_parameters;+     int *parameter_type;+     STATE *current_generated_state;+     STATE *last_saved_state;+     USER_DEFINES *OPTIONS;+#endif+{+  ALLOC_INT index_v;+  double x;+  double parameter_v, min_parameter_v, max_parameter_v, temperature_v,+    parameter_range_v;+#if USER_GENERATING_FUNCTION+  double init_param_temp_v;+  double temp_scale_params_v;+#endif+#if ASA_RESOLUTION+  double xres, xint, xminus, xplus, dx, dxminus, dxplus;+#endif++  /* generate a new value for each parameter */+  VFOR (index_v) {+    if (OPTIONS->Sequential_Parameters >= -1) {+      ++OPTIONS->Sequential_Parameters;+      if (OPTIONS->Sequential_Parameters == *number_parameters)+        OPTIONS->Sequential_Parameters = 0;+      index_v = OPTIONS->Sequential_Parameters;+    }+    min_parameter_v = parameter_minimum[index_v];+    max_parameter_v = parameter_maximum[index_v];+    parameter_range_v = max_parameter_v - min_parameter_v;++    /* ignore parameters that have too small a range */+    if (fabs (parameter_range_v) < (double) EPS_DOUBLE)+      continue;++    temperature_v = current_user_parameter_temp[index_v];+#if USER_GENERATING_FUNCTION+    init_param_temp_v = initial_user_parameter_temp[index_v];+    temp_scale_params_v = temperature_scale_parameters[index_v];+#endif+    parameter_v = last_saved_state->parameter[index_v];++    /* Handle discrete parameters. */+#if ASA_RESOLUTION+    xres = OPTIONS->Coarse_Resolution[index_v];+    if (xres > EPS_DOUBLE) {+      min_parameter_v -= (xres / TWO);+      max_parameter_v += (xres / TWO);+      parameter_range_v = max_parameter_v - min_parameter_v;+    }+#endif /* ASA_RESOLUTION */+    if (INTEGER_PARAMETER (index_v)) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        min_parameter_v -= HALF;+        max_parameter_v += HALF;+        parameter_range_v = max_parameter_v - min_parameter_v;+      }+#if ASA_RESOLUTION+    }+#endif++    /* generate a new state x within the parameter bounds */+    for (;;) {+#if USER_GENERATING_FUNCTION+      x = OPTIONS->Generating_Distrib (seed,+                                       number_parameters,+                                       index_v,+                                       temperature_v,+                                       init_param_temp_v,+                                       temp_scale_params_v,+                                       parameter_v,+                                       parameter_range_v,+                                       last_saved_state->parameter, OPTIONS);+#else+      x = parameter_v+        + generate_asa_state (user_random_generator, seed, &temperature_v)+        * parameter_range_v;+#endif /* USER_GENERATING_FUNCTION */+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        xint = xres * (double) ((LONG_INT) (x / xres));+        xplus = xint + xres;+        xminus = xint - xres;+        dx = fabs (xint - x);+        dxminus = fabs (xminus - x);+        dxplus = fabs (xplus - x);++        if (dx < dxminus && dx < dxplus)+          x = xint;+        else if (dxminus < dxplus)+          x = xminus;+        else+          x = xplus;+      }+#endif /* ASA_RESOLUTION */++      /* exit the loop if within its valid parameter range */+      if (x <= max_parameter_v - (double) EPS_DOUBLE+          && x >= min_parameter_v + (double) EPS_DOUBLE)+        break;+    }++    /* Handle discrete parameters.+       You might have to check rounding on your machine. */+    if (INTEGER_PARAMETER (index_v)) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        if (x < min_parameter_v + HALF)+          x = min_parameter_v + HALF + (double) EPS_DOUBLE;+        if (x > max_parameter_v - HALF)+          x = max_parameter_v - HALF + (double) EPS_DOUBLE;++        if (x + HALF > ZERO) {+          x = (double) ((LONG_INT) (x + HALF));+        } else {+          x = (double) ((LONG_INT) (x - HALF));+        }+        if (x > parameter_maximum[index_v])+          x = parameter_maximum[index_v];+        if (x < parameter_minimum[index_v])+          x = parameter_minimum[index_v];+      }+#if ASA_RESOLUTION+    }+    if (xres > EPS_DOUBLE) {+      if (x < min_parameter_v + xres / TWO)+        x = min_parameter_v + xres / TWO + (double) EPS_DOUBLE;+      if (x > max_parameter_v - xres / TWO)+        x = max_parameter_v - xres / TWO + (double) EPS_DOUBLE;++      if (x > parameter_maximum[index_v])+        x = parameter_maximum[index_v];+      if (x < parameter_minimum[index_v])+        x = parameter_minimum[index_v];+    }+#endif /* ASA_RESOLUTION */++    /* save the newly generated value */+    current_generated_state->parameter[index_v] = x;++    if (OPTIONS->Sequential_Parameters >= 0)+      break;+  }++}++/***********************************************************************+* generate_asa_state+*       This function generates a single value according to the+*       ASA generating function and the passed temperature+***********************************************************************/+#if HAVE_ANSI+double++generate_asa_state (double (*user_random_generator) (LONG_INT *),+                    LONG_INT * seed, double *temp)+#else+double+generate_asa_state (user_random_generator, seed, temp)+     double (*user_random_generator) ();+     LONG_INT *seed;+     double *temp;+#endif+{+  double x, y, z;++  x = (*user_random_generator) (seed);+  y = x < HALF ? -ONE : ONE;+  z = y * *temp * (F_POW ((ONE + ONE / *temp), fabs (TWO * x - ONE)) - ONE);++  return (z);++}++/***********************************************************************+* accept_new_state+*	This procedure accepts or rejects a newly generated state,+*	depending on whether the difference between new and old+*	cost functions passes a statistical test. If accepted,+*	the current state is updated.+***********************************************************************/+#if HAVE_ANSI+void++accept_new_state (double (*user_random_generator) (LONG_INT *),+                  LONG_INT * seed,+                  double *parameter_minimum,+                  double *parameter_maximum, double *current_cost_temperature,+#if ASA_SAMPLE+                  double *current_user_parameter_temp,+#endif+                  ALLOC_INT * number_parameters,+                  LONG_INT * recent_number_acceptances,+                  LONG_INT * number_accepted,+                  LONG_INT * index_cost_acceptances,+                  LONG_INT * number_acceptances_saved,+                  LONG_INT * recent_number_generated,+                  LONG_INT * number_generated,+                  LONG_INT * index_parameter_generations,+                  STATE * current_generated_state, STATE * last_saved_state,+#if ASA_SAMPLE+                  FILE * ptr_asa_out,+#endif+                  USER_DEFINES * OPTIONS)+#else+void++accept_new_state (user_random_generator,+                  seed,+                  parameter_minimum,+                  parameter_maximum, current_cost_temperature,+#if ASA_SAMPLE+                  current_user_parameter_temp,+#endif+                  number_parameters,+                  recent_number_acceptances,+                  number_accepted,+                  index_cost_acceptances,+                  number_acceptances_saved,+                  recent_number_generated,+                  number_generated,+                  index_parameter_generations,+                  current_generated_state, last_saved_state,+#if ASA_SAMPLE+                  ptr_asa_out,+#endif+                  OPTIONS)+     double (*user_random_generator) ();+     LONG_INT *seed;+     double *parameter_minimum;+     double *parameter_maximum;+     double *current_cost_temperature;+#if ASA_SAMPLE+     double *current_user_parameter_temp;+#endif+     ALLOC_INT *number_parameters;+     LONG_INT *recent_number_acceptances;+     LONG_INT *number_accepted;+     LONG_INT *index_cost_acceptances;+     LONG_INT *number_acceptances_saved;+     LONG_INT *recent_number_generated;+     LONG_INT *number_generated;+     LONG_INT *index_parameter_generations;+     STATE *current_generated_state;+     STATE *last_saved_state;+#if ASA_SAMPLE+     FILE *ptr_asa_out;+#endif+     USER_DEFINES *OPTIONS;++#endif+{+#if USER_ACCEPTANCE_TEST+#else+  double delta_cost;+#if USER_ACCEPT_ASYMP_EXP+  double q;+#endif+#endif+  double prob_test, unif_test;+  double curr_cost_temp;+  ALLOC_INT index_v;+#if ASA_SAMPLE+  LONG_INT active_params;+  double weight_param_ind, weight_aver, range;+#endif++  /* update accepted and generated count */+  ++*number_acceptances_saved;+  ++*recent_number_generated;+  ++*number_generated;+  OPTIONS->N_Generated = *number_generated;++  /* increment the parameter index generation for each parameter */+  if (OPTIONS->Sequential_Parameters >= 0) {+    /* ignore parameters with too small a range */+    if (!PARAMETER_RANGE_TOO_SMALL (OPTIONS->Sequential_Parameters))+      ++index_parameter_generations[OPTIONS->Sequential_Parameters];+  } else {+    VFOR (index_v) {+      if (!PARAMETER_RANGE_TOO_SMALL (index_v))+        ++index_parameter_generations[index_v];+    }+  }++  /* effective cost function for testing acceptance criteria,+     calculate the cost difference and divide by the temperature */+  curr_cost_temp = *current_cost_temperature;+#if USER_ACCEPTANCE_TEST+  if (OPTIONS->Cost_Acceptance_Flag == TRUE) {+    if (OPTIONS->User_Acceptance_Flag == TRUE) {+      unif_test = ZERO;+      OPTIONS->User_Acceptance_Flag = FALSE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+    } else {+      unif_test = ONE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+    }+  } else {+    OPTIONS->Acceptance_Test (current_generated_state->cost,+                              parameter_minimum,+                              parameter_maximum, *number_parameters, OPTIONS);+    if (OPTIONS->User_Acceptance_Flag == TRUE) {+      unif_test = ZERO;+      OPTIONS->User_Acceptance_Flag = FALSE;+    } else {+      unif_test = ONE;+    }+  }+  prob_test = OPTIONS->Prob_Bias;+#else /* USER_ACCEPTANCE_TEST */++#if USER_COST_SCHEDULE+  curr_cost_temp =+    (OPTIONS->Cost_Schedule (*current_cost_temperature, OPTIONS)+     + (double) EPS_DOUBLE);+#endif+  delta_cost = (current_generated_state->cost - last_saved_state->cost)+    / (curr_cost_temp + (double) EPS_DOUBLE);++#if USER_ACCEPT_ASYMP_EXP+  q = OPTIONS->Asymp_Exp_Param;+  if (fabs (ONE - q) < (double) EPS_DOUBLE)+    prob_test = MIN (ONE, (F_EXP (EXPONENT_CHECK (-delta_cost))));+  else if ((ONE - (ONE - q) * delta_cost) < (double) EPS_DOUBLE)+    prob_test = MIN (ONE, (F_EXP (EXPONENT_CHECK (-delta_cost))));+  else+    prob_test = MIN (ONE, F_POW ((ONE - (ONE - q) * delta_cost),+                                 (ONE / (ONE - q))));+#else /* USER_ACCEPT_ASYMP_EXP */++#if USER_ACCEPT_THRESHOLD       /* USER_ACCEPT_THRESHOLD */+  prob_test = delta_cost <= 1.0 ? 1.0 : 0.0;+#else /* Metropolis */+  prob_test = MIN (ONE, (F_EXP (EXPONENT_CHECK (-delta_cost))));+#endif /* USER_ACCEPT_THRESHOLD */++#endif /* USER_ACCEPT_ASYMP_EXP */++  unif_test = (*user_random_generator) (seed);+#endif /* USER_ACCEPTANCE_TEST */++#if ASA_SAMPLE+  active_params = 0;+  weight_aver = ZERO;+  VFOR (index_v) {+    /* ignore parameters with too small a range */+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    ++active_params;+    range = parameter_maximum[index_v] - parameter_minimum[index_v];+    weight_param_ind = TWO * (fabs ((last_saved_state->parameter[index_v]+                                     -+                                     current_generated_state->+                                     parameter[index_v]) / range)+                              + current_user_parameter_temp[index_v])+      * F_LOG (ONE + ONE / current_user_parameter_temp[index_v]);+    weight_aver += weight_param_ind;+    OPTIONS->Bias_Generated[index_v] = ONE / weight_param_ind;+  }+  weight_aver /= (double) active_params;+  OPTIONS->Average_Weights = weight_aver;+  if (prob_test >= unif_test) {+    OPTIONS->Bias_Acceptance = prob_test;+  } else {+    OPTIONS->Bias_Acceptance = ONE - prob_test;+  }++#if ASA_PRINT+  if (OPTIONS->Limit_Weights < OPTIONS->Average_Weights) {+    fprintf (ptr_asa_out, ":SAMPLE#\n");+    if (prob_test >= unif_test) {+      fprintf (ptr_asa_out,+#if INT_LONG+               ":SAMPLE+ %10ld %*.*g %*.*g %*.*g %*.*g\n",+#else+               ":SAMPLE+ %10d %*.*g %*.*g %*.*g\n",+#endif+               OPTIONS->N_Accepted,+               G_FIELD, G_PRECISION, current_generated_state->cost,+               G_FIELD, G_PRECISION, *current_cost_temperature,+               G_FIELD, G_PRECISION, OPTIONS->Bias_Acceptance,+               G_FIELD, G_PRECISION, OPTIONS->Average_Weights);+      VFOR (index_v) {+        /* ignore parameters with too small a range */+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+        range = parameter_maximum[index_v] - parameter_minimum[index_v];+        fprintf (ptr_asa_out,+#if INT_ALLOC+                 ":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",+#else+#if INT_LONG+                 ":SAMPLE %11ld %*.*g %*.*g %*.*g %*.*g\n",+#else+                 ":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",+#endif+#endif+                 index_v,+                 G_FIELD, G_PRECISION,+                 current_generated_state->parameter[index_v], G_FIELD,+                 G_PRECISION, current_user_parameter_temp[index_v],+                 G_FIELD, G_PRECISION, OPTIONS->Bias_Generated[index_v],+                 G_FIELD, G_PRECISION, range);+      }+    } else {+      fprintf (ptr_asa_out,+#if INT_LONG+               ":SAMPLE %11ld %*.*g %*.*g %*.*g %*.*g\n",+#else+               ":SAMPLE %11d %*.*g %*.*g %*.*g\n",+#endif+               OPTIONS->N_Accepted,+               G_FIELD, G_PRECISION, last_saved_state->cost,+               G_FIELD, G_PRECISION, *current_cost_temperature,+               G_FIELD, G_PRECISION, OPTIONS->Bias_Acceptance,+               G_FIELD, G_PRECISION, OPTIONS->Average_Weights);+      VFOR (index_v) {+        /* ignore parameters with too small a range */+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+        range = parameter_maximum[index_v] - parameter_minimum[index_v];+        fprintf (ptr_asa_out,+#if INT_ALLOC+                 ":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",+#else+#if INT_LONG+                 ":SAMPLE %11ld %*.*g %*.*g %*.*g %*.*g\n",+#else+                 ":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",+#endif+#endif+                 index_v,+                 G_FIELD, G_PRECISION,+                 last_saved_state->parameter[index_v], G_FIELD,+                 G_PRECISION, current_user_parameter_temp[index_v],+                 G_FIELD, G_PRECISION, OPTIONS->Bias_Generated[index_v],+                 G_FIELD, G_PRECISION, range);+      }+    }+  }+#endif+#endif /* ASA_SAMPLE */++  /* accept/reject the new state */+  if (prob_test >= unif_test) {+    /* copy current state to the last saved state */++    last_saved_state->cost = current_generated_state->cost;+    VFOR (index_v) {+      /* ignore parameters with too small a range */+      if (PARAMETER_RANGE_TOO_SMALL (index_v))+        continue;+      last_saved_state->parameter[index_v] =+        current_generated_state->parameter[index_v];+    }++    /* update acceptance counts */+    ++*recent_number_acceptances;+    ++*number_accepted;+    ++*index_cost_acceptances;+    *number_acceptances_saved = *number_accepted;+    OPTIONS->N_Accepted = *number_accepted;+  }+}++/***********************************************************************+* reanneal+*	Readjust temperatures of generating and acceptance functions+***********************************************************************/+#if HAVE_ANSI+void++reanneal (double *parameter_minimum,+          double *parameter_maximum,+          double *tangents,+          double *maximum_tangent,+          double *current_cost_temperature,+          double *initial_cost_temperature,+          double *temperature_scale_cost,+          double *current_user_parameter_temp,+          double *initial_user_parameter_temp,+          double *temperature_scale_parameters,+          ALLOC_INT * number_parameters,+          int *parameter_type,+          LONG_INT * index_cost_acceptances,+          LONG_INT * index_parameter_generations,+          STATE * last_saved_state,+          STATE * best_generated_state, USER_DEFINES * OPTIONS)+#else+void++reanneal (parameter_minimum,+          parameter_maximum,+          tangents,+          maximum_tangent,+          current_cost_temperature,+          initial_cost_temperature,+          temperature_scale_cost,+          current_user_parameter_temp,+          initial_user_parameter_temp,+          temperature_scale_parameters,+          number_parameters,+          parameter_type,+          index_cost_acceptances,+          index_parameter_generations,+          last_saved_state, best_generated_state, OPTIONS)+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *maximum_tangent;+     double *current_cost_temperature;+     double *initial_cost_temperature;+     double *temperature_scale_cost;+     double *current_user_parameter_temp;+     double *initial_user_parameter_temp;+     double *temperature_scale_parameters;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     LONG_INT *index_cost_acceptances;+     LONG_INT *index_parameter_generations;+     STATE *last_saved_state;+     STATE *best_generated_state;+     USER_DEFINES *OPTIONS;+#endif+{+  ALLOC_INT index_v;+  int cost_test;+  double tmp_var_db3;+  double new_temperature;+  double log_new_temperature_ratio;+  double log_init_cur_temp_ratio;+  double temperature_rescale_power;+  double cost_best, cost_last;+  double tmp_dbl, tmp_dbl1;++  double xnumber_parameters[1];++  cost_test = cost_function_test (last_saved_state->cost,+                                  last_saved_state->parameter,+                                  parameter_minimum,+                                  parameter_maximum, number_parameters,+                                  xnumber_parameters);++  if (OPTIONS->Reanneal_Parameters == TRUE) {+    VFOR (index_v) {+      if (NO_REANNEAL (index_v))+        continue;++      /* use the temp double to prevent overflow */+      tmp_dbl = (double) index_parameter_generations[index_v];++      /* skip parameters with too small range or integer parameters */+      if (OPTIONS->Include_Integer_Parameters == TRUE) {+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+      } else {+        if (PARAMETER_RANGE_TOO_SMALL (index_v) ||+            INTEGER_PARAMETER (index_v))+          continue;+      }++      /* ignore parameters with too small tangents */+      if (fabs (tangents[index_v]) < (double) EPS_DOUBLE)+        continue;++      /* reset the index of parameter generations appropriately */+#if USER_REANNEAL_PARAMETERS+      new_temperature =+        fabs (OPTIONS->+              Reanneal_Params_Function (current_user_parameter_temp+                                        [index_v], tangents[index_v],+                                        *maximum_tangent, OPTIONS));+#else+      new_temperature =+        fabs (FUNCTION_REANNEAL_PARAMS+              (current_user_parameter_temp[index_v], tangents[index_v],+               *maximum_tangent));+#endif+      if (new_temperature < initial_user_parameter_temp[index_v]) {+        log_init_cur_temp_ratio =+          fabs (F_LOG (((double) EPS_DOUBLE+                        + initial_user_parameter_temp[index_v])+                       / ((double) EPS_DOUBLE + new_temperature)));+        tmp_dbl = (double) EPS_DOUBLE+          + F_POW (log_init_cur_temp_ratio+                   / temperature_scale_parameters[index_v],+                   *xnumber_parameters+#if QUENCH_PARAMETERS+                   / OPTIONS->User_Quench_Param_Scale[index_v]);+#else+          );+#endif+      } else {+        tmp_dbl = ONE;+      }++      /* Reset index_parameter_generations if index reset too large,+         and also reset the initial_user_parameter_temp, to achieve+         the same new temperature. */+      while (tmp_dbl > ((double) MAXIMUM_REANNEAL_INDEX)) {+        log_new_temperature_ratio =+          -temperature_scale_parameters[index_v] * F_POW (tmp_dbl,+#if QUENCH_PARAMETERS+                                                          OPTIONS->+                                                          User_Quench_Param_Scale+                                                          [index_v]+#else+                                                          ONE+#endif+                                                          /+                                                          *xnumber_parameters);+        log_new_temperature_ratio =+          EXPONENT_CHECK (log_new_temperature_ratio);+        new_temperature =+          initial_user_parameter_temp[index_v] *+          F_EXP (log_new_temperature_ratio);+        tmp_dbl /= (double) REANNEAL_SCALE;+        temperature_rescale_power = ONE / F_POW ((double) REANNEAL_SCALE,+#if QUENCH_PARAMETERS+                                                 OPTIONS->+                                                 User_Quench_Param_Scale+                                                 [index_v]+#else+                                                 ONE+#endif+                                                 / *xnumber_parameters);+        initial_user_parameter_temp[index_v] =+          new_temperature * F_POW (initial_user_parameter_temp[index_v] /+                                   new_temperature,+                                   temperature_rescale_power);+      }+      /* restore from temporary double */+      index_parameter_generations[index_v] = (LONG_INT) tmp_dbl;+    }+  }++  if (OPTIONS->Reanneal_Cost == 0) {+    ;+  } else if (OPTIONS->Reanneal_Cost < -1) {+    *index_cost_acceptances = 1;+  } else {+    /* reanneal : Reset the current cost temp and rescale the+       index of cost acceptances. */++    cost_best = best_generated_state->cost;+    cost_last = last_saved_state->cost;+#if USER_REANNEAL_COST+    cost_test = OPTIONS->Reanneal_Cost_Function (&cost_best,+                                                 &cost_last,+                                                 initial_cost_temperature,+                                                 current_cost_temperature,+                                                 OPTIONS);+    tmp_dbl1 = *current_cost_temperature;+#else+    cost_test = TRUE;+    if (OPTIONS->Reanneal_Cost == 1) {+      /* (re)set the initial cost_temperature */+      tmp_dbl = MAX (fabs (cost_last), fabs (cost_best));+      tmp_dbl = MAX (tmp_dbl, fabs (cost_best - cost_last));+      tmp_dbl = MAX ((double) EPS_DOUBLE, tmp_dbl);+      *initial_cost_temperature = MIN (*initial_cost_temperature, tmp_dbl);+    }++    tmp_dbl = (double) *index_cost_acceptances;++    tmp_dbl1 = MAX (fabs (cost_last - cost_best), *current_cost_temperature);+    tmp_dbl1 = MAX ((double) EPS_DOUBLE, tmp_dbl1);+    tmp_dbl1 = MIN (tmp_dbl1, *initial_cost_temperature);+#endif /* USER_REANNEAL_COST */+    if (cost_test == TRUE && (*current_cost_temperature > tmp_dbl1)) {+      tmp_var_db3 =+        fabs (F_LOG (((double) EPS_DOUBLE + *initial_cost_temperature) /+                     (tmp_dbl1)));+      tmp_dbl = (double) EPS_DOUBLE + F_POW (tmp_var_db3+                                             / *temperature_scale_cost,+                                             *xnumber_parameters+#if QUENCH_COST+                                             /+                                             OPTIONS->+                                             User_Quench_Cost_Scale[0]);+#else+        );+#endif+    } else {+      log_init_cur_temp_ratio =+        fabs (F_LOG (((double) EPS_DOUBLE + *initial_cost_temperature) /+                     ((double) EPS_DOUBLE + *current_cost_temperature)));+      tmp_dbl = (double) EPS_DOUBLE+        + F_POW (log_init_cur_temp_ratio+                 / *temperature_scale_cost, *xnumber_parameters+#if QUENCH_COST+                 / OPTIONS->User_Quench_Cost_Scale[0]+#else+#endif+        );+    }++    /* reset index_cost_temperature if index reset too large */+    while (tmp_dbl > ((double) MAXIMUM_REANNEAL_INDEX)) {+      log_new_temperature_ratio = -*temperature_scale_cost * F_POW (tmp_dbl,+#if QUENCH_COST+                                                                    OPTIONS->+                                                                    User_Quench_Cost_Scale+                                                                    [0]+#else+                                                                    ONE+#endif+                                                                    /+                                                                    *xnumber_parameters);+      log_new_temperature_ratio = EXPONENT_CHECK (log_new_temperature_ratio);+      new_temperature =+        *initial_cost_temperature * F_EXP (log_new_temperature_ratio);+      tmp_dbl /= (double) REANNEAL_SCALE;+      temperature_rescale_power = ONE / F_POW ((double) REANNEAL_SCALE,+#if QUENCH_COST+                                               OPTIONS->+                                               User_Quench_Cost_Scale[0]+#else+                                               ONE+#endif+                                               / *xnumber_parameters);+      *initial_cost_temperature =+        new_temperature * F_POW (*initial_cost_temperature /+                                 new_temperature, temperature_rescale_power);+    }+    *index_cost_acceptances = (LONG_INT) tmp_dbl;+#if USER_ACCEPTANCE_TEST+    OPTIONS->Cost_Temp_Init = *initial_cost_temperature;+#endif+  }+}++/***********************************************************************+* cost_derivatives+*	This procedure calculates the derivatives of the cost function+*	with respect to its parameters.  The first derivatives are+*	used as a sensitivity measure for reannealing.  The second+*	derivatives are calculated only if *curvature_flag=TRUE;+*	these are a measure of the covariance of the fit when a+*	minimum is found.+***********************************************************************/+  /* Calculate the numerical derivatives of the best+     generated state found so far */++  /* In this implementation of ASA, no checks are made for+   *valid_state_generated_flag=FALSE for differential neighbors+   to the current best state. */++  /* Assuming no information is given about the metric of the parameter+     space, use simple Cartesian space to calculate curvatures. */++#if HAVE_ANSI+void+cost_derivatives (double (*user_cost_function)++                   +                  (double *, double *, double *, double *, double *,+                   ALLOC_INT *, int *, int *, int *, USER_DEFINES *),+                  double *parameter_minimum, double *parameter_maximum,+                  double *tangents, double *curvature,+                  double *maximum_tangent, ALLOC_INT * number_parameters,+                  int *parameter_type, int *exit_status,+                  int *curvature_flag, int *valid_state_generated_flag,+                  LONG_INT * number_invalid_generated_states,+                  STATE * current_generated_state,+                  STATE * best_generated_state, FILE * ptr_asa_out,+                  USER_DEFINES * OPTIONS)+#else+void++cost_derivatives (user_cost_function,+                  parameter_minimum,+                  parameter_maximum,+                  tangents,+                  curvature,+                  maximum_tangent,+                  number_parameters,+                  parameter_type,+                  exit_status,+                  curvature_flag,+                  valid_state_generated_flag,+                  number_invalid_generated_states,+                  current_generated_state,+                  best_generated_state, ptr_asa_out, OPTIONS)+     double (*user_cost_function) ();+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *curvature;+     double *maximum_tangent;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     int *exit_status;+     int *curvature_flag;+     int *valid_state_generated_flag;+     LONG_INT *number_invalid_generated_states;+     STATE *current_generated_state;+     STATE *best_generated_state;+     FILE *ptr_asa_out;+     USER_DEFINES *OPTIONS;+#endif+{+  ALLOC_INT index_v, index_vv, index_v_vv, index_vv_v;+  LONG_INT saved_num_invalid_gen_states;+#if ASA_PRINT+  LONG_INT tmp_saved;+#endif+  double parameter_v, parameter_vv, parameter_v_offset, parameter_vv_offset;+  double recent_best_cost;+  double new_cost_state_1, new_cost_state_2, new_cost_state_3;+  double delta_parameter_v, delta_parameter_vv;+  int immediate_flag;+  double xnumber_parameters[1];++  if (OPTIONS->Curvature_0 == TRUE)+    *curvature_flag = FALSE;+  if (OPTIONS->Curvature_0 == -1)+    *curvature_flag = TRUE;++  /* save Immediate_Exit flag */+  immediate_flag = OPTIONS->Immediate_Exit;++  /* save the best cost */+  recent_best_cost = best_generated_state->cost;++  /* copy the best state into the current state */+  VFOR (index_v) {+    /* ignore parameters with too small ranges */+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    current_generated_state->parameter[index_v] =+      best_generated_state->parameter[index_v];+  }++  saved_num_invalid_gen_states = (*number_invalid_generated_states);++  /* set parameters (& possibly constraints) to best state */+  *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+  OPTIONS->User_Acceptance_Flag = TRUE;+  OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+  current_generated_state->cost =+    user_cost_function (current_generated_state->parameter,+                        parameter_minimum,+                        parameter_maximum,+                        tangents,+                        curvature,+                        number_parameters,+                        parameter_type,+                        valid_state_generated_flag, exit_status, OPTIONS);+  if (cost_function_test (current_generated_state->cost,+                          current_generated_state->parameter,+                          parameter_minimum,+                          parameter_maximum, number_parameters,+                          xnumber_parameters) == 0) {+    *exit_status = INVALID_COST_FUNCTION_DERIV;+    return;+  }+  if (*valid_state_generated_flag == FALSE)+    ++(*number_invalid_generated_states);++  if (OPTIONS->User_Tangents == TRUE) {+    *valid_state_generated_flag = FALSE;+#if USER_ACCEPTANCE_TEST+    OPTIONS->User_Acceptance_Flag = TRUE;+    OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+    current_generated_state->cost =+      user_cost_function (current_generated_state->parameter,+                          parameter_minimum,+                          parameter_maximum,+                          tangents,+                          curvature,+                          number_parameters,+                          parameter_type,+                          valid_state_generated_flag, exit_status, OPTIONS);+    if (cost_function_test (current_generated_state->cost,+                            current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum, number_parameters,+                            xnumber_parameters) == 0) {+      *exit_status = INVALID_COST_FUNCTION_DERIV;+      return;+    }+    if (*valid_state_generated_flag == FALSE)+      ++(*number_invalid_generated_states);+  } else {+    /* calculate tangents */+    VFOR (index_v) {+      if (NO_REANNEAL (index_v)) {+        tangents[index_v] = ZERO;+        continue;+      }+      /* skip parameters with too small range or integer parameters */+      if (OPTIONS->Include_Integer_Parameters == TRUE) {+        if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+          tangents[index_v] = ZERO;+          continue;+        }+      } else {+        if (PARAMETER_RANGE_TOO_SMALL (index_v) ||+            INTEGER_PARAMETER (index_v)) {+          tangents[index_v] = ZERO;+          continue;+        }+      }++      /* save the v_th parameter and delta_parameter */+      parameter_v = best_generated_state->parameter[index_v];+#if DELTA_PARAMETERS+      delta_parameter_v = OPTIONS->User_Delta_Parameter[index_v];+#else+      delta_parameter_v = OPTIONS->Delta_X;+#endif++      parameter_v_offset = (ONE + delta_parameter_v) * parameter_v;+      if (parameter_v_offset > parameter_maximum[index_v] ||+          parameter_v_offset < parameter_minimum[index_v]) {+        delta_parameter_v = -delta_parameter_v;+        parameter_v_offset = (ONE + delta_parameter_v) * parameter_v;+      }++      /* generate the first sample point */+      current_generated_state->parameter[index_v] = parameter_v_offset;+      *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+      OPTIONS->User_Acceptance_Flag = TRUE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+      current_generated_state->cost =+        user_cost_function (current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum,+                            tangents,+                            curvature,+                            number_parameters,+                            parameter_type,+                            valid_state_generated_flag, exit_status, OPTIONS);+      if (cost_function_test+          (current_generated_state->cost,+           current_generated_state->parameter, parameter_minimum,+           parameter_maximum, number_parameters, xnumber_parameters) == 0) {+        *exit_status = INVALID_COST_FUNCTION_DERIV;+        return;+      }+      if (*valid_state_generated_flag == FALSE)+        ++(*number_invalid_generated_states);+      new_cost_state_1 = current_generated_state->cost;++      /* restore the parameter state */+      current_generated_state->parameter[index_v] = parameter_v;++      /* calculate the numerical derivative */+      tangents[index_v] = (new_cost_state_1 - recent_best_cost)+        / (delta_parameter_v * parameter_v + (double) EPS_DOUBLE);++    }+  }++  /* find the maximum |tangent| from all tangents */+  *maximum_tangent = 0;+  VFOR (index_v) {+    if (NO_REANNEAL (index_v))+      continue;++    /* ignore too small ranges and integer parameters types */+    if (OPTIONS->Include_Integer_Parameters == TRUE) {+      if (PARAMETER_RANGE_TOO_SMALL (index_v))+        continue;+    } else {+      if (PARAMETER_RANGE_TOO_SMALL (index_v)+          || INTEGER_PARAMETER (index_v))+        continue;+    }++    /* find the maximum |tangent| (from all tangents) */+    if (fabs (tangents[index_v]) > *maximum_tangent) {+      *maximum_tangent = fabs (tangents[index_v]);+    }+  }++  if (*curvature_flag == TRUE || *curvature_flag == -1) {+    /* calculate diagonal curvatures */+    VFOR (index_v) {+      if (NO_REANNEAL (index_v)) {+        index_v_vv = ROW_COL_INDEX (index_v, index_v);+        curvature[index_v_vv] = ZERO;+        continue;+      }+      /* skip parameters with too small range or integer parameters */+      if (OPTIONS->Include_Integer_Parameters == TRUE) {+        if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+          index_v_vv = ROW_COL_INDEX (index_v, index_v);+          curvature[index_v_vv] = ZERO;+          continue;+        }+      } else {+        if (PARAMETER_RANGE_TOO_SMALL (index_v) ||+            INTEGER_PARAMETER (index_v)) {+          index_v_vv = ROW_COL_INDEX (index_v, index_v);+          curvature[index_v_vv] = ZERO;+          continue;+        }+      }++      /* save the v_th parameter and delta_parameter */+      parameter_v = best_generated_state->parameter[index_v];+#if DELTA_PARAMETERS+      delta_parameter_v = OPTIONS->User_Delta_Parameter[index_v];+#else+      delta_parameter_v = OPTIONS->Delta_X;+#endif++      if (parameter_v + delta_parameter_v * fabs (parameter_v)+          > parameter_maximum[index_v]) {+        /* generate the first sample point */+        current_generated_state->parameter[index_v] =+          parameter_v - TWO * delta_parameter_v * fabs (parameter_v);+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_1 = current_generated_state->cost;++        /* generate the second sample point */+        current_generated_state->parameter[index_v] =+          parameter_v - delta_parameter_v * fabs (parameter_v);++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_2 = current_generated_state->cost;++        /* restore the parameter state */+        current_generated_state->parameter[index_v] = parameter_v;++        /* index_v_vv: row index_v, column index_v */+        index_v_vv = ROW_COL_INDEX (index_v, index_v);++        /* calculate and store the curvature */+        curvature[index_v_vv] =+          (recent_best_cost - TWO * new_cost_state_2+           + new_cost_state_1) / (delta_parameter_v * delta_parameter_v+                                  * parameter_v * parameter_v ++                                  (double) EPS_DOUBLE);+      } else if (parameter_v - delta_parameter_v * fabs (parameter_v)+                 < parameter_minimum[index_v]) {+        /* generate the first sample point */+        current_generated_state->parameter[index_v] =+          parameter_v + TWO * delta_parameter_v * fabs (parameter_v);+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_1 = current_generated_state->cost;++        /* generate the second sample point */+        current_generated_state->parameter[index_v] =+          parameter_v + delta_parameter_v * fabs (parameter_v);++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_2 = current_generated_state->cost;++        /* restore the parameter state */+        current_generated_state->parameter[index_v] = parameter_v;++        /* index_v_vv: row index_v, column index_v */+        index_v_vv = ROW_COL_INDEX (index_v, index_v);++        /* calculate and store the curvature */+        curvature[index_v_vv] =+          (recent_best_cost - TWO * new_cost_state_2+           + new_cost_state_1) / (delta_parameter_v * delta_parameter_v+                                  * parameter_v * parameter_v ++                                  (double) EPS_DOUBLE);+      } else {+        /* generate the first sample point */+        parameter_v_offset = (ONE + delta_parameter_v) * parameter_v;+        current_generated_state->parameter[index_v] = parameter_v_offset;+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_1 = current_generated_state->cost;++        /* generate the second sample point */+        current_generated_state->parameter[index_v] =+          (ONE - delta_parameter_v) * parameter_v;++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_2 = current_generated_state->cost;++        /* restore the parameter state */+        current_generated_state->parameter[index_v] = parameter_v;++        /* index_v_vv: row index_v, column index_v */+        index_v_vv = ROW_COL_INDEX (index_v, index_v);++        /* calculate and store the curvature */+        curvature[index_v_vv] =+          (new_cost_state_2 - TWO * recent_best_cost+           + new_cost_state_1) / (delta_parameter_v * delta_parameter_v+                                  * parameter_v * parameter_v ++                                  (double) EPS_DOUBLE);+      }+    }++    /* calculate off-diagonal curvatures */+    VFOR (index_v) {+      /* save the v_th parameter and delta_x */+      parameter_v = current_generated_state->parameter[index_v];+#if DELTA_PARAMETERS+      delta_parameter_v = OPTIONS->User_Delta_Parameter[index_v];+#else+      delta_parameter_v = OPTIONS->Delta_X;+#endif++      VFOR (index_vv) {+        /* index_v_vv: row index_v, column index_vv */+        index_v_vv = ROW_COL_INDEX (index_v, index_vv);+        index_vv_v = ROW_COL_INDEX (index_vv, index_v);++        if (NO_REANNEAL (index_vv) || NO_REANNEAL (index_v)) {+          curvature[index_vv_v] = curvature[index_v_vv] = ZERO;+          continue;+        }++        /* calculate only the upper diagonal */+        if (index_v <= index_vv)+          continue;++        /* skip parms with too small range or integer parameters */+        if (OPTIONS->Include_Integer_Parameters == TRUE) {+          if (PARAMETER_RANGE_TOO_SMALL (index_v) ||+              PARAMETER_RANGE_TOO_SMALL (index_vv)) {+            curvature[index_vv_v] = curvature[index_v_vv] = ZERO;+            continue;+          }+        } else {+          if (INTEGER_PARAMETER (index_v) ||+              INTEGER_PARAMETER (index_vv) ||+              PARAMETER_RANGE_TOO_SMALL (index_v) ||+              PARAMETER_RANGE_TOO_SMALL (index_vv)) {+            curvature[index_vv_v] = curvature[index_v_vv] = ZERO;+            continue;+          }+        }+        /* save the vv_th parameter and delta_parameter */+        parameter_vv = current_generated_state->parameter[index_vv];+#if DELTA_PARAMETERS+        delta_parameter_vv = OPTIONS->User_Delta_Parameter[index_vv];+#else+        delta_parameter_vv = OPTIONS->Delta_X;+#endif++        /* generate first sample point */+        parameter_v_offset = current_generated_state->parameter[index_v] =+          (ONE + delta_parameter_v) * parameter_v;+        parameter_vv_offset = current_generated_state->parameter[index_vv] =+          (ONE + delta_parameter_vv) * parameter_vv;+        if (parameter_v_offset > parameter_maximum[index_v] ||+            parameter_v_offset < parameter_minimum[index_v]) {+          delta_parameter_v = -delta_parameter_v;+          current_generated_state->parameter[index_v] =+            (ONE + delta_parameter_v) * parameter_v;+        }+        if (parameter_vv_offset > parameter_maximum[index_vv] ||+            parameter_vv_offset < parameter_minimum[index_vv]) {+          delta_parameter_vv = -delta_parameter_vv;+          current_generated_state->parameter[index_vv] =+            (ONE + delta_parameter_vv) * parameter_vv;+        }++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_1 = current_generated_state->cost;++        /* restore the v_th parameter */+        current_generated_state->parameter[index_v] = parameter_v;++        /* generate second sample point */+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_2 = current_generated_state->cost;++        /* restore the vv_th parameter */+        current_generated_state->parameter[index_vv] = parameter_vv;++        /* generate third sample point */+        current_generated_state->parameter[index_v] =+          (ONE + delta_parameter_v) * parameter_v;+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_3 = current_generated_state->cost;++        /* restore the v_th parameter */+        current_generated_state->parameter[index_v] = parameter_v;++        /* calculate and store the curvature */+        curvature[index_vv_v] = curvature[index_v_vv] =+          (new_cost_state_1 - new_cost_state_2+           - new_cost_state_3 + recent_best_cost)+          / (delta_parameter_v * delta_parameter_vv+             * parameter_v * parameter_vv + (double) EPS_DOUBLE);+      }+    }+  }++  /* restore Immediate_Exit flag */+  OPTIONS->Immediate_Exit = immediate_flag;++  /* restore the best cost function value */+  current_generated_state->cost = recent_best_cost;+#if ASA_PRINT+  tmp_saved = *number_invalid_generated_states - saved_num_invalid_gen_states;+  if (tmp_saved > 0)+#if INT_LONG+    fprintf (ptr_asa_out,+             "Generated %ld invalid states when calculating the derivatives\n",+             tmp_saved);+#else+    fprintf (ptr_asa_out,+             "Generated %d invalid states when calculating the derivatives\n",+             tmp_saved);+#endif+#endif /* ASA_PRINT */+  *number_invalid_generated_states = saved_num_invalid_gen_states;+#if USER_ACCEPTANCE_TEST+  OPTIONS->User_Acceptance_Flag = TRUE;+  OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+}++/***********************************************************************+* asa_test_asa_options+*       Tests user's selected options+***********************************************************************/+#if HAVE_ANSI+int++asa_test_asa_options (LONG_INT * seed,+                      double *parameter_initial_final,+                      double *parameter_minimum,+                      double *parameter_maximum,+                      double *tangents,+                      double *curvature,+                      ALLOC_INT * number_parameters,+                      int *parameter_type,+                      int *valid_state_generated_flag,+                      int *exit_status,+                      FILE * ptr_asa_out, USER_DEFINES * OPTIONS)+#else+int++asa_test_asa_options (seed,+                      parameter_initial_final,+                      parameter_minimum,+                      parameter_maximum,+                      tangents,+                      curvature,+                      number_parameters,+                      parameter_type,+                      valid_state_generated_flag,+                      exit_status, ptr_asa_out, OPTIONS)+     LONG_INT *seed;+     double *parameter_initial_final;+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *curvature;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     int *valid_state_generated_flag;+     int *exit_status;+     FILE *ptr_asa_out;+     USER_DEFINES *OPTIONS;+#endif /* HAVE_ANSI */+{+  int invalid, index_v;++  invalid = 0;++  if (seed == NULL) {+    strcpy (exit_msg, "*** seed == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (parameter_initial_final == NULL) {+    strcpy (exit_msg, "*** parameter_initial_final == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (parameter_minimum == NULL) {+    strcpy (exit_msg, "*** parameter_minimum == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (parameter_maximum == NULL) {+    strcpy (exit_msg, "*** parameter_maximum == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (tangents == NULL) {+    strcpy (exit_msg, "*** tangents == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Curvature_0 == FALSE || OPTIONS->Curvature_0 == -1) {+    if (curvature == NULL) {+      strcpy (exit_msg, "*** curvature == NULL ***");+      print_string (ptr_asa_out, exit_msg);+      ++invalid;+    }+  }+  if (number_parameters == NULL) {+    strcpy (exit_msg, "*** number_parameters == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (parameter_type == NULL) {+    strcpy (exit_msg, "*** parameter_type == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (valid_state_generated_flag == NULL) {+    strcpy (exit_msg, "*** valid_state_generated_flag == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (exit_status == NULL) {+    strcpy (exit_msg, "*** exit_status == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS == NULL) {+    strcpy (exit_msg, "*** OPTIONS == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }++  VFOR (index_v) if (parameter_minimum[index_v] > parameter_maximum[index_v]) {+    strcpy (exit_msg, "*** parameter_minimum[] > parameter_maximum[] ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+  VFOR (index_v)+    if (parameter_initial_final[index_v] < parameter_minimum[index_v]) {+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    strcpy (exit_msg, "*** parameter_initial[] < parameter_minimum[] ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+  VFOR (index_v)+    if (parameter_initial_final[index_v] > parameter_maximum[index_v]) {+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    strcpy (exit_msg, "*** parameter_initial[] > parameter_maximum[] ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+  if (*number_parameters < 1) {+    strcpy (exit_msg, "*** *number_parameters < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  VFOR (index_v)+    if (parameter_type[index_v] != -2 && parameter_type[index_v] != 2+        && parameter_type[index_v] != -1 && parameter_type[index_v] != 1) {+    strcpy (exit_msg,+            "*** parameter_type[] != -2 && parameter_type[] != 2 && parameter_type[] != -1 && parameter_type[] != 1 ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }++  if (OPTIONS_FILE != FALSE && OPTIONS_FILE != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONS_FILE != FALSE && OPTIONS_FILE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS_FILE_DATA != FALSE && OPTIONS_FILE_DATA != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONS_FILE_DATA != FALSE && OPTIONS_FILE_DATA != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (RECUR_OPTIONS_FILE != FALSE && RECUR_OPTIONS_FILE != TRUE) {+    strcpy (exit_msg,+            "*** RECUR_OPTIONS_FILE != FALSE && RECUR_OPTIONS_FILE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (RECUR_OPTIONS_FILE_DATA != FALSE && RECUR_OPTIONS_FILE_DATA != TRUE) {+    strcpy (exit_msg,+            "*** RECUR_OPTIONS_FILE_DATA != FALSE && RECUR_OPTIONS_FILE_DATA != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (COST_FILE != FALSE && COST_FILE != TRUE) {+    strcpy (exit_msg, "*** COST_FILE != FALSE && COST_FILE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_LIB != FALSE && ASA_LIB != TRUE) {+    strcpy (exit_msg, "*** ASA_LIB != FALSE && ASA_LIB != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MY_TEMPLATE != FALSE && MY_TEMPLATE != TRUE) {+    strcpy (exit_msg, "*** MY_TEMPLATE != FALSE && MY_TEMPLATE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_LIB != FALSE && ASA_TEMPLATE_LIB != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_LIB != FALSE && ASA_TEMPLATE_LIB != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (HAVE_ANSI != FALSE && HAVE_ANSI != TRUE) {+    strcpy (exit_msg, "*** HAVE_ANSI != FALSE && HAVE_ANSI != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (IO_PROTOTYPES != FALSE && IO_PROTOTYPES != TRUE) {+    strcpy (exit_msg,+            "*** IO_PROTOTYPES != FALSE && IO_PROTOTYPES != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (TIME_CALC != FALSE && TIME_CALC != TRUE) {+    strcpy (exit_msg, "*** TIME_CALC != FALSE && TIME_CALC != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (TIME_STD != FALSE && TIME_STD != TRUE) {+    strcpy (exit_msg, "*** TIME_STD != FALSE && TIME_STD != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (TIME_GETRUSAGE != FALSE && TIME_GETRUSAGE != TRUE) {+    strcpy (exit_msg,+            "*** TIME_GETRUSAGE != FALSE && TIME_GETRUSAGE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (INT_LONG != FALSE && INT_LONG != TRUE) {+    strcpy (exit_msg, "*** INT_LONG != FALSE && INT_LONG != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (INT_ALLOC != FALSE && INT_ALLOC != TRUE) {+    strcpy (exit_msg, "*** INT_ALLOC != FALSE && INT_ALLOC != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (SMALL_FLOAT < ZERO) {+    strcpy (exit_msg, "*** SMALL_FLOAT < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MIN_DOUBLE < ZERO) {+    strcpy (exit_msg, "*** MIN_DOUBLE < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MAX_DOUBLE < ZERO) {+    strcpy (exit_msg, "*** MAX_DOUBLE < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (EPS_DOUBLE < ZERO) {+    strcpy (exit_msg, "*** EPS_DOUBLE < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (CHECK_EXPONENT != FALSE && CHECK_EXPONENT != TRUE) {+    strcpy (exit_msg,+            "*** CHECK_EXPONENT != FALSE && CHECK_EXPONENT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (NO_PARAM_TEMP_TEST != FALSE && NO_PARAM_TEMP_TEST != TRUE) {+    strcpy (exit_msg,+            "*** NO_PARAM_TEMP_TEST != FALSE && NO_PARAM_TEMP_TEST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (NO_COST_TEMP_TEST != FALSE && NO_COST_TEMP_TEST != TRUE) {+    strcpy (exit_msg,+            "*** NO_COST_TEMP_TEST != FALSE && NO_COST_TEMP_TEST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (SELF_OPTIMIZE != FALSE && SELF_OPTIMIZE != TRUE) {+    strcpy (exit_msg,+            "*** SELF_OPTIMIZE != FALSE && SELF_OPTIMIZE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEST != FALSE && ASA_TEST != TRUE) {+    strcpy (exit_msg, "*** ASA_TEST != FALSE && ASA_TEST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEST_POINT != FALSE && ASA_TEST_POINT != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEST_POINT != FALSE && ASA_TEST_POINT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE != FALSE) {+    strcpy (exit_msg, "*** ASA_TEMPLATE != FALSE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_ASA_OUT_PID != FALSE && ASA_TEMPLATE_ASA_OUT_PID != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_ASA_OUT_PID != FALSE && ASA_TEMPLATE_ASA_OUT_PID != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_MULTIPLE != FALSE && ASA_TEMPLATE_MULTIPLE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_MULTIPLE != FALSE && ASA_TEMPLATE_MULTIPLE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_SELFOPT != FALSE && ASA_TEMPLATE_SELFOPT != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_SELFOPT != FALSE && ASA_TEMPLATE_SELFOPT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_SAMPLE != FALSE && ASA_TEMPLATE_SAMPLE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_SAMPLE != FALSE && ASA_TEMPLATE_SAMPLE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_QUEUE != FALSE && ASA_TEMPLATE_QUEUE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_QUEUE != FALSE && ASA_TEMPLATE_QUEUE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_PARALLEL != FALSE && ASA_TEMPLATE_PARALLEL != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_PARALLEL != FALSE && ASA_TEMPLATE_PARALLEL != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_SAVE != FALSE && ASA_TEMPLATE_SAVE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_SAVE != FALSE && ASA_TEMPLATE_SAVE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_INITIAL_COST_TEMP != FALSE && USER_INITIAL_COST_TEMP != TRUE) {+    strcpy (exit_msg,+            "*** USER_INITIAL_COST_TEMP != FALSE && USER_INITIAL_COST_TEMP != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (RATIO_TEMPERATURE_SCALES != FALSE && RATIO_TEMPERATURE_SCALES != TRUE) {+    strcpy (exit_msg,+            "*** RATIO_TEMPERATURE_SCALES != FALSE && RATIO_TEMPERATURE_SCALES != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_INITIAL_PARAMETERS_TEMPS != FALSE+      && USER_INITIAL_PARAMETERS_TEMPS != TRUE) {+    strcpy (exit_msg,+            "*** USER_INITIAL_PARAMETERS_TEMPS != FALSE && USER_INITIAL_PARAMETERS_TEMPS != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (DELTA_PARAMETERS != FALSE && DELTA_PARAMETERS != TRUE) {+    strcpy (exit_msg,+            "*** DELTA_PARAMETERS != FALSE && DELTA_PARAMETERS != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (QUENCH_PARAMETERS != FALSE && QUENCH_PARAMETERS != TRUE) {+    strcpy (exit_msg,+            "*** QUENCH_PARAMETERS != FALSE && QUENCH_PARAMETERS != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (QUENCH_COST != FALSE && QUENCH_COST != TRUE) {+    strcpy (exit_msg, "*** QUENCH_COST != FALSE && QUENCH_COST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (QUENCH_PARAMETERS_SCALE != FALSE && QUENCH_PARAMETERS_SCALE != TRUE) {+    strcpy (exit_msg,+            "*** QUENCH_PARAMETERS_SCALE != FALSE && QUENCH_PARAMETERS_SCALE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (QUENCH_COST_SCALE != FALSE && QUENCH_COST_SCALE != TRUE) {+    strcpy (exit_msg,+            "*** QUENCH_COST_SCALE != FALSE && QUENCH_COST_SCALE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONAL_DATA_DBL != FALSE && OPTIONAL_DATA_DBL != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONAL_DATA_DBL != FALSE && OPTIONAL_DATA_DBL != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONAL_DATA_INT != FALSE && OPTIONAL_DATA_INT != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONAL_DATA_INT != FALSE && OPTIONAL_DATA_INT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONAL_DATA_PTR != FALSE && OPTIONAL_DATA_PTR != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONAL_DATA_PTR != FALSE && OPTIONAL_DATA_PTR != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_COST_SCHEDULE != FALSE && USER_COST_SCHEDULE != TRUE) {+    strcpy (exit_msg,+            "*** USER_COST_SCHEDULE != FALSE && USER_COST_SCHEDULE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_ACCEPT_ASYMP_EXP != FALSE && USER_ACCEPT_ASYMP_EXP != TRUE) {+    strcpy (exit_msg,+            "*** USER_ACCEPT_ASYMP_EXP != FALSE && USER_ACCEPT_ASYMP_EXP != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_ACCEPT_THRESHOLD != FALSE && USER_ACCEPT_THRESHOLD != TRUE) {+    strcpy (exit_msg,+            "*** USER_ACCEPT_THRESHOLD != FALSE && USER_ACCEPT_THRESHOLD != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_ACCEPTANCE_TEST != FALSE && USER_ACCEPTANCE_TEST != TRUE) {+    strcpy (exit_msg,+            "*** USER_ACCEPTANCE_TEST != FALSE && USER_ACCEPTANCE_TEST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_GENERATING_FUNCTION != FALSE && USER_GENERATING_FUNCTION != TRUE) {+    strcpy (exit_msg,+            "*** USER_GENERATING_FUNCTION != FALSE && USER_GENERATING_FUNCTION != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_REANNEAL_COST != FALSE && USER_REANNEAL_COST != TRUE) {+    strcpy (exit_msg,+            "*** USER_REANNEAL_COST != FALSE && USER_REANNEAL_COST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_REANNEAL_PARAMETERS != FALSE && USER_REANNEAL_PARAMETERS != TRUE) {+    strcpy (exit_msg,+            "*** USER_REANNEAL_PARAMETERS != FALSE && USER_REANNEAL_PARAMETERS != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MAXIMUM_REANNEAL_INDEX < 1) {+    strcpy (exit_msg, "*** MAXIMUM_REANNEAL_INDEX < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (REANNEAL_SCALE < ZERO) {+    strcpy (exit_msg, "*** REANNEAL_SCALE < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_SAMPLE != FALSE && ASA_SAMPLE != TRUE) {+    strcpy (exit_msg, "*** ASA_SAMPLE != FALSE && ASA_SAMPLE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_QUEUE != FALSE && ASA_QUEUE != TRUE) {+    strcpy (exit_msg, "*** ASA_QUEUE != FALSE && ASA_QUEUE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_RESOLUTION != FALSE && ASA_RESOLUTION != TRUE) {+    strcpy (exit_msg,+            "*** ASA_RESOLUTION != FALSE && ASA_RESOLUTION != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FITLOC != FALSE && FITLOC != TRUE) {+    strcpy (exit_msg, "*** FITLOC != FALSE && FITLOC != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FITLOC_ROUND != FALSE && FITLOC_ROUND != TRUE) {+    strcpy (exit_msg,+            "*** FITLOC_ROUND != FALSE && FITLOC_ROUND != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FITLOC_PRINT != FALSE && FITLOC_PRINT != TRUE) {+    strcpy (exit_msg,+            "*** FITLOC_PRINT != FALSE && FITLOC_PRINT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MULTI_MIN != FALSE && MULTI_MIN != TRUE) {+    strcpy (exit_msg, "*** MULTI_MIN != FALSE && MULTI_MIN != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if MULTI_MIN+  if (OPTIONS->Multi_Number <= 0) {+    strcpy (exit_msg, "*** OPTIONS->Multi_Number <= 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  VFOR (index_v) {+    if (((OPTIONS->Multi_Grid[index_v]) != (OPTIONS->Multi_Grid[index_v]))+        || OPTIONS->Multi_Grid[index_v] < 0) {+      strcpy (exit_msg,+              "*** (OPTIONS->Multi_Grid[]) != (OPTIONS->Multi_Grid[]) || OPTIONS->Multi_Grid[] < 0 ***");+      print_string_index (ptr_asa_out, exit_msg, index_v);+      ++invalid;+    }+  }+  if (OPTIONS->Multi_Specify != 0 && OPTIONS->Multi_Specify != 1) {+    strcpy (exit_msg,+            "*** OPTIONS->Multi_Specify != 0 && OPTIONS->Multi_Specify != 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+  if (ASA_PARALLEL != FALSE && ASA_PARALLEL != TRUE) {+    strcpy (exit_msg,+            "*** ASA_PARALLEL != FALSE && ASA_PARALLEL != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_SAVE != FALSE && ASA_SAVE != TRUE) {+    strcpy (exit_msg, "*** ASA_SAVE != FALSE && ASA_SAVE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_SAVE_OPT != FALSE && ASA_SAVE_OPT != TRUE) {+    strcpy (exit_msg,+            "*** ASA_SAVE_OPT != FALSE && ASA_SAVE_OPT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_SAVE_BACKUP != FALSE && ASA_SAVE_BACKUP != TRUE) {+    strcpy (exit_msg,+            "*** ASA_SAVE_BACKUP != FALSE && ASA_SAVE_BACKUP != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PIPE != FALSE && ASA_PIPE != TRUE) {+    strcpy (exit_msg, "*** ASA_PIPE != FALSE && ASA_PIPE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PIPE_FILE != FALSE && ASA_PIPE_FILE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_PIPE_FILE != FALSE && ASA_PIPE_FILE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (SYSTEM_CALL != FALSE && SYSTEM_CALL != TRUE) {+    strcpy (exit_msg, "*** SYSTEM_CALL != FALSE && SYSTEM_CALL != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FDLIBM_POW != FALSE && FDLIBM_POW != TRUE) {+    strcpy (exit_msg, "*** FDLIBM_POW != FALSE && FDLIBM_POW != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FDLIBM_LOG != FALSE && FDLIBM_LOG != TRUE) {+    strcpy (exit_msg, "*** FDLIBM_LOG != FALSE && FDLIBM_LOG != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FDLIBM_EXP != FALSE && FDLIBM_EXP != TRUE) {+    strcpy (exit_msg, "*** FDLIBM_EXP != FALSE && FDLIBM_EXP != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PRINT != FALSE && ASA_PRINT != TRUE) {+    strcpy (exit_msg, "*** ASA_PRINT != FALSE && ASA_PRINT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_ASA_OUT != FALSE && USER_ASA_OUT != TRUE) {+    strcpy (exit_msg,+            "*** USER_ASA_OUT != FALSE && USER_ASA_OUT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PRINT_INTERMED != FALSE && ASA_PRINT_INTERMED != TRUE) {+    strcpy (exit_msg,+            "*** ASA_PRINT_INTERMED != FALSE && ASA_PRINT_INTERMED != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PRINT_MORE != FALSE && ASA_PRINT_MORE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_PRINT_MORE != FALSE && ASA_PRINT_MORE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (G_FIELD < 0) {+    strcpy (exit_msg, "*** G_FIELD < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (G_PRECISION < 0) {+    strcpy (exit_msg, "*** G_PRECISION < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }++  if (OPTIONS->Limit_Acceptances < 0) {+    strcpy (exit_msg, "*** Limit_Acceptances < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Limit_Generated < 0) {+    strcpy (exit_msg, "*** Limit_Generated < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Limit_Invalid_Generated_States < 0) {+    strcpy (exit_msg, "*** Limit_Invalid_Generated_States < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Accepted_To_Generated_Ratio <= ZERO) {+    strcpy (exit_msg, "*** Accepted_To_Generated_Ratio <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Cost_Precision <= ZERO) {+    strcpy (exit_msg, "*** Cost_Precision <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Maximum_Cost_Repeat < 0) {+    strcpy (exit_msg, "*** Maximum_Cost_Repeat < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Number_Cost_Samples == 0 || OPTIONS->Number_Cost_Samples == -1) {+    strcpy (exit_msg,+            "*** Number_Cost_Samples == 0 || Number_Cost_Samples == -1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Temperature_Ratio_Scale <= ZERO) {+    strcpy (exit_msg, "*** Temperature_Ratio_Scale <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Cost_Parameter_Scale_Ratio <= ZERO) {+    strcpy (exit_msg, "*** Cost_Parameter_Scale_Ratio <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Temperature_Anneal_Scale <= ZERO) {+    strcpy (exit_msg, "*** Temperature_Anneal_Scale <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if USER_INITIAL_COST_TEMP+  if (OPTIONS->User_Cost_Temperature[0] <= ZERO) {+    strcpy (exit_msg, "*** User_Cost_Temperature[0] <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+  if (OPTIONS->Include_Integer_Parameters != FALSE+      && OPTIONS->Include_Integer_Parameters != TRUE) {+    strcpy (exit_msg, "");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->User_Initial_Parameters != FALSE+      && OPTIONS->User_Initial_Parameters != TRUE) {+    strcpy (exit_msg,+            "*** User_Initial_Parameters != FALSE && User_Initial_Parameters != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Sequential_Parameters >= *number_parameters) {+    strcpy (exit_msg, "*** Sequential_Parameters >= *number_parameters ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Initial_Parameter_Temperature <= ZERO) {+    strcpy (exit_msg, "*** Initial_Parameter_Temperature <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if RATIO_TEMPERATURE_SCALES+  VFOR (index_v) if (OPTIONS->User_Temperature_Ratio[index_v] <= ZERO) {+    strcpy (exit_msg, "*** User_Temperature_Ratio[] <= ZERO ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+#endif+#if USER_INITIAL_PARAMETERS_TEMPS+  VFOR (index_v) if (OPTIONS->User_Parameter_Temperature[index_v] <= ZERO) {+    strcpy (exit_msg, "*** User_Parameter_Temperature[] <= ZERO ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+#endif+  if (OPTIONS->Acceptance_Frequency_Modulus < 0) {+    strcpy (exit_msg, "*** Acceptance_Frequency_Modulus < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Generated_Frequency_Modulus < 0) {+    strcpy (exit_msg, "*** Generated_Frequency_Modulus < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Reanneal_Cost == -1) {+    strcpy (exit_msg, "*** Reanneal_Cost == -1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Reanneal_Parameters != FALSE+      && OPTIONS->Reanneal_Parameters != TRUE) {+    strcpy (exit_msg,+            "*** Reanneal_Parameters != FALSE && Reanneal_Parameters != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Delta_X <= ZERO) {+    strcpy (exit_msg, "*** Delta_X <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if DELTA_PARAMETERS+  VFOR (index_v) if (OPTIONS->User_Delta_Parameter[index_v] <= ZERO) {+    strcpy (exit_msg, "*** User_Delta_Parameter[] <= ZERO ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+#endif+  if (OPTIONS->User_Tangents != FALSE && OPTIONS->User_Tangents != TRUE) {+    strcpy (exit_msg,+            "*** User_Tangents != FALSE && User_Tangents != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Curvature_0 != -1 && OPTIONS->Curvature_0 != FALSE+      && OPTIONS->Curvature_0 != TRUE) {+    strcpy (exit_msg,+            "*** Curvature_0 -1 && Curvature_0 != FALSE && Curvature_0 != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if QUENCH_PARAMETERS+  VFOR (index_v) if (OPTIONS->User_Quench_Param_Scale[index_v] <= ZERO) {+    strcpy (exit_msg, "*** User_Quench_Param_Scale[] <= ZERO ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+#endif+#if QUENCH_COST+  if (OPTIONS->User_Quench_Cost_Scale[0] <= ZERO) {+    strcpy (exit_msg, "*** User_Quench_Cost_Scale[0] <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if OPTIONAL_DATA_DBL+  if (OPTIONS->Asa_Data_Dim_Dbl < 1) {+    strcpy (exit_msg, "*** Asa_Data_Dim_Dbl < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Asa_Data_Dbl == NULL) {+    strcpy (exit_msg, "*** Asa_Data_Dbl == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if ASA_SAVE+  if (OPTIONS->Random_Array_Dim < 1) {+    strcpy (exit_msg, "*** Random_Array_Dim < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Random_Array == NULL) {+    strcpy (exit_msg, "*** Random_Array == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if OPTIONAL_DATA_INT+  if (OPTIONS->Asa_Data_Dim_Int < 1) {+    strcpy (exit_msg, "*** Asa_Data_Dim_Int < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Asa_Data_Int == NULL) {+    strcpy (exit_msg, "*** Asa_Data_Int == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if OPTIONAL_DATA_PTR+  if (OPTIONS->Asa_Data_Dim_Ptr < 1) {+    strcpy (exit_msg, "*** Asa_Data_Dim_Ptr < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Asa_Data_Ptr == NULL) {+    strcpy (exit_msg, "*** Asa_Data_Ptr == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_ASA_OUT+  if (OPTIONS->Asa_Out_File == NULL) {+    strcpy (exit_msg, "*** Asa_Out_File == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_COST_SCHEDULE+  if (OPTIONS->Cost_Schedule == NULL) {+    strcpy (exit_msg, "*** Cost_Schedule == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_ACCEPTANCE_TEST+  if (OPTIONS->Acceptance_Test == NULL) {+    strcpy (exit_msg, "*** Acceptance_Test == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->User_Acceptance_Flag != FALSE+      && OPTIONS->User_Acceptance_Flag != TRUE) {+    strcpy (exit_msg,+            "*** User_Acceptance_Flag != FALSE && User_Acceptance_Flag != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Cost_Acceptance_Flag != FALSE+      && OPTIONS->Cost_Acceptance_Flag != TRUE) {+    strcpy (exit_msg,+            "*** Cost_Acceptance_Flag != FALSE && Cost_Acceptance_Flag != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_GENERATING_FUNCTION+  if (OPTIONS->Generating_Distrib == NULL) {+    strcpy (exit_msg, "*** Generating_Distrib == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_REANNEAL_COST+  if (OPTIONS->Reanneal_Cost_Function == NULL) {+    strcpy (exit_msg, "*** Reanneal_Cost_Function == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_REANNEAL_PARAMETERS+  if (OPTIONS->Reanneal_Params_Function == NULL) {+    strcpy (exit_msg, "*** Reanneal_Params_Function == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if ASA_SAMPLE+  if (OPTIONS->Bias_Generated == NULL) {+    strcpy (exit_msg, "*** Bias_Generated == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Limit_Weights < ZERO) {+    strcpy (exit_msg, "*** Limit_Weights < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if ASA_QUEUE+  if (OPTIONS->Queue_Size < 0) {+    strcpy (exit_msg, "*** Queue_Size < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Queue_Size > 0) {+    if (OPTIONS->Queue_Resolution == NULL) {+      strcpy (exit_msg, "*** Queue_Resolution == NULL ***");+      print_string (ptr_asa_out, exit_msg);+      ++invalid;+    }+  }+#endif+#if ASA_RESOLUTION+  if (OPTIONS->Coarse_Resolution == NULL) {+    strcpy (exit_msg, "*** Coarse_Resolution == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if ASA_PARALLEL+  if (OPTIONS->Gener_Block < 1) {+    strcpy (exit_msg, "*** Gener_Block < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Gener_Block_Max < 1) {+    strcpy (exit_msg, "*** Gener_Block_Max < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Gener_Mov_Avr < 1) {+    strcpy (exit_msg, "*** Gener_Mov_Avr < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif++  return (invalid);+}++/***********************************************************************+* cost_function_test+*       Tests user's returned cost function values and parameters+***********************************************************************/+#if HAVE_ANSI+int++cost_function_test (double cost,+                    double *parameter,+                    double *parameter_minimum,+                    double *parameter_maximum,+                    ALLOC_INT * number_parameters, double *xnumber_parameters)+#else+int++cost_function_test (cost,+                    parameter,+                    parameter_minimum, parameter_maximum,+                    number_parameters, xnumber_parameters)+     double cost;+     double *parameter;+     double *parameter_minimum;+     double *parameter_maximum;+     ALLOC_INT *number_parameters;+     double *xnumber_parameters;+#endif /* HAVE_ANSI */+{+  ALLOC_INT index_v;+  int test_flag;++  test_flag = 1;++  if (((cost) != (cost)) || (cost < -MAX_DOUBLE || cost > MAX_DOUBLE))+    test_flag = 0;++  *xnumber_parameters = (double) *number_parameters;+  VFOR (index_v) {+    if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+      *xnumber_parameters -= 1.0;+      continue;+    }+    if (parameter[index_v] < parameter_minimum[index_v] ||+        parameter[index_v] > parameter_maximum[index_v]) {+      test_flag = 0;+    }+  }++  return (test_flag);+}++/***********************************************************************+* print_string+*	This prints the designated string+***********************************************************************/+#if HAVE_ANSI+void+print_string (FILE * ptr_asa_out, char *string)+#else+void+print_string (ptr_asa_out, string)+     FILE *ptr_asa_out;+     char *string;+#endif /* HAVE_ANSI */+{+#if INCL_STDOUT+  printf ("\n\n%s\n\n", string);+#endif /* INCL_STDOUT */+#if ASA_PRINT+  fprintf (ptr_asa_out, "\n\n%s\n\n", string);+#else+#endif+}++/***********************************************************************+* print_string_index+*	This prints the designated string and index+***********************************************************************/+#if HAVE_ANSI+void+print_string_index (FILE * ptr_asa_out, char *string, ALLOC_INT index)+#else+void+print_string_index (ptr_asa_out, string, index)+     FILE *ptr_asa_out;+     char *string;+     ALLOC_INT index;+#endif /* HAVE_ANSI */+{+#if INCL_STDOUT+#if INT_ALLOC+  printf ("\n\n%s index = %d\n\n", string, index);+#else /* INT_ALLOC */+#if INT_LONG+  printf ("\n\n%s index = %ld\n\n", string, index);+#else /* INT_LONG */+  printf ("\n\n%s index = %ld\n\n", string, index);+#endif /* INT_LONG */+#endif /* INT_ALLOC */+#endif /* INCL_STDOUT */++#if ASA_PRINT+#if INT_ALLOC+  fprintf (ptr_asa_out, "\n\n%s index = %d\n\n", string, index);+#else /* INT_ALLOC */+#if INT_LONG+  fprintf (ptr_asa_out, "\n\n%s index = %ld\n\n", string, index);+#else /* INT_LONG */+  fprintf (ptr_asa_out, "\n\n%s index = %d\n\n", string, index);+#endif /* INT_LONG */+#endif /* INT_ALLOC */+#else /* ASA_PRINT */+  ;+#endif /* ASA_PRINT */+}++#if ASA_PRINT+/***********************************************************************+* print_state+*	Prints a description of the current state of the system+***********************************************************************/+void+print_state (double *parameter_minimum,+             double *parameter_maximum,+             double *tangents,+             double *curvature,+             double *current_cost_temperature,+             double *current_user_parameter_temp,+             double *accepted_to_generated_ratio,+             ALLOC_INT * number_parameters,+             int *curvature_flag,+             LONG_INT * number_accepted,+             LONG_INT * index_cost_acceptances,+             LONG_INT * number_generated,+             LONG_INT * number_invalid_generated_states,+             STATE * last_saved_state,+             STATE * best_generated_state,+             FILE * ptr_asa_out, USER_DEFINES * OPTIONS)+{+  ALLOC_INT index_v;+  ALLOC_INT index_vv, index_v_vv;++  fprintf (ptr_asa_out, "\n");+#if TIME_CALC+  print_time ("", ptr_asa_out);+#endif++  if (OPTIONS->Curvature_0 == TRUE)+    *curvature_flag = FALSE;+  if (OPTIONS->Curvature_0 == -1)+    *curvature_flag = TRUE;++#if INT_LONG+  fprintf (ptr_asa_out,+           "*index_cost_acceptances = %ld, *current_cost_temperature = %*.*g\n",+           *index_cost_acceptances,+           G_FIELD, G_PRECISION, *current_cost_temperature);+  fprintf (ptr_asa_out, "*accepted_to_generated_ratio = %*.*g,\+ *number_invalid... = %ld\n", G_FIELD, G_PRECISION, *accepted_to_generated_ratio, (*number_invalid_generated_states));+  fprintf (ptr_asa_out,+           "*number_generated = %ld, *number_accepted = %ld\n",+           *number_generated, *number_accepted);+#else+  fprintf (ptr_asa_out,+           "*index_cost_acceptances = %d, *current_cost_temperature = %*.*g\n",+           *index_cost_acceptances,+           G_FIELD, G_PRECISION, *current_cost_temperature);+  fprintf (ptr_asa_out, "*accepted_to_generated_ratio = %*.*g,\+ *number_invalid... = %d\n", G_FIELD, G_PRECISION, *accepted_to_generated_ratio, *number_invalid_generated_states);+  fprintf (ptr_asa_out,+           "*number_generated = %d, *number_accepted = %d\n",+           *number_generated, *number_accepted);+#endif++  fprintf (ptr_asa_out, "best...->cost = %*.*g,\+ last...->cost = %*.*g\n", G_FIELD, G_PRECISION, best_generated_state->cost, G_FIELD, G_PRECISION, last_saved_state->cost);++  /* Note that tangents will not be calculated until reanneal+     is called, and therefore their listing in the printout only+     is relevant then */++  fprintf (ptr_asa_out,+           "index_v  best...->parameter current_parameter_temp\ttangent\n");+  VFOR (index_v) {+    /* ignore too small ranges */+#if DROPPED_PARAMETERS+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+#endif+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "%d\t%*.*g\t\t%*.*g\t%*.*g\n",+#else+#if INT_LONG+             "%ld\t%*.*g\t\t%*.*g\t%*.*g\n",+#else+             "%d\t%*.*g\t\t%*.*g\t%*.*g\n",+#endif+#endif+             index_v,+             G_FIELD, G_PRECISION, best_generated_state->parameter[index_v],+             G_FIELD, G_PRECISION, current_user_parameter_temp[index_v],+             G_FIELD, G_PRECISION, tangents[index_v]);+  }++  if (*curvature_flag == TRUE) {+    /* print curvatures */+    VFOR (index_v) {+      /* ignore too small ranges */+      if (PARAMETER_RANGE_TOO_SMALL (index_v))+        continue;+      fprintf (ptr_asa_out, "\n");+      VFOR (index_vv) {+        /* only print upper diagonal of matrix */+        if (index_v < index_vv)+          continue;+        /* ignore too small ranges (index_vv) */+        if (PARAMETER_RANGE_TOO_SMALL (index_vv))+          continue;++        /* index_v_vv: row index_v, column index_vv */+        index_v_vv = ROW_COL_INDEX (index_v, index_vv);++        if (index_v == index_vv) {+          fprintf (ptr_asa_out,+#if INT_ALLOC+                   "curvature[%d][%d] = %*.*g\n",+#else+#if INT_LONG+                   "curvature[%ld][%ld] = %*.*g\n",+#else+                   "curvature[%d][%d] = %*.*g\n",+#endif+#endif+                   index_v, index_vv,+                   G_FIELD, G_PRECISION, curvature[index_v_vv]);+        } else {+          fprintf (ptr_asa_out,+#if INT_ALLOC+                   "curvature[%d][%d] = %*.*g \t = curvature[%d][%d]\n",+#else+#if INT_LONG+                   "curvature[%ld][%ld] = %*.*g \t = curvature[%ld][%ld]\n",+#else+                   "curvature[%d][%d] = %*.*g \t = curvature[%d][%d]\n",+#endif+#endif+                   index_v, index_vv,+                   G_FIELD, G_PRECISION, curvature[index_v_vv],+                   index_vv, index_v);+        }+      }+    }+  }+  fprintf (ptr_asa_out, "\n");+  fflush (ptr_asa_out);++}++/***********************************************************************+* print_asa_options+*	Prints user's selected options+***********************************************************************/+void+print_asa_options (FILE * ptr_asa_out, USER_DEFINES * OPTIONS)+{+  fprintf (ptr_asa_out, "\t\tADAPTIVE SIMULATED ANNEALING\n\n");++  fprintf (ptr_asa_out, "%s\n\n", ASA_ID);++  fprintf (ptr_asa_out, "OPTIONS_FILE = %d\n", (int) OPTIONS_FILE);+  fprintf (ptr_asa_out, "OPTIONS_FILE_DATA = %d\n", (int) OPTIONS_FILE_DATA);+  fprintf (ptr_asa_out, "RECUR_OPTIONS_FILE = %d\n",+           (int) RECUR_OPTIONS_FILE);+  fprintf (ptr_asa_out, "RECUR_OPTIONS_FILE_DATA = %d\n",+           (int) RECUR_OPTIONS_FILE_DATA);+  fprintf (ptr_asa_out, "COST_FILE = %d\n", (int) COST_FILE);+  fprintf (ptr_asa_out, "ASA_LIB = %d\n", (int) ASA_LIB);+  fprintf (ptr_asa_out, "HAVE_ANSI = %d\n", (int) HAVE_ANSI);+  fprintf (ptr_asa_out, "IO_PROTOTYPES = %d\n", (int) IO_PROTOTYPES);+  fprintf (ptr_asa_out, "TIME_CALC = %d\n", (int) TIME_CALC);+  fprintf (ptr_asa_out, "TIME_STD = %d\n", (int) TIME_STD);+  fprintf (ptr_asa_out, "TIME_GETRUSAGE = %d\n", (int) TIME_GETRUSAGE);+  fprintf (ptr_asa_out, "INT_LONG = %d\n", (int) INT_LONG);+  fprintf (ptr_asa_out, "INT_ALLOC = %d\n", (int) INT_ALLOC);+  fprintf (ptr_asa_out, "SMALL_FLOAT = %*.*g\n",+           G_FIELD, G_PRECISION, (double) SMALL_FLOAT);+  fprintf (ptr_asa_out, "MIN_DOUBLE = %*.*g\n",+           G_FIELD, G_PRECISION, (double) MIN_DOUBLE);+  fprintf (ptr_asa_out, "MAX_DOUBLE = %*.*g\n",+           G_FIELD, G_PRECISION, (double) MAX_DOUBLE);+  fprintf (ptr_asa_out, "EPS_DOUBLE = %*.*g\n",+           G_FIELD, G_PRECISION, (double) EPS_DOUBLE);+  fprintf (ptr_asa_out, "CHECK_EXPONENT = %d\n", (int) CHECK_EXPONENT);+  fprintf (ptr_asa_out, "NO_PARAM_TEMP_TEST = %d\n",+           (int) NO_PARAM_TEMP_TEST);+  fprintf (ptr_asa_out, "NO_COST_TEMP_TEST = %d\n", (int) NO_COST_TEMP_TEST);+  fprintf (ptr_asa_out, "SELF_OPTIMIZE = %d\n", (int) SELF_OPTIMIZE);+  fprintf (ptr_asa_out, "ASA_TEST = %d\n", (int) ASA_TEST);+  fprintf (ptr_asa_out, "ASA_TEST_POINT = %d\n", (int) ASA_TEST_POINT);+  fprintf (ptr_asa_out, "ASA_TEMPLATE = %d\n", (int) ASA_TEMPLATE);+  fprintf (ptr_asa_out, "MY_TEMPLATE = %d\n", (int) MY_TEMPLATE);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_LIB = %d\n", (int) ASA_TEMPLATE_LIB);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_ASA_OUT_PID = %d\n",+           (int) ASA_TEMPLATE_ASA_OUT_PID);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_MULTIPLE = %d\n",+           (int) ASA_TEMPLATE_MULTIPLE);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_SELFOPT = %d\n",+           (int) ASA_TEMPLATE_SELFOPT);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_SAMPLE = %d\n",+           (int) ASA_TEMPLATE_SAMPLE);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_QUEUE = %d\n",+           (int) ASA_TEMPLATE_QUEUE);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_PARALLEL = %d\n",+           (int) ASA_TEMPLATE_PARALLEL);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_SAVE = %d\n", (int) ASA_TEMPLATE_SAVE);+  fprintf (ptr_asa_out, "USER_INITIAL_COST_TEMP = %d\n",+           (int) USER_INITIAL_COST_TEMP);+  fprintf (ptr_asa_out, "RATIO_TEMPERATURE_SCALES = %d\n",+           (int) RATIO_TEMPERATURE_SCALES);+  fprintf (ptr_asa_out, "USER_INITIAL_PARAMETERS_TEMPS = %d\n",+           (int) USER_INITIAL_PARAMETERS_TEMPS);+  fprintf (ptr_asa_out, "DELTA_PARAMETERS = %d\n", (int) DELTA_PARAMETERS);+  fprintf (ptr_asa_out, "QUENCH_PARAMETERS = %d\n", (int) QUENCH_PARAMETERS);+  fprintf (ptr_asa_out, "QUENCH_COST = %d\n", (int) QUENCH_COST);+  fprintf (ptr_asa_out, "QUENCH_PARAMETERS_SCALE = %d\n",+           (int) QUENCH_PARAMETERS_SCALE);+  fprintf (ptr_asa_out, "QUENCH_COST_SCALE = %d\n", (int) QUENCH_COST_SCALE);+  fprintf (ptr_asa_out, "OPTIONAL_DATA_DBL = %d\n", (int) OPTIONAL_DATA_DBL);+  fprintf (ptr_asa_out, "OPTIONAL_DATA_INT = %d\n", (int) OPTIONAL_DATA_INT);+  fprintf (ptr_asa_out, "OPTIONAL_DATA_PTR = %d\n", (int) OPTIONAL_DATA_PTR);+  fprintf (ptr_asa_out, "USER_COST_SCHEDULE = %d\n",+           (int) USER_COST_SCHEDULE);+  fprintf (ptr_asa_out, "USER_ACCEPT_ASYMP_EXP = %d\n",+           (int) USER_ACCEPT_ASYMP_EXP);+  fprintf (ptr_asa_out, "USER_ACCEPT_THRESHOLD = %d\n",+           (int) USER_ACCEPT_THRESHOLD);+  fprintf (ptr_asa_out, "USER_ACCEPTANCE_TEST = %d\n",+           (int) USER_ACCEPTANCE_TEST);+  fprintf (ptr_asa_out, "USER_GENERATING_FUNCTION = %d\n",+           (int) USER_GENERATING_FUNCTION);+  fprintf (ptr_asa_out, "USER_REANNEAL_COST = %d\n",+           (int) USER_REANNEAL_COST);+  fprintf (ptr_asa_out, "USER_REANNEAL_PARAMETERS = %d\n",+           (int) USER_REANNEAL_PARAMETERS);+#if INT_LONG+  fprintf (ptr_asa_out, "MAXIMUM_REANNEAL_INDEX = %ld\n",+           (LONG_INT) MAXIMUM_REANNEAL_INDEX);+#else+  fprintf (ptr_asa_out, "MAXIMUM_REANNEAL_INDEX = %d\n",+           (LONG_INT) MAXIMUM_REANNEAL_INDEX);+#endif+  fprintf (ptr_asa_out, "REANNEAL_SCALE = %*.*g\n",+           G_FIELD, G_PRECISION, (double) REANNEAL_SCALE);+  fprintf (ptr_asa_out, "ASA_SAMPLE = %d\n", (int) ASA_SAMPLE);+  fprintf (ptr_asa_out, "ASA_QUEUE = %d\n", (int) ASA_QUEUE);+  fprintf (ptr_asa_out, "ASA_RESOLUTION = %d\n", (int) ASA_RESOLUTION);+  fprintf (ptr_asa_out, "FITLOC = %d\n", (int) FITLOC);+  fprintf (ptr_asa_out, "FITLOC_ROUND = %d\n", (int) FITLOC_ROUND);+  fprintf (ptr_asa_out, "FITLOC_PRINT = %d\n", (int) FITLOC_PRINT);+  fprintf (ptr_asa_out, "MULTI_MIN = %d\n", (int) MULTI_MIN);+  fprintf (ptr_asa_out, "ASA_PARALLEL = %d\n", (int) ASA_PARALLEL);+  fprintf (ptr_asa_out, "FDLIBM_POW = %d\n", (int) FDLIBM_POW);+  fprintf (ptr_asa_out, "FDLIBM_LOG = %d\n", (int) FDLIBM_LOG);+  fprintf (ptr_asa_out, "FDLIBM_EXP = %d\n\n", (int) FDLIBM_EXP);++  fprintf (ptr_asa_out, "ASA_PRINT = %d\n", (int) ASA_PRINT);+  fprintf (ptr_asa_out, "USER_OUT = %s\n", USER_OUT);+#if USER_ASA_OUT+  fprintf (ptr_asa_out, "ASA_OUT = %s\n", OPTIONS->Asa_Out_File);+#else+  fprintf (ptr_asa_out, "ASA_OUT = %s\n", ASA_OUT);+#endif+  fprintf (ptr_asa_out, "USER_ASA_OUT = %d\n", (int) USER_ASA_OUT);+  fprintf (ptr_asa_out, "ASA_PRINT_INTERMED = %d\n",+           (int) ASA_PRINT_INTERMED);+  fprintf (ptr_asa_out, "ASA_PRINT_MORE = %d\n", (int) ASA_PRINT_MORE);+  fprintf (ptr_asa_out, "INCL_STDOUT = %d\n", (int) INCL_STDOUT);+  fprintf (ptr_asa_out, "G_FIELD = %d\n", (int) G_FIELD);+  fprintf (ptr_asa_out, "G_PRECISION = %d\n", (int) G_PRECISION);+  fprintf (ptr_asa_out, "ASA_SAVE = %d\n", (int) ASA_SAVE);+  fprintf (ptr_asa_out, "ASA_SAVE_OPT = %d\n", (int) ASA_SAVE_OPT);+  fprintf (ptr_asa_out, "ASA_SAVE_BACKUP = %d\n", (int) ASA_SAVE_BACKUP);+  fprintf (ptr_asa_out, "ASA_PIPE = %d\n", (int) ASA_PIPE);+  fprintf (ptr_asa_out, "ASA_PIPE_FILE = %d\n", (int) ASA_PIPE_FILE);+  fprintf (ptr_asa_out, "SYSTEM_CALL = %d\n\n", (int) SYSTEM_CALL);++#if INT_LONG+  fprintf (ptr_asa_out, "OPTIONS->Limit_Acceptances = %ld\n",+           (LONG_INT) OPTIONS->Limit_Acceptances);+  fprintf (ptr_asa_out, "OPTIONS->Limit_Generated = %ld\n",+           (LONG_INT) OPTIONS->Limit_Generated);+#else+  fprintf (ptr_asa_out, "OPTIONS->Limit_Acceptances = %d\n",+           (LONG_INT) OPTIONS->Limit_Acceptances);+  fprintf (ptr_asa_out, "OPTIONS->Limit_Generated = %d\n",+           (LONG_INT) OPTIONS->Limit_Generated);+#endif+  fprintf (ptr_asa_out, "OPTIONS->Limit_Invalid_Generated_States = %d\n",+           OPTIONS->Limit_Invalid_Generated_States);+  fprintf (ptr_asa_out, "OPTIONS->Accepted_To_Generated_Ratio = %*.*g\n\n",+           G_FIELD, G_PRECISION, OPTIONS->Accepted_To_Generated_Ratio);++  fprintf (ptr_asa_out, "OPTIONS->Cost_Precision = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Cost_Precision);+  fprintf (ptr_asa_out, "OPTIONS->Maximum_Cost_Repeat = %d\n",+           OPTIONS->Maximum_Cost_Repeat);+  fprintf (ptr_asa_out, "OPTIONS->Number_Cost_Samples = %d\n",+           OPTIONS->Number_Cost_Samples);+  fprintf (ptr_asa_out, "OPTIONS->Temperature_Ratio_Scale = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Temperature_Ratio_Scale);+  fprintf (ptr_asa_out, "OPTIONS->Cost_Parameter_Scale_Ratio = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Cost_Parameter_Scale_Ratio);+  fprintf (ptr_asa_out, "OPTIONS->Temperature_Anneal_Scale = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Temperature_Anneal_Scale);++  fprintf (ptr_asa_out, "OPTIONS->Include_Integer_Parameters = %d\n",+           OPTIONS->Include_Integer_Parameters);+  fprintf (ptr_asa_out, "OPTIONS->User_Initial_Parameters = %d\n",+           OPTIONS->User_Initial_Parameters);+#if INT_ALLOC+  fprintf (ptr_asa_out, "OPTIONS->Sequential_Parameters = %d\n",+           (int) OPTIONS->Sequential_Parameters);+#else+#if INT_LONG+  fprintf (ptr_asa_out, "OPTIONS->Sequential_Parameters = %ld\n",+           (LONG_INT) OPTIONS->Sequential_Parameters);+#else+  fprintf (ptr_asa_out, "OPTIONS->Sequential_Parameters = %d\n",+           (LONG_INT) OPTIONS->Sequential_Parameters);+#endif+#endif+  fprintf (ptr_asa_out, "OPTIONS->Initial_Parameter_Temperature = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Initial_Parameter_Temperature);++  fprintf (ptr_asa_out, "OPTIONS->Acceptance_Frequency_Modulus = %d\n",+           OPTIONS->Acceptance_Frequency_Modulus);+  fprintf (ptr_asa_out, "OPTIONS->Generated_Frequency_Modulus = %d\n",+           OPTIONS->Generated_Frequency_Modulus);+  fprintf (ptr_asa_out, "OPTIONS->Reanneal_Cost = %d\n",+           OPTIONS->Reanneal_Cost);+  fprintf (ptr_asa_out, "OPTIONS->Reanneal_Parameters = %d\n\n",+           OPTIONS->Reanneal_Parameters);++  fprintf (ptr_asa_out, "OPTIONS->Delta_X = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Delta_X);+  fprintf (ptr_asa_out, "OPTIONS->User_Tangents = %d\n",+           OPTIONS->User_Tangents);+  fprintf (ptr_asa_out, "OPTIONS->Curvature_0 = %d\n", OPTIONS->Curvature_0);+  fprintf (ptr_asa_out, "OPTIONS->Asa_Recursive_Level = %d\n\n",+           OPTIONS->Asa_Recursive_Level);++  fprintf (ptr_asa_out, "\n");+}+#endif /* ASA_PRINT */++#if TIME_CALC+#if TIME_GETRUSAGE+/***********************************************************************+* print_time+*	This calculates the time and runtime and prints it.+***********************************************************************/+#if HAVE_ANSI+void+print_time (char *message, FILE * ptr_asa_out)+#else+void+print_time (message, ptr_asa_out)+     char *message;+     FILE *ptr_asa_out;+#endif /* HAVE_ANSI */+{+  int who = RUSAGE_SELF;        /* Check our own time */+  struct rusage usage;++  /* get the resource usage information */+#if TIME_STD+  syscall (SYS_GETRUSAGE, who, &usage);+#else+  getrusage (who, &usage);+#endif++  /* print the usage time in reasonable form */+  aux_print_time (&usage.ru_utime, message, ptr_asa_out);+}++/***********************************************************************+* aux_print_time+*      auxiliary print the time routine+***********************************************************************/+#if HAVE_ANSI+void+aux_print_time (struct timeval *time, char *message, FILE * ptr_asa_out)+#else+void+aux_print_time (time, message, ptr_asa_out)+     struct timeval *time;+     char *message;+     FILE *ptr_asa_out;+#endif /* HAVE_ANSI */+{+  static double sx;+  double us, s, m, h;+  double ds, dm, dh;++  /* calculate the new microseconds, seconds, minutes, hours+     and the differences since the last call */+  us = (double) ((int) ((double) EPS_DOUBLE + time->tv_usec)) / 1.E6;+  s = (double) ((int) ((double) EPS_DOUBLE + time->tv_sec)) + us;+  ds = s - sx;+  sx = s;++  h = (int) ((double) EPS_DOUBLE + s / 3600.);+  m = (int) ((double) EPS_DOUBLE + s / 60.) - 60. * h;+  s -= (3600. * h + 60. * m);+  dh = (int) ((double) EPS_DOUBLE + ds / 3600.);+  dm = (int) ((double) EPS_DOUBLE + ds / 60.) - 60. * dh;+  ds -= (3600. * dh + 60. * dm);++  /* print the statistics */+  fprintf (ptr_asa_out,+           "%s:time: %gh %gm %gs; incr: %gh %gm %gs\n",+           message, h, m, s, dh, dm, ds);+}+#else /* TIME_GETRUSAGE */+  /* Note that on many machines the time resolution of this algorithm+   * may be less than the other alternatives, e.g., rounding off the+   * number of ticks to the nearest tens of thousands.  Also, because+   * time here is typically indexed by a long integer, there typically+   * is a cycle of time in periods of fractions of an hour.  For+   * example, under Solaris 2.5.1:  The value returned by clock() is+   * defined in microseconds, since the first call to clock(), for+   *  compatibility with  systems that have * CPU clocks with much higher+   * resolution.  Because of this, the value returned will wrap around+   * after accumulating only 2147 seconds of CPU time (about 36 minutes).+   *+   * See asa.h for two places where some additional modifications should+   * be made under SunOS 4.1.x. */++#if HAVE_ANSI+void+print_time (char *message, FILE * ptr_asa_out)+#else+void+print_time (message, ptr_asa_out)+     char *message;+     FILE *ptr_asa_out;+#endif /* HAVE_ANSI */+{+  aux_print_time (clock (), message, ptr_asa_out);++}                               /*print_time */++/***********************************************************************+* aux_print_time+*      auxiliary print the time routine+***********************************************************************/+#if HAVE_ANSI+void+aux_print_time (clock_t time, char *message, FILE * ptr_asa_out)+#else+void+aux_print_time (time, message, ptr_asa_out)+     clock_t time;+     char *message;+     FILE *ptr_asa_out;+#endif /* HAVE_ANSI */+{+  static clock_t previousTime = -1;+  clock_t diffTime;+  double clocksPerSecF = CLOCKS_PER_SEC;+  double timeF, diffF;+  double s, m, h;+  double ds, dm, dh;++  if (previousTime != -1) {+    diffTime = time - previousTime;+    timeF = time;+    diffF = diffTime;+    previousTime = time;++    s = timeF / clocksPerSecF;+    ds = diffF / clocksPerSecF;++    h = (int) ((double) EPS_DOUBLE + s / 3600.);+    m = (int) ((double) EPS_DOUBLE + s / 60.) - 60. * h;+    s -= (3600. * h + 60. * m);+    dh = (int) ((double) EPS_DOUBLE + ds / 3600.);+    dm = (int) ((double) EPS_DOUBLE + ds / 60.) - 60. * dh;+    ds -= (3600. * dh + 60. * dm);++    fprintf (ptr_asa_out,+             "%s:time: %gh %gm %gs; incr: %gh %gm %gs\n",+             message, h, m, s, dh, dm, ds);+  } else {+    /* The first call will be invalid - don't output anything. */+    fprintf (ptr_asa_out, "TIMING PARAMETERS: ticks/sec: %lu\n",+             CLOCKS_PER_SEC);+    previousTime = time;+  }+}                               /* aux_print_time */++#endif /* TIME_GETRUSAGE */++#endif /* TIME_CALC */++#if MULTI_MIN+#if HAVE_ANSI+static int+multi_compare (const void *ii, const void *jj)+#else /* HAVE_ANSI */+static int+multi_compare (ii, jj)+     char *ii;+     char *jj;+#endif /* HAVE_ANSI */+{+  int i;+  int j;++  i = *(int *) ii;+  j = *(int *) jj;++  if (multi_cost_qsort[i] > multi_cost_qsort[j] + (double) EPS_DOUBLE)+    return (1);+  else if (multi_cost_qsort[i] < multi_cost_qsort[j] - (double) EPS_DOUBLE)+    return (-1);+  else+    return (0);+}+#endif /* MULTI_MIN */++#if ASA_PARALLEL+#if HAVE_ANSI+static int+sort_parallel (const void *ii, const void *jj)+#else /* HAVE_ANSI */+static int+sort_parallel (ii, jj)+     void *ii;+     void *jj;+#endif /* HAVE_ANSI */+{+  LONG_INT i;+  LONG_INT j;++  i = *(LONG_INT *) ii;+  j = *(LONG_INT *) jj;++  if (gener_block_state_qsort[i].cost > gener_block_state_qsort[j].cost)+    return (1);+  else if (gener_block_state_qsort[i].cost < gener_block_state_qsort[j].cost)+    return (-1);+  else+    return (0);+}+#endif /* ASA_PARALLEL */+#if HAVE_ANSI+void+Exit_ASA (char *statement)+#else /* HAVE_ANSI */+void+Exit_ASA (statement)+     char *statement;+#endif /* HAVE_ANSI */+{+#if INCL_STDOUT+  printf ("\n\n*** EXIT calloc failed in ASA *** %s\n\n", statement);+#else+  ;+#endif /* INCL_STDOUT */+}
+ _darcs/pristine/asa.h view
@@ -0,0 +1,337 @@+#ifndef _ASA_H_+#define _ASA_H_++/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+***********************************************************************/++ /* $Id: asa.h,v 25.15 2004/09/23 18:10:48 ingber Exp ingber $ */++ /* asa.h for Adaptive Simulated Annealing */++#include "asa_usr_asa.h"++#define ZERO			((double) 0.0)+#define ONE			((double) 1.0)+#define TWO			((double) 2.0)+#define TEN			((double) 10.0)+#define HALF			((double) 0.5)++#define NORMAL_EXIT			((int) 0)+#define P_TEMP_TOO_SMALL		((int) 1)+#define C_TEMP_TOO_SMALL		((int) 2)+#define COST_REPEATING			((int) 3)+#define TOO_MANY_INVALID_STATES		((int) 4)+#define IMMEDIATE_EXIT			((int) 5)+#define INVALID_USER_INPUT		((int) 7)+#define INVALID_COST_FUNCTION		((int) 8)+#define INVALID_COST_FUNCTION_DERIV	((int) 9)+#define CALLOC_FAILED			((int) -1)++#ifndef TIME_STD+#define TIME_STD FALSE+#endif++#ifndef TIME_GETRUSAGE+#define TIME_GETRUSAGE TRUE+#endif++#if TIME_CALC+#if TIME_GETRUSAGE+#include <sys/time.h>+#include <sys/resource.h>+#if TIME_STD+#include <sys/syscall.h>+#endif /* TIME_STD */+#else /* TIME_GETRUSAGE */+#if TRUE                        /* change to FALSE for SunOS 4.1.x */+#include <time.h>+#else+#include </usr/5include/time.h>+#endif+#endif /* TIME_GETRUSAGE */+#endif /* TIME_CALC */++ /* Set this to TRUE to override the P_TEMP_TOO_SMALL test */+#ifndef NO_PARAM_TEMP_TEST+#define NO_PARAM_TEMP_TEST FALSE+#endif++ /* Set this to TRUE to override the C_TEMP_TOO_SMALL test */+#ifndef NO_COST_TEMP_TEST+#define NO_COST_TEMP_TEST FALSE+#endif++#ifndef SYSTEM_CALL+#define SYSTEM_CALL TRUE+#endif++ /* Printing Options */++#ifndef ASA_PRINT+#define ASA_PRINT TRUE+#endif++#if ASA_PRINT+#else+#if ASA_SAMPLE+#define ASA_PRINT TRUE+#endif+#endif++#ifndef ASA_OUT+#define ASA_OUT "asa_out"+#endif++#ifndef DROPPED_PARAMETERS+#define DROPPED_PARAMETERS FALSE+#endif++ /* You can set ASA_PRINT_INTERMED to TRUE to print out+    intermediate data when SELF_OPTIMIZE is set to TRUE */+#ifndef ASA_PRINT_INTERMED+#if SELF_OPTIMIZE+#define ASA_PRINT_INTERMED FALSE+#else+#define ASA_PRINT_INTERMED TRUE+#endif+#endif++#ifndef ASA_PRINT_MORE+#define ASA_PRINT_MORE FALSE+#endif++char exit_msg[160];             /* temp storage for exit messages */++ /* The state of the system in terms of parameters and function value */+typedef struct {+  double cost;+  double *parameter;+#if ASA_PARALLEL+#if USER_ACCEPTANCE_TEST+  int par_user_accept_flag;+  int par_cost_accept_flag;+#endif+#endif+} STATE;++#if ASA_PARALLEL+  /* parallel generated states */+STATE *gener_block_state_qsort;+#endif++ /* essential MACROS */++#if USER_REANNEAL_PARAMETERS+#else+ /* FUNCTION_REANNEAL_PARAMS(temperature, tangent, max_tangent)+    determines the reannealed temperature. */+#define FUNCTION_REANNEAL_PARAMS(temperature, tangent, max_tangent) \+ (temperature * (max_tangent / tangent))+#endif++ /* IABS(i)+    absolute value for integers, in stdlib.h on _some_ machines */+#define IABS(i) ((i) < 0? -(i) : (i))++ /*  NO_REANNEAL(x)+    can determine whether to calculate derivatives. */+#define NO_REANNEAL(x)	(IABS(parameter_type[x]) == 2)++ /* VFOR+    is a simple macro to iterate on each parameter index. */++#define VFOR(index_v) \+ for (index_v = 0; index_v < *number_parameters; ++index_v)++#if CHECK_EXPONENT+ /* EXPONENT_CHECK+    checks that an exponent x is within a valid range and,+    if not, adjusts its magnitude to fit in the range. */+#define MIN_EXPONENT (0.9 * F_LOG ((double) MIN_DOUBLE))+#define MAX_EXPONENT (0.9 * F_LOG ((double) MAX_DOUBLE))+#define EXPONENT_CHECK(x) \+ ((x) < MIN_EXPONENT ? MIN_EXPONENT : \+ ((x) > MAX_EXPONENT ? MAX_EXPONENT : (x)))+#else+#define EXPONENT_CHECK(x) (x)+#endif /* CHECK_EXPONENT */++ /* PARAMETER_RANGE_TOO_SMALL(x)+    checks if the range of parameter x is too small to work with.+    If user_cost_function changes the parameter ranges,+    this test could be used to adaptively bypass+    some parameters, e.g., depending on constraints. */+#define PARAMETER_RANGE_TOO_SMALL(x) \+ (fabs(parameter_minimum[x] - parameter_maximum[x]) < (double) EPS_DOUBLE)++ /* INTEGER_PARAMETER(x)+    determines if the parameter is an integer type. */+#define INTEGER_PARAMETER(x) (parameter_type[x] > 0)++ /* ROW_COL_INDEX(i, j)+    converts from row i, column j to an index. */+#define ROW_COL_INDEX(i, j) ((i) + *number_parameters * (j))++#if HAVE_ANSI++ /* asa function prototypes */+void accept_new_state (double (*user_random_generator) (LONG_INT *),+                       LONG_INT * seed,+                       double *parameter_minimum,+                       double *parameter_maximum,+                       double *current_cost_temperature,+#if ASA_SAMPLE+                       double *current_user_parameter_temp,+#endif+                       ALLOC_INT * number_parameters,+                       LONG_INT * recent_number_acceptances,+                       LONG_INT * number_accepted,+                       LONG_INT * index_cost_acceptances,+                       LONG_INT * number_acceptances_saved,+                       LONG_INT * recent_number_generated,+                       LONG_INT * number_generated,+                       LONG_INT * index_parameter_generations,+                       STATE * current_generated_state,+                       STATE * last_saved_state,+#if ASA_SAMPLE+                       FILE * ptr_asa_out,+#endif+                       USER_DEFINES * OPTIONS);++void generate_new_state (double (*user_random_generator) (LONG_INT *),+                         LONG_INT * seed,+                         double *parameter_minimum,+                         double *parameter_maximum,+                         double *current_parameter_temperature,+#if USER_GENERATING_FUNCTION+                         double *initial_user_parameter_temp,+                         double *temperature_scale_parameters,+#endif+                         ALLOC_INT * number_parameters,+                         int *parameter_type,+                         STATE * current_generated_state,+                         STATE * last_saved_state, USER_DEFINES * OPTIONS);++void reanneal (double *parameter_minimum,+               double *parameter_maximum,+               double *tangents,+               double *maximum_tangent,+               double *current_cost_temperature,+               double *initial_cost_temperature,+               double *temperature_scale_cost,+               double *current_user_parameter_temp,+               double *initial_user_parameter_temp,+               double *temperature_scale_parameters,+               ALLOC_INT * number_parameters,+               int *parameter_type,+               LONG_INT * index_cost_acceptances,+               LONG_INT * index_parameter_generations,+               STATE * last_saved_state,+               STATE * best_generated_state, USER_DEFINES * OPTIONS);++void+  cost_derivatives (double (*user_cost_function)++                     +                    (double *, double *, double *, double *, double *,+                     ALLOC_INT *, int *, int *, int *, USER_DEFINES *),+                    double *parameter_minimum, double *parameter_maximum,+                    double *tangents, double *curvature,+                    double *maximum_tangent, ALLOC_INT * number_parameters,+                    int *parameter_type, int *exit_status,+                    int *curvature_flag, int *valid_state_generated_flag,+                    LONG_INT * number_invalid_generated_states,+                    STATE * current_generated_state,+                    STATE * best_generated_state, FILE * ptr_asa_out,+                    USER_DEFINES * OPTIONS);++double generate_asa_state (double (*user_random_generator) (LONG_INT *),+                           LONG_INT * seed, double *temp);++int+  asa_exit (double (*user_cost_function)++             +            (double *, double *, double *, double *, double *, ALLOC_INT *,+             int *, int *, int *, USER_DEFINES *), double *final_cost,+            double *parameter_initial_final, double *parameter_minimum,+            double *parameter_maximum, double *tangents, double *curvature,+            double *maximum_tangent, double *current_cost_temperature,+            double *initial_user_parameter_temp,+            double *current_user_parameter_temp,+            double *accepted_to_generated_ratio,+            ALLOC_INT * number_parameters, int *parameter_type,+            int *valid_state_generated_flag, int *exit_status,+            ALLOC_INT * index_exit_v, ALLOC_INT * start_sequence,+            LONG_INT * number_accepted, LONG_INT * best_number_accepted_saved,+            LONG_INT * index_cost_acceptances, LONG_INT * number_generated,+            LONG_INT * number_invalid_generated_states,+            LONG_INT * index_parameter_generations,+            LONG_INT * best_number_generated_saved,+            STATE * current_generated_state, STATE * last_saved_state,+            STATE * best_generated_state, FILE * ptr_asa_out,+            USER_DEFINES * OPTIONS);++void Exit_ASA (char *statement);++int asa_test_asa_options (LONG_INT * seed,+                          double *parameter_initial_final,+                          double *parameter_minimum,+                          double *parameter_maximum,+                          double *tangents,+                          double *curvature,+                          ALLOC_INT * number_parameters,+                          int *parameter_type,+                          int *valid_state_generated_flag,+                          int *exit_status,+                          FILE * ptr_asa_out, USER_DEFINES * OPTIONS);++int cost_function_test (double cost,+                        double *parameter,+                        double *parameter_minimum,+                        double *parameter_maximum,+                        ALLOC_INT * number_parameters,+                        double *xnumber_parameters);++void print_string (FILE * ptr_asa_out, char *string);+void print_string_index (FILE * ptr_asa_out, char *string, ALLOC_INT index);++#if ASA_PRINT+void print_state (double *parameter_minimum,+                  double *parameter_maximum,+                  double *tangents,+                  double *curvature,+                  double *current_cost_temperature,+                  double *current_user_parameter_temp,+                  double *accepted_to_generated_ratio,+                  ALLOC_INT * number_parameters,+                  int *curvature_flag,+                  LONG_INT * number_accepted,+                  LONG_INT * index_cost_acceptances,+                  LONG_INT * number_generated,+                  LONG_INT * number_invalid_generated_states,+                  STATE * last_saved_state,+                  STATE * best_generated_state,+                  FILE * ptr_asa_out, USER_DEFINES * OPTIONS);++void print_asa_options (FILE * ptr_asa_out, USER_DEFINES * OPTIONS);+#endif /* ASA_PRINT */+++#if MULTI_MIN+static int multi_compare (const void *cost_ii, const void *cost_jj);+double *multi_cost_qsort;+#endif++#if ASA_PARALLEL+static int sort_parallel (const void *cost_ii, const void *cost_jj);+#endif++#else /* HAVE_ANSI */+#endif /* HAVE_ANSI */++#endif /* _ASA_H_ */
+ _darcs/pristine/asa_usr.h view
@@ -0,0 +1,293 @@+#ifndef _ASA_USER_H_+#define _ASA_USER_H_++/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+***********************************************************************/++ /* $Id: asa_usr.h,v 25.15 2004/09/23 18:10:45 ingber Exp ingber $ */++ /* asa_usr.h for Adaptive Simulated Annealing */++#include "asa_usr_asa.h"++#define SHUFFLE 256             /* size of random array */++#if ASA_TEMPLATE_ASA_OUT_PID+#include <sys/types.h>+#endif++#if TIME_CALC+ /* print the time every PRINT_FREQUENCY function evaluations+    Define PRINT_FREQUENCY to 0 to not print out the time. */+#define PRINT_FREQUENCY ((LONG_INT) 1000)+#endif++#if USER_ACCEPTANCE_TEST+#define MIN(x,y)	((x) < (y) ? (x) : (y))+#endif++ /* system function prototypes */++#if ASA_TEMPLATE_ASA_OUT_PID+int getpid ();+#endif++#if HAVE_ANSI+++#if IO_PROTOTYPES+#if OPTIONS_FILE+int fscanf ();+#endif+#endif++ /* user-defined */+double USER_COST_FUNCTION (double *cost_parameters,+                           double *parameter_lower_bound,+                           double *parameter_upper_bound,+                           double *cost_tangents,+                           double *cost_curvature,+                           ALLOC_INT * parameter_dimension,+                           int *parameter_int_real,+                           int *cost_flag,+                           int *exit_code, USER_DEFINES * USER_OPTIONS);+#if ASA_LIB+int+asa_main (+           hs_cost_func *func, +           int number_parameters,+           double *upper_bounds,+           double *lower_bounds,+           int *type,+           double *main_cost_value,+           double *main_cost_parameters, +           int *main_exit_code,+           long int rand_seed+  );+#else+int main (int argc, char **argv);+#endif++#if ASA_TEMPLATE_LIB+int main ();+#endif++ /* possibly with accompanying data file */+int initialize_parameters (double *cost_parameters,+                           double *parameter_lower_bound,+                           double *parameter_upper_bound,+                           double *cost_tangents,+                           double *cost_curvature,+                           ALLOC_INT * parameter_dimension,+                           int *parameter_int_real,+#if OPTIONS_FILE_DATA+                           FILE * ptr_options,+#endif+                           USER_DEFINES * USER_OPTIONS);++//double myrand (LONG_INT * rand_seed);+//double randflt (LONG_INT * rand_seed);+//double resettable_randflt (LONG_INT * rand_seed, int reset);++#if USER_COST_SCHEDULE+double user_cost_schedule (double test_temperature,+                           USER_DEFINES * USER_OPTIONS);+#endif++#if USER_ACCEPTANCE_TEST+void user_acceptance_test (double current_cost,+                           double *parameter_lower_bound,+                           double *parameter_upper_bound,+                           ALLOC_INT * parameter_dimension,+                           USER_DEFINES * USER_OPTIONS);+#endif++#if USER_GENERATING_FUNCTION+double user_generating_distrib (LONG_INT * seed,+                                ALLOC_INT * parameter_dimension,+                                ALLOC_INT index_v,+                                double temperature_v,+                                double init_param_temp_v,+                                double temp_scale_params_v,+                                double parameter_v,+                                double parameter_range_v,+                                double *last_saved_parameter,+                                USER_DEFINES * USER_OPTIONS);+#endif++#if USER_REANNEAL_COST+int user_reanneal_cost (double *cost_best,+                        double *cost_last,+                        double *initial_cost_temperature,+                        double *current_cost_temperature,+                        USER_DEFINES * USER_OPTIONS);+#endif++#if USER_REANNEAL_PARAMETERS+double user_reanneal_params (double current_temp,+                             double tangent,+                             double max_tangent, USER_DEFINES * USER_OPTIONS);+#endif++#if ASA_TEMPLATE_SAMPLE+void sample (FILE * ptr_out, FILE * ptr_asa);+#endif++void Exit_USER (char *statement);++#else /* HAVE_ANSI */+#endif /* HAVE_ANSI */++void Exit_USER ();++#if SELF_OPTIMIZE+#if TIME_CALC+#define RECUR_PRINT_FREQUENCY ((LONG_INT) 1)+#endif++#if HAVE_ANSI                   /* HAVE_ANSI SELF_OPTIMIZE */+double RECUR_USER_COST_FUNCTION (double *recur_cost_parameters,+                                 double *recur_parameter_lower_bound,+                                 double *recur_parameter_upper_bound,+                                 double *recur_cost_tangents,+                                 double *recur_cost_curvature,+                                 ALLOC_INT * recur_parameter_dimension,+                                 int *recur_parameter_int_real,+                                 int *recur_cost_flag,+                                 int *recur_exit_code,+                                 USER_DEFINES * RECUR_USER_OPTIONS);++int recur_initialize_parameters (double *recur_cost_parameters,+                                 double *recur_parameter_lower_bound,+                                 double *recur_parameter_upper_bound,+                                 double *recur_cost_tangents,+                                 double *recur_cost_curvature,+                                 ALLOC_INT * recur_parameter_dimension,+                                 int *recur_parameter_int_real,+#if RECUR_OPTIONS_FILE_DATA+                                 FILE * recur_ptr_options,+#endif+                                 USER_DEFINES * RECUR_USER_OPTIONS);++#if USER_COST_SCHEDULE+double recur_user_cost_schedule (double test_temperature,+                                 USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#if USER_ACCEPTANCE_TEST+void recur_user_acceptance_test (double current_cost,+                                 double *recur_parameter_lower_bound,+                                 double *recur_parameter_upper_bound,+                                 ALLOC_INT * recur_parameter_dimension,+                                 USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#if USER_GENERATING_FUNCTION+double recur_user_generating_distrib (LONG_INT * seed,+                                      ALLOC_INT * recur_parameter_dimension,+                                      ALLOC_INT index_v,+                                      double temperature_v,+                                      double init_param_temp_v,+                                      double temp_scale_params_v,+                                      double parameter_v,+                                      double parameter_range_v,+                                      double *last_saved_parameter,+                                      USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#if USER_REANNEAL_COST+int recur_user_reanneal_cost (double *cost_best,+                              double *cost_last,+                              double *initial_cost_temperature,+                              double *current_cost_temperature,+                              USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#if USER_REANNEAL_PARAMETERS+double recur_user_reanneal_params (double current_temp,+                                   double tangent,+                                   double max_tangent,+                                   USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#else /* HAVE_ANSI SELF_OPTIMIZE */++double RECUR_USER_COST_FUNCTION ();+int recur_initialize_parameters ();++#if USER_COST_SCHEDULE+double recur_user_cost_schedule ();+#endif++#if USER_ACCEPTANCE_TEST+void recur_user_acceptance_test ();+#endif++#if USER_GENERATING_FUNCTION+double recur_user_generating_distrib ();+#endif++#if USER_REANNEAL_COST+int recur_user_reanneal_cost ();+#endif++#if USER_REANNEAL_PARAMETERS+double recur_user_reanneal_params ();+#endif++#endif /* HAVE_ANSI */+#endif /* SELF_OPTIMIZE */++#if FITLOC+#if HAVE_ANSI+double+  calcf (double (*user_cost_function)++          +         (double *, double *, double *, double *, double *, ALLOC_INT *,+          int *, int *, int *, USER_DEFINES *), double *cost_parameters,+         double *parameter_lower_bound, double *parameter_upper_bound,+         double *cost_tangents, double *cost_curvature,+         ALLOC_INT * parameter_dimension, int *parameter_int_real,+         int *cost_flag, int *exit_code, USER_DEFINES * USER_OPTIONS,+         FILE * ptr_out);++double+  fitloc (double (*user_cost_function)++           +          (double *, double *, double *, double *, double *, ALLOC_INT *,+           int *, int *, int *, USER_DEFINES *), double *cost_parameters,+          double *parameter_lower_bound, double *parameter_upper_bound,+          double *cost_tangents, double *cost_curvature,+          ALLOC_INT * parameter_dimension, int *parameter_int_real,+          int *cost_flag, int *exit_code, USER_DEFINES * USER_OPTIONS,+          FILE * ptr_out);++int+  simplex (double (*user_cost_function)++            +           (double *, double *, double *, double *, double *, ALLOC_INT *,+            int *, int *, int *, USER_DEFINES *), double *cost_parameters,+           double *parameter_lower_bound, double *parameter_upper_bound,+           double *cost_tangents, double *cost_curvature,+           ALLOC_INT * parameter_dimension, int *parameter_int_real,+           int *cost_flag, int *exit_code, USER_DEFINES * USER_OPTIONS,+           FILE * ptr_out, double tol1, double tol2, int no_progress,+           double alpha, double beta1, double beta2, double gamma,+           double delta);+#else /* HAVE_ANSI */++double calcf ();+double fitloc ();+int simplex ();++#endif /* HAVE_ANSI */+#endif /* FITLOC */++#endif /* _ASA_USER_H_ */
+ _darcs/pristine/asa_usr_asa.h view
@@ -0,0 +1,682 @@+#ifndef _ASA_USER_ASA_H_+#define _ASA_USER_ASA_H_++/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+***********************************************************************/++ /* $Id: asa_usr_asa.h,v 25.15 2004/09/23 18:10:49 ingber Exp ingber $ */++ /* asa_usr_asa.h for Adaptive Simulated Annealing */++#include <errno.h>+#include <math.h>+#include <stdio.h>+#include <stdlib.h>             /* misc defs on most machines */+#include <string.h>++/* required if use machine-defined {DBL_EPSILON DBL_MIN DBL_MAX} */+/* #include <float.h> */++/* test for memory leaks */+/* #include "/usr/local/include/leak.h" */++#define	TRUE			1+#define	FALSE			0++#define MIN(x,y)	((x) < (y) ? (x) : (y))+#define MAX(x,y)	((x) > (y) ? (x) : (y))++ /* DEFAULT PARAMETERS SETTINGS */++ /* Pre-Compile Options */++ /* Special ASA_TEMPLATEs */++#ifndef MY_TEMPLATE+#define MY_TEMPLATE TRUE+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_asa_user */++// #include <HsFFI.h>++typedef double hs_cost_func(double *x, int *flag);++/* #define ASA_LIB TRUE */+#define ASA_TEST FALSE+#define ASA_LIB TRUE+#define ASA_OUT  "STDOUT"+#define USER_OUT "STDOUT"+#define FITLOC TRUE+#define COST_FILE FALSE+// #define ASA_PRINT FALSE+// #define USER_ASA_OUT TRUE +#define OPTIONS_FILE FALSE+#define OPTIONAL_PTR_TYPE hs_cost_func+#define OPTIONAL_DATA_PTR TRUE+#define QUENCH_COST TRUE+#define QUENCH_PARAMETERS TRUE+++  /* you can add your own set of #define here */+#endif /* MY_TEMPLATE */++#ifndef ASA_TEMPLATE_LIB+#define ASA_TEMPLATE_LIB FALSE+#endif+#if ASA_TEMPLATE_LIB+#define ASA_LIB TRUE+#define ASA_TEST TRUE+#endif++#ifndef ASA_TEMPLATE_ASA_OUT_PID+#define ASA_TEMPLATE_ASA_OUT_PID FALSE+#endif+#if ASA_TEMPLATE_ASA_OUT_PID+#define USER_ASA_OUT TRUE+#endif++#ifndef ASA_TEMPLATE_MULTIPLE+#define ASA_TEMPLATE_MULTIPLE FALSE+#endif+#if ASA_TEMPLATE_MULTIPLE+#define COST_FILE FALSE+#define USER_ASA_OUT TRUE+#define ASA_TEST TRUE+#define QUENCH_COST TRUE+#define QUENCH_PARAMETERS TRUE+#define OPTIONS_FILE FALSE+#endif++#ifndef ASA_TEMPLATE_SELFOPT+#define ASA_TEMPLATE_SELFOPT FALSE+#endif+#if ASA_TEMPLATE_SELFOPT+#define COST_FILE FALSE+#define SELF_OPTIMIZE TRUE+#define OPTIONAL_DATA_DBL TRUE+#define USER_ASA_OUT TRUE+#define ASA_TEST TRUE+#define OPTIONS_FILE FALSE+#endif++#ifndef ASA_TEMPLATE_SAMPLE+#define ASA_TEMPLATE_SAMPLE FALSE+#endif+#if ASA_TEMPLATE_SAMPLE+#define COST_FILE FALSE+#define ASA_SAMPLE TRUE+#define USER_ACCEPTANCE_TEST TRUE+#define USER_COST_SCHEDULE TRUE+#define OPTIONS_FILE_DATA FALSE+#define USER_ACCEPT_ASYMP_EXP TRUE+#endif++#ifndef ASA_TEMPLATE_PARALLEL+#define ASA_TEMPLATE_PARALLEL FALSE+#endif+#if ASA_TEMPLATE_PARALLEL+#define COST_FILE FALSE+#define ASA_TEST TRUE+#define ASA_PARALLEL TRUE+#endif++#ifndef ASA_TEMPLATE_SAVE+#define ASA_TEMPLATE_SAVE FALSE+#endif+#if ASA_TEMPLATE_SAVE+#define COST_FILE FALSE+#define ASA_TEST TRUE+#define ASA_SAVE TRUE+#define QUENCH_PARAMETERS TRUE+#define QUENCH_COST TRUE+#endif++#ifndef ASA_TEMPLATE_QUEUE+#define ASA_TEMPLATE_QUEUE FALSE+#endif+#if ASA_TEMPLATE_QUEUE+#define ASA_QUEUE TRUE+#define ASA_RESOLUTION FALSE+#define ASA_TEST TRUE+#define COST_FILE FALSE+#define ASA_PRINT_MORE TRUE+#endif++#ifndef ASA_TEST_POINT+#define ASA_TEST_POINT FALSE+#endif+#if ASA_TEST_POINT+#define ASA_TEST TRUE+#define COST_FILE FALSE+#define SMALL_FLOAT 1.0E-50+#define QUENCH_COST TRUE+#endif++ /* Standard Pre-Compile Options */++#ifndef USER_COST_FUNCTION+#define USER_COST_FUNCTION cost_function+#endif++#if SELF_OPTIMIZE+#ifndef RECUR_USER_COST_FUNCTION+#define RECUR_USER_COST_FUNCTION recur_cost_function+#endif+#endif++#ifndef INCL_STDOUT+#define INCL_STDOUT TRUE+#endif+#if INCL_STDOUT+#define TIME_CALC FALSE+#endif++#ifndef OPTIONS_FILE+#define OPTIONS_FILE TRUE+#endif++#if OPTIONS_FILE+#ifndef OPTIONS_FILE_DATA+#define OPTIONS_FILE_DATA TRUE+#endif+#else+#define OPTIONS_FILE_DATA FALSE+#endif++#ifndef RECUR_OPTIONS_FILE+#define RECUR_OPTIONS_FILE FALSE+#endif++#if RECUR_OPTIONS_FILE+#ifndef RECUR_OPTIONS_FILE_DATA+#define RECUR_OPTIONS_FILE_DATA FALSE+#endif+#else+#define RECUR_OPTIONS_FILE_DATA FALSE+#endif++#ifndef COST_FILE+#define COST_FILE TRUE+#endif++#ifndef ASA_LIB+#define ASA_LIB FALSE+#endif++#ifndef HAVE_ANSI+#define HAVE_ANSI TRUE+#endif++#ifndef IO_PROTOTYPES+#define IO_PROTOTYPES FALSE+#endif++#ifndef TIME_CALC+#define TIME_CALC FALSE+#endif++#ifndef INT_LONG+#define INT_LONG TRUE+#endif++#if INT_LONG+#define LONG_INT long int+#else+#define LONG_INT int+#endif++#ifndef INT_ALLOC+#define INT_ALLOC FALSE+#endif++#if INT_ALLOC+#define ALLOC_INT int+#else+#define ALLOC_INT LONG_INT+#endif++ /* You can define SMALL_FLOAT to better correlate to your machine's+    precision, i.e., as used in asa */+#ifndef SMALL_FLOAT+#define SMALL_FLOAT 1.0E-18+#endif++ /* You can define your machine's maximum and minimum doubles here */+#ifndef MIN_DOUBLE+#define MIN_DOUBLE ((double) SMALL_FLOAT)+#endif++#ifndef MAX_DOUBLE+#define MAX_DOUBLE ((double) 1.0 / (double) SMALL_FLOAT)+#endif++#ifndef EPS_DOUBLE+#define EPS_DOUBLE ((double) SMALL_FLOAT)+#endif++#ifndef CHECK_EXPONENT+#define CHECK_EXPONENT FALSE+#endif++#ifndef ASA_TEST+#define ASA_TEST FALSE+#endif++#ifndef ASA_TEMPLATE+#define ASA_TEMPLATE FALSE+#endif++#ifndef USER_INITIAL_COST_TEMP+#define USER_INITIAL_COST_TEMP FALSE+#endif++#ifndef RATIO_TEMPERATURE_SCALES+#define RATIO_TEMPERATURE_SCALES FALSE+#endif++#ifndef USER_INITIAL_PARAMETERS_TEMPS+#define USER_INITIAL_PARAMETERS_TEMPS FALSE+#endif++#ifndef DELTA_PARAMETERS+#define DELTA_PARAMETERS FALSE+#endif++#ifndef QUENCH_PARAMETERS+#define QUENCH_PARAMETERS FALSE+#endif++#ifndef QUENCH_COST+#define QUENCH_COST FALSE+#endif++#ifndef QUENCH_PARAMETERS_SCALE+#define QUENCH_PARAMETERS_SCALE TRUE+#endif++#ifndef QUENCH_COST_SCALE+#define QUENCH_COST_SCALE TRUE+#endif++#ifndef OPTIONAL_DATA_DBL+#define OPTIONAL_DATA_DBL FALSE+#endif++#ifndef OPTIONAL_DATA_INT+#define OPTIONAL_DATA_INT FALSE+#endif++#ifndef OPTIONAL_DATA_PTR+#define OPTIONAL_DATA_PTR FALSE+#endif+#if OPTIONAL_DATA_PTR+/* user must define USER_TYPE; if a struct, it must be declared above */+#ifndef OPTIONAL_PTR_TYPE+#define OPTIONAL_PTR_TYPE USER_TYPE+#endif+#endif /* OPTIONAL_DATA_PTR */++#ifndef USER_REANNEAL_COST+#define USER_REANNEAL_COST FALSE+#endif++#ifndef USER_REANNEAL_PARAMETERS+#define USER_REANNEAL_PARAMETERS FALSE+#endif++#ifndef MAXIMUM_REANNEAL_INDEX+#define MAXIMUM_REANNEAL_INDEX 50000+#endif++#ifndef REANNEAL_SCALE+#define REANNEAL_SCALE 10+#endif++#ifndef USER_COST_SCHEDULE+#define USER_COST_SCHEDULE FALSE+#endif++#ifndef USER_ACCEPT_ASYMP_EXP+#define USER_ACCEPT_ASYMP_EXP FALSE+#endif++#ifndef USER_ACCEPT_THRESHOLD+#define USER_ACCEPT_THRESHOLD FALSE+#endif++#ifndef USER_ACCEPTANCE_TEST+#define USER_ACCEPTANCE_TEST FALSE+#endif++#ifndef USER_GENERATING_FUNCTION+#define USER_GENERATING_FUNCTION FALSE+#endif++ /* in asa.c, field-width.precision = G_FIELD.G_PRECISION */+#ifndef G_FIELD+#define G_FIELD 12+#endif+#ifndef G_PRECISION+#define G_PRECISION 7+#endif++#define INTEGER_TYPE		((int) 1)+#define REAL_TYPE		((int) -1)+#define INTEGER_NO_REANNEAL	((int) 2)+#define REAL_NO_REANNEAL	((int) -2)++ /* Set this to TRUE to self-optimize the Program Options */+#ifndef SELF_OPTIMIZE+#define SELF_OPTIMIZE FALSE+#endif++#ifndef USER_OUT+#define USER_OUT "asa_usr_out"+#endif++#ifndef USER_ASA_OUT+#define USER_ASA_OUT FALSE+#endif++#ifndef ASA_SAMPLE+#define ASA_SAMPLE FALSE+#endif++#ifndef ASA_QUEUE+#define ASA_QUEUE FALSE+#endif++#ifndef ASA_RESOLUTION+#define ASA_RESOLUTION FALSE+#endif++#ifndef ASA_PARALLEL+#define ASA_PARALLEL FALSE+#endif++#ifndef ASA_SAVE_OPT+#define ASA_SAVE_OPT FALSE+#endif+#if ASA_SAVE_OPT+#define ASA_SAVE TRUE+#endif++#ifndef ASA_SAVE_BACKUP+#define ASA_SAVE_BACKUP FALSE+#endif+#if ASA_SAVE_BACKUP+#define ASA_SAVE TRUE+#endif++#ifndef ASA_SAVE+#define ASA_SAVE FALSE+#endif++#ifndef ASA_PIPE+#define ASA_PIPE FALSE+#endif++#ifndef ASA_PIPE_FILE+#define ASA_PIPE_FILE FALSE+#endif++#ifndef FDLIBM_POW+#define FDLIBM_POW FALSE+#endif+#if FDLIBM_POW+#define F_POW s_pow+#else+#define F_POW pow+#endif++#ifndef FDLIBM_LOG+#define FDLIBM_LOG FALSE+#endif+#if FDLIBM_LOG+#define F_LOG s_log+#else+#define F_LOG log+#endif++#ifndef FDLIBM_EXP+#define FDLIBM_EXP FALSE+#endif+#if FDLIBM_EXP+#define F_EXP s_exp+#else+#define F_EXP exp+#endif++#ifndef FITLOC+#define FITLOC FALSE+#endif++#ifndef FITLOC_ROUND+#define FITLOC_ROUND TRUE+#endif++#ifndef FITLOC_PRINT+#define FITLOC_PRINT TRUE+#endif++#ifndef MULTI_MIN+#define MULTI_MIN FALSE+#endif++ /* Program Options */++typedef struct {+  LONG_INT Limit_Acceptances;+  LONG_INT Limit_Generated;+  int Limit_Invalid_Generated_States;+  double Accepted_To_Generated_Ratio;++  double Cost_Precision;+  int Maximum_Cost_Repeat;+  int Number_Cost_Samples;+  double Temperature_Ratio_Scale;+  double Cost_Parameter_Scale_Ratio;+  double Temperature_Anneal_Scale;+#if USER_INITIAL_COST_TEMP+  double *User_Cost_Temperature;+#endif++  int Include_Integer_Parameters;+  int User_Initial_Parameters;+  ALLOC_INT Sequential_Parameters;+  double Initial_Parameter_Temperature;+#if RATIO_TEMPERATURE_SCALES+  double *User_Temperature_Ratio;+#endif+#if USER_INITIAL_PARAMETERS_TEMPS+  double *User_Parameter_Temperature;+#endif++  int Acceptance_Frequency_Modulus;+  int Generated_Frequency_Modulus;+  int Reanneal_Cost;+  int Reanneal_Parameters;++  double Delta_X;+#if DELTA_PARAMETERS+  double *User_Delta_Parameter;+#endif+  int User_Tangents;+  int Curvature_0;++#if QUENCH_PARAMETERS+  double *User_Quench_Param_Scale;+#endif+#if QUENCH_COST+  double *User_Quench_Cost_Scale;+#endif++  LONG_INT N_Accepted;+  LONG_INT N_Generated;+  int Locate_Cost;+  int Immediate_Exit;++  double *Best_Cost;+  double *Best_Parameters;+  double *Last_Cost;+  double *Last_Parameters;++#if OPTIONAL_DATA_DBL+  ALLOC_INT Asa_Data_Dim_Dbl;+  double *Asa_Data_Dbl;+#endif+#if OPTIONAL_DATA_INT+  ALLOC_INT Asa_Data_Dim_Int;+  LONG_INT *Asa_Data_Int;+#endif+#if OPTIONAL_DATA_PTR+  ALLOC_INT Asa_Data_Dim_Ptr;+  OPTIONAL_PTR_TYPE *Asa_Data_Ptr;+#endif+#if USER_ASA_OUT+  char *Asa_Out_File;+#endif+#if USER_COST_SCHEDULE+  double (*Cost_Schedule) ();+#endif+#if USER_ACCEPT_ASYMP_EXP+  double Asymp_Exp_Param;+#endif+#if USER_ACCEPTANCE_TEST+  void (*Acceptance_Test) ();+  int User_Acceptance_Flag;+  int Cost_Acceptance_Flag;+  double Cost_Temp_Curr;+  double Cost_Temp_Init;+  double Cost_Temp_Scale;+  double Prob_Bias;+  LONG_INT *Random_Seed;+#endif+#if USER_GENERATING_FUNCTION+  double (*Generating_Distrib) ();+#endif+#if USER_REANNEAL_COST+  int (*Reanneal_Cost_Function) ();+#endif+#if USER_REANNEAL_PARAMETERS+  double (*Reanneal_Params_Function) ();+#endif+#if ASA_SAMPLE+  double Bias_Acceptance;+  double *Bias_Generated;+  double Average_Weights;+  double Limit_Weights;+#endif+#if ASA_QUEUE+  ALLOC_INT Queue_Size;+  double *Queue_Resolution;+#endif+#if ASA_RESOLUTION+  double *Coarse_Resolution;+#endif+#if FITLOC+  int Fit_Local;+  int Iter_Max;+  double Penalty;+#endif+#if MULTI_MIN+  int Multi_Number;+  double *Multi_Cost;+  double **Multi_Params;+  double *Multi_Grid;+  int Multi_Specify;+#endif+#if ASA_PARALLEL+  int Gener_Mov_Avr;+  LONG_INT Gener_Block;+  LONG_INT Gener_Block_Max;+#endif+  int Asa_Recursive_Level;+} USER_DEFINES;++ /* system function prototypes */++#if HAVE_ANSI++/* This block gives trouble under some Ultrix */+#if FALSE+int fprintf (FILE * fp, const char *string, ...);+int sprintf (char *s, const char *format, ...);+FILE *popen (const char *command, const char *mode);+void exit (int code);+#endif++#if IO_PROTOTYPES+int fprintf ();+int sprintf ();+int fflush (FILE * fp);+int fclose (FILE * fp);+void exit ();+int fread ();+int fwrite ();+int pclose ();+#endif++double+  asa (double (*user_cost_function)++        +       (double *, double *, double *, double *, double *, ALLOC_INT *, int *,+        int *, int *, USER_DEFINES *),+       double (*user_random_generator) (LONG_INT *), LONG_INT * rand_seed,+       double *parameter_initial_final, double *parameter_minimum,+       double *parameter_maximum, double *tangents, double *curvature,+       ALLOC_INT * number_parameters, int *parameter_type,+       int *valid_state_generated_flag, int *exit_status,+       USER_DEFINES * OPTIONS);++#if TIME_CALC+void print_time (char *message, FILE * ptr_out);+#endif++#if FDLIBM_POW+double s_pow (double x, double y);+#endif+#if FDLIBM_LOG+double s_log (double x);+#endif+#if FDLIBM_EXP+double s_exp (double x);+#endif++#else /* HAVE_ANSI */++#if IO_PROTOTYPES+int fprintf ();+int sprintf ();+int fflush ();+int fclose ();+int fread ();+int fwrite ();+FILE *popen ();+int pclose ();+#endif++double asa ();++#if TIME_CALC+void print_time ();+#endif++#if FDLIBM_POW+double s_pow ();+#endif+#if FDLIBM_LOG+double s_log ();+#endif+#if FDLIBM_EXP+double s_exp ();+#endif++#endif /* HAVE_ANSI */++#endif /* _ASA_USER_ASA_H_ */
+ _darcs/pristine/hs_asa.c view
@@ -0,0 +1,4369 @@+/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+* Modified by John Meacham for Haskell interface+***********************************************************************/++#include "asa_usr.h"+++++char user_exit_msg[160];        /* temp storage for exit messages */+FILE *ptr_out;++static double resettable_randflt (LONG_INT * rand_seed, int reset);+static double randflt (LONG_INT * rand_seed);+/***********************************************************************+* main+*	This is a sample calling program to optimize using ASA+***********************************************************************/+int+asa_main (+           hs_cost_func *func, +           int number_parameters,+           double *upper_bounds,+           double *lower_bounds,+           int *type,+           double *main_cost_value,+           double *main_cost_parameters, +           int *main_exit_code,+           long int initial_rand_seed+  )+{+  int i;+  int *exit_code;+  ALLOC_INT n_param;+#if ASA_TEMPLATE_SAMPLE+  FILE *ptr_asa;+#endif+#if MULTI_MIN+  int multi_index;+#endif++  /* pointer to array storage for asa arguments */+  double *parameter_lower_bound, *parameter_upper_bound, *cost_parameters,+    *cost_tangents, *cost_curvature;+  double cost_value;++  int initialize_parameters_value;++  /* the number of parameters to optimize */+  ALLOC_INT *parameter_dimension;++  /* pointer to array storage for parameter type flags */+  int *parameter_int_real;++  /* valid flag for cost function */+  int *cost_flag;++  /* seed for random number generator */+  LONG_INT *rand_seed;++  USER_DEFINES *USER_OPTIONS;++#if MY_TEMPLATE                 /* MY_TEMPLATE_main_decl */+  /* add some declarations if required */+#endif++#if ASA_TEMPLATE_MULTIPLE+  int n_asa, n_trajectory;+  ALLOC_INT index;+#if HAVE_ANSI+  char asa_file[8] = "asa_x_y";+#else+  char asa_file[8];+#endif /* HAVE_ANSI */+#endif /* ASA_TEMPLATE_MULTIPLE */+++  if ((USER_OPTIONS =+       (USER_DEFINES *) calloc (1, sizeof (USER_DEFINES))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): USER_DEFINES");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if OPTIONAL_DATA_PTR+#if ASA_TEMPLATE+  USER_OPTIONS->Asa_Data_Dim_Ptr = 256;+  if ((USER_OPTIONS->Asa_Data_Ptr =+       (OPTIONAL_PTR_TYPE *) calloc (USER_OPTIONS->Asa_Data_Dim_Ptr,+                                     sizeof (OPTIONAL_PTR_TYPE))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): USER_OPTIONS->Asa_Data_Ptr");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* ASA_TEMPLATE */+#endif /* OPTIONAL_DATA_PTR */+++  if (!strcmp (USER_OUT, "STDOUT")) {+#if INCL_STDOUT+    ptr_out = stdout;+#endif /* INCL_STDOUT */+  } else {+    ptr_out = fopen (USER_OUT, "w");+  }+++  fflush (ptr_out);++  if ((rand_seed = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): rand_seed");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  *rand_seed = initial_rand_seed;++  /* initialize random number generator with first call */+  resettable_randflt (rand_seed, 1);++  /* Initialize the users parameters, allocating space, etc.+     Note that the default is to have asa generate the initial+     cost_parameters that satisfy the user's constraints. */++  if ((parameter_dimension =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): parameter_dimension");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((exit_code = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): exit_code");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((cost_flag = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): cost_flag");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  //USER_OPTIONS->Limit_Acceptances = 10000; +  USER_OPTIONS->Limit_Acceptances = 1000;+  USER_OPTIONS->Limit_Generated = 99999;+  USER_OPTIONS->Limit_Invalid_Generated_States = 1000;+  /* USER_OPTIONS->Accepted_To_Generated_Ratio = 1.0E-6; */+  USER_OPTIONS->Accepted_To_Generated_Ratio = 1.0E-4;++  USER_OPTIONS->Cost_Precision = 1.0E-18;+  USER_OPTIONS->Maximum_Cost_Repeat = 5;+  USER_OPTIONS->Number_Cost_Samples = 5;+  USER_OPTIONS->Temperature_Ratio_Scale = 1.0E-5;+  USER_OPTIONS->Cost_Parameter_Scale_Ratio = 1.0;+  USER_OPTIONS->Temperature_Anneal_Scale = 100.0;++  USER_OPTIONS->Include_Integer_Parameters = FALSE;+  USER_OPTIONS->User_Initial_Parameters = FALSE;+  USER_OPTIONS->Sequential_Parameters = -1;+  USER_OPTIONS->Initial_Parameter_Temperature = 1.0;++  USER_OPTIONS->Acceptance_Frequency_Modulus = 100;+  USER_OPTIONS->Generated_Frequency_Modulus = 10000;+  USER_OPTIONS->Reanneal_Cost = 1;+  USER_OPTIONS->Reanneal_Parameters = TRUE;++  USER_OPTIONS->Delta_X = 0.001;+  USER_OPTIONS->User_Tangents = FALSE;+  USER_OPTIONS->Curvature_0 = FALSE;+++  /* ALLOCATE STORAGE */+++#if USER_ASA_OUT+  if ((USER_OPTIONS->Asa_Out_File =+       (char *) calloc (80, sizeof (char))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): USER_OPTIONS->Asa_Out_File");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif++  /* the number of parameters for the cost function */+#if OPTIONS_FILE_DATA+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%s", read_option);++#if INT_ALLOC+  fscanf (ptr_options, "%d", &read_int);+  *parameter_dimension = read_int;+#else+#if INT_LONG+  fscanf (ptr_options, "%ld", &read_long);+  *parameter_dimension = read_long;+#else+  fscanf (ptr_options, "%d", &read_int);+  *parameter_dimension = read_int;+#endif+#endif++#else /* OPTIONS_FILE_DATA */+#endif /* OPTIONS_FILE_DATA */+#if MY_TEMPLATE                 /* MY_TEMPLATE_dim */+  *parameter_dimension = number_parameters;+  /* If not using OPTIONS_FILE_DATA or data read from asa_opt,+     insert the number of parameters for the cost_function */+#endif /* MY_TEMPLATE dim */++#if ASA_TEMPLATE_SAMPLE+  *parameter_dimension = 2;+  USER_OPTIONS->Limit_Acceptances = 2000;+  USER_OPTIONS->User_Tangents = TRUE;+  USER_OPTIONS->Limit_Weights = 1.0E-7;+#endif+#if ASA_TEMPLATE_PARALLEL+  USER_OPTIONS->Gener_Block = 100;+  USER_OPTIONS->Gener_Block_Max = 512;+  USER_OPTIONS->Gener_Mov_Avr = 3;+#endif++  /* allocate parameter minimum space */+  if ((parameter_lower_bound =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): parameter_lower_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* allocate parameter maximum space */+  if ((parameter_upper_bound =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): parameter_upper_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* allocate parameter initial values; the parameter final values+     will be stored here later */+  if ((cost_parameters =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): cost_parameters");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* allocate the parameter types, real or integer */+  if ((parameter_int_real =+       (int *) calloc (*parameter_dimension, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): parameter_int_real");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* allocate space for parameter cost_tangents -+     used for reannealing */+  if ((cost_tangents =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): cost_tangents");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if (USER_OPTIONS->Curvature_0 == FALSE || USER_OPTIONS->Curvature_0 == -1) {+    /* allocate space for parameter cost_curvatures/covariance */+    if ((cost_curvature =+         (double *) calloc ((*parameter_dimension) *+                            (*parameter_dimension),+                            sizeof (double))) == NULL) {+      strcpy (user_exit_msg, "main()/asa_main(): cost_curvature");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  } else {+    cost_curvature = (double *) NULL;+  }++#if USER_COST_SCHEDULE+  USER_OPTIONS->Cost_Schedule = user_cost_schedule;+#endif+#if USER_ACCEPTANCE_TEST+  USER_OPTIONS->Acceptance_Test = user_acceptance_test;+#endif+#if USER_ACCEPT_ASYMP_EXP+  USER_OPTIONS->Asymp_Exp_Param = 1.0;+#endif+#if USER_GENERATING_FUNCTION+  USER_OPTIONS->Generating_Distrib = user_generating_distrib;+#endif+#if USER_REANNEAL_COST+  USER_OPTIONS->Reanneal_Cost_Function = user_reanneal_cost;+#endif+#if USER_REANNEAL_PARAMETERS+  USER_OPTIONS->Reanneal_Params_Function = user_reanneal_params;+#endif++#if MY_TEMPLATE                 /* MY_TEMPLATE_pre_initialize */+  /* last changes before entering initialize_parameters() */+  USER_OPTIONS->Asa_Data_Ptr = func;+  USER_OPTIONS->Asa_Data_Dim_Ptr = 1;+  memcpy(parameter_lower_bound,lower_bounds,sizeof(double)*number_parameters);+  memcpy(cost_parameters,lower_bounds,sizeof(double)*number_parameters);+  memcpy(parameter_upper_bound,upper_bounds,sizeof(double)*number_parameters);+  memcpy(parameter_int_real, type, sizeof(int)*number_parameters);+#endif++  initialize_parameters_value = initialize_parameters (cost_parameters,+                                                       parameter_lower_bound,+                                                       parameter_upper_bound,+                                                       cost_tangents,+                                                       cost_curvature,+                                                       parameter_dimension,+                                                       parameter_int_real,+#if OPTIONS_FILE_DATA+                                                       ptr_options,+#endif+                                                       USER_OPTIONS);++  if (initialize_parameters_value == -2)+    return (initialize_parameters_value);++  for(i = 0; i < number_parameters; i++) {+          USER_OPTIONS->User_Quench_Param_Scale[i] = 1.0;+  }+        USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;++  /* optimize the cost_function, returning the results in+     cost_value and cost_parameters */+#if ASA_TEMPLATE_MULTIPLE+  /* multiple asa() quenched calls + multiple asa_out files+     (To get longer quenched runs, decrease SMALL_FLOAT.) */+  for (n_asa = 1; n_asa <= *parameter_dimension; n_asa++) {+    asa_file[4] = 'A' + n_asa - 1;+    USER_OPTIONS->User_Quench_Cost_Scale[0] = (double) n_asa;+    for (index = 0; index < *parameter_dimension; ++index)+      USER_OPTIONS->User_Quench_Param_Scale[index] = (double) n_asa;+    for (n_trajectory = 0; n_trajectory < 3; ++n_trajectory) {+      asa_file[6] = 'a' + n_trajectory;+      strcpy (USER_OPTIONS->Asa_Out_File, asa_file);+#endif++#if ASA_TEMPLATE_ASA_OUT_PID+      pid_file[0] = 'a';+      pid_file[1] = 's';+      pid_file[2] = 'a';+      pid_file[3] = '_';+      pid_file[4] = 'o';+      pid_file[5] = 'u';+      pid_file[6] = 't';+      pid_file[7] = '_';++      pid_int = getpid ();+      if (pid_int < 0) {+        pid_file[7] = '0';+        pid_int = -pid_int;+      }++      strcpy (USER_OPTIONS->Asa_Out_File, pid_file);+#endif+      cost_value =+        asa (USER_COST_FUNCTION,+             randflt,+             rand_seed,+             cost_parameters,+             parameter_lower_bound,+             parameter_upper_bound,+             cost_tangents,+             cost_curvature,+             parameter_dimension,+             parameter_int_real, cost_flag, exit_code, USER_OPTIONS);+      if (*exit_code == -1) {+#if INCL_STDOUT+        printf ("\n\n*** error in calloc in ASA ***\n\n");+#endif /* INCL_STDOUT */+        fprintf (ptr_out, "\n\n*** error in calloc in ASA ***\n\n");+        fflush (ptr_out);+        return (-1);+      }+#if MULTI_MIN+      fprintf (ptr_out, "Multi_Specify = %d\n", USER_OPTIONS->Multi_Specify);+#if INT_LONG+      fprintf (ptr_out, "N_Accepted = %ld\n", USER_OPTIONS->N_Accepted);+#else+      fprintf (ptr_out, "N_Accepted = %d\n", USER_OPTIONS->N_Accepted);+#endif+#if ASA_RESOLUTION+      for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+        fprintf (ptr_out,+#if INT_ALLOC+                 "Coarse_Resolution[%d] = %12.7g\n",+#else+#if INT_LONG+                 "Coarse_Resolution[%ld] = %12.7g\n",+#else+                 "Coarse_Resolution[%d] = %12.7g\n",+#endif+#endif+                 n_param, USER_OPTIONS->Coarse_Resolution[n_param]);+      }+#else /* ASA_RESOLUTION */+      for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+        fprintf (ptr_out,+#if INT_ALLOC+                 "Multi_Grid[%d] = %12.7g\n",+#else+#if INT_LONG+                 "Multi_Grid[%ld] = %12.7g\n",+#else+                 "Multi_Grid[%d] = %12.7g\n",+#endif+#endif+                 n_param, USER_OPTIONS->Multi_Grid[n_param]);+      }+#endif /* ASA_RESOLUTION */+      fprintf (ptr_out, "\n");+      for (multi_index = 0; multi_index < USER_OPTIONS->Multi_Number;+           ++multi_index) {+        fprintf (ptr_out, "\n");+        fprintf (ptr_out, "Multi_Cost[%d] = %12.7g\n",+                 multi_index, USER_OPTIONS->Multi_Cost[multi_index]);+        for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+          fprintf (ptr_out,+#if INT_ALLOC+                   "Multi_Params[%d][%d] = %12.7g\n",+#else+#if INT_LONG+                   "Multi_Params[%d][%ld] = %12.7g\n",+#else+                   "Multi_Params[%d][%d] = %12.7g\n",+#endif+#endif+                   multi_index, n_param,+                   USER_OPTIONS->Multi_Params[multi_index][n_param]);+        }+      }+      fprintf (ptr_out, "\n");+      fflush (ptr_out);+#endif /* MULTI_MIN */++#if FITLOC+      /* Fit_Local, Iter_Max and Penalty may be set adaptively */+      USER_OPTIONS->Penalty = 1000;+      USER_OPTIONS->Fit_Local = 0;+      USER_OPTIONS->Iter_Max = 500;+      if (USER_OPTIONS->Fit_Local >= 1) {+        cost_value = fitloc (USER_COST_FUNCTION,+                             cost_parameters,+                             parameter_lower_bound,+                             parameter_upper_bound,+                             cost_tangents,+                             cost_curvature,+                             parameter_dimension,+                             parameter_int_real,+                             cost_flag, exit_code, USER_OPTIONS, ptr_out);+      }+#endif /* FITLOC */+#if MY_TEMPLATE                 /* MY_TEMPLATE_post_asa */+#endif+      *main_cost_value = cost_value;+      for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+        main_cost_parameters[n_param] = cost_parameters[n_param];+      }+      *main_exit_code = *exit_code;++      fprintf (ptr_out, "exit code = %d\n", *exit_code);+      fprintf (ptr_out, "final cost value = %-12.7g\n", cost_value);+      fprintf (ptr_out, "%12s %12s\n","parameter","value");+      for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+        fprintf (ptr_out,+#if INT_ALLOC+                 "%12d %12.7g\n",+#else+#if INT_LONG+                 "%12ld %12.7g\n",+#else+                 "%12d %12.7g\n",+#endif+#endif+                 n_param, cost_parameters[n_param]);+      }+++#if ASA_TEMPLATE_MULTIPLE+    }+  }+#endif++#if ASA_TEMPLATE_SAMPLE+  ptr_asa = fopen ("asa_out", "r");+  sample (ptr_out, ptr_asa);+#endif++  /* close all files */+  ptr_out != stdout && fclose (ptr_out);+#if OPTIONAL_DATA_DBL+  free (USER_OPTIONS->Asa_Data_Dbl);+#endif+#if OPTIONAL_DATA_INT+  free (USER_OPTIONS->Asa_Data_Int);+#endif+#if OPTIONAL_DATA_PTR+#if MY_TEMPLATE+  /* Instead of freeing Asa_Data_Ptr, if memory has been allocated+   * outside ASA, e.g., by the use of ASA_LIB, use the following: */+  USER_OPTIONS->Asa_Data_Ptr = NULL; +#endif /* MY_TEMPLATE */+  free (USER_OPTIONS->Asa_Data_Ptr);+#endif+#if USER_ASA_OUT+  free (USER_OPTIONS->Asa_Out_File);+#endif+#if ASA_SAMPLE+  free (USER_OPTIONS->Bias_Generated);+#endif+#if ASA_QUEUE+#if ASA_RESOLUTION+#else+  free (USER_OPTIONS->Queue_Resolution);+#endif+#endif+#if ASA_RESOLUTION+  free (USER_OPTIONS->Coarse_Resolution);+#endif+  if (USER_OPTIONS->Curvature_0 == FALSE || USER_OPTIONS->Curvature_0 == -1)+    free (cost_curvature);+#if USER_INITIAL_PARAMETERS_TEMPS+  free (USER_OPTIONS->User_Parameter_Temperature);+#endif+#if USER_INITIAL_COST_TEMP+  free (USER_OPTIONS->User_Cost_Temperature);+#endif+#if DELTA_PARAMETERS+  free (USER_OPTIONS->User_Delta_Parameter);+#endif+#if QUENCH_PARAMETERS+  free (USER_OPTIONS->User_Quench_Param_Scale);+#endif+#if QUENCH_COST+  free (USER_OPTIONS->User_Quench_Cost_Scale);+#endif+#if RATIO_TEMPERATURE_SCALES+  free (USER_OPTIONS->User_Temperature_Ratio);+#endif+#if MULTI_MIN+  free (USER_OPTIONS->Multi_Cost);+  free (USER_OPTIONS->Multi_Grid);+  for (multi_index = 0; multi_index < USER_OPTIONS->Multi_Number;+       ++multi_index) {+    free (USER_OPTIONS->Multi_Params[multi_index]);+  }+  free (USER_OPTIONS->Multi_Params);+#endif /* MULTI_MIN */+  free (USER_OPTIONS);+  free (parameter_dimension);+  free (exit_code);+  free (cost_flag);+  free (parameter_lower_bound);+  free (parameter_upper_bound);+  free (cost_parameters);+  free (parameter_int_real);+  free (cost_tangents);+  free (rand_seed);+  return (0);+  /* NOTREACHED */+}++/***********************************************************************+* initialize_parameters - sample parameter initialization function+*	This depends on the users cost function to optimize (minimum).+*	The routine allocates storage needed for asa. The user should+*	define the number of parameters and their ranges,+*	and make sure the initial parameters are within+*	the minimum and maximum ranges. The array+*	parameter_int_real should be REAL_TYPE (-1) for real parameters,+*	and INTEGER_TYPE (1) for integer values+***********************************************************************/+#if HAVE_ANSI+int+initialize_parameters (double *cost_parameters,+                       double *parameter_lower_bound,+                       double *parameter_upper_bound,+                       double *cost_tangents,+                       double *cost_curvature,+                       ALLOC_INT * parameter_dimension,+                       int *parameter_int_real,+#if OPTIONS_FILE_DATA+                       FILE * ptr_options,+#endif+                       USER_DEFINES * USER_OPTIONS)+#else+int+initialize_parameters (cost_parameters,+                       parameter_lower_bound,+                       parameter_upper_bound,+                       cost_tangents,+                       cost_curvature,+                       parameter_dimension, parameter_int_real,+#if OPTIONS_FILE_DATA+                       ptr_options,+#endif+                       USER_OPTIONS)+     double *cost_parameters;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+#if OPTIONS_FILE_DATA+     FILE *ptr_options;+#endif+     USER_DEFINES *USER_OPTIONS;+#endif+{+  ALLOC_INT index;+#if OPTIONS_FILE_DATA+  char read_option[80];+  ALLOC_INT read_index;+#endif+#if MULTI_MIN+  int multi_index;+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_init_decl */+  /* add some declarations if required */+#endif++  index = 0;+#if OPTIONS_FILE_DATA+  fscanf (ptr_options, "%s", read_option);++  for (index = 0; index < *parameter_dimension; ++index) {+#if MY_TEMPLATE                 /* MY_TEMPLATE_read_opt */+    /* put in some code as required to alter lines read from asa_opt */+#endif+#if INT_ALLOC+    fscanf (ptr_options, "%d", &read_index);+#else+#if INT_LONG+    fscanf (ptr_options, "%ld", &read_index);+#else+    fscanf (ptr_options, "%d", &read_index);+#endif+#endif+    fscanf (ptr_options, "%lf%lf%lf%d",+            &(parameter_lower_bound[read_index]),+            &(parameter_upper_bound[read_index]),+            &(cost_parameters[read_index]),+            &(parameter_int_real[read_index]));+  }+#else /* OPTIONS_FILE_DATA */+#if ASA_TEST+  /* store the parameter ranges */+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_lower_bound[index] = -10000.0;+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_upper_bound[index] = 10000.0;++  /* store the initial parameter types */+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_int_real[index] = REAL_TYPE;++  /* store the initial parameter values */+  for (index = 0; index < *parameter_dimension / 4.0; ++index) {+    cost_parameters[4 * (index + 1) - 4] = 999.0;+    cost_parameters[4 * (index + 1) - 3] = -1007.0;+    cost_parameters[4 * (index + 1) - 2] = 1001.0;+    cost_parameters[4 * (index + 1) - 1] = -903.0;+  }+#endif /* ASA_TEST */+#endif /* OPTIONS_FILE_DATA */+#if ASA_TEMPLATE_SAMPLE+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_lower_bound[index] = 0;+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_upper_bound[index] = 2.0;+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_int_real[index] = REAL_TYPE;+  for (index = 0; index < *parameter_dimension; ++index)+    cost_parameters[index] = 0.5;+#endif++#if USER_INITIAL_PARAMETERS_TEMPS+  if ((USER_OPTIONS->User_Parameter_Temperature =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Parameter_Temperature");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Parameter_Temperature[index] = 1.0;+#endif+#endif /* USER_INITIAL_PARAMETERS_TEMPS */+#if USER_INITIAL_COST_TEMP+  if ((USER_OPTIONS->User_Cost_Temperature =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Cost_Temperature");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  USER_OPTIONS->User_Cost_Temperature[0] = 5.936648E+09;+#endif+#endif /* USER_INITIAL_COST_TEMP */+#if DELTA_PARAMETERS+  if ((USER_OPTIONS->User_Delta_Parameter =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Delta_Parameter");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Delta_Parameter[index] = 0.001;+#endif+#endif /* DELTA_PARAMETERS */+#if QUENCH_PARAMETERS+  if ((USER_OPTIONS->User_Quench_Param_Scale =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Quench_Param_Scale");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#if ASA_TEMPLATE_MULTIPLE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#if ASA_TEMPLATE_SAVE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#endif /* QUENCH_PARAMETERS */+#if QUENCH_COST+  if ((USER_OPTIONS->User_Quench_Cost_Scale =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Quench_Cost_Scale");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#if ASA_TEMPLATE_MULTIPLE+  USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#if ASA_TEMPLATE_SAVE+  USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#endif /* QUENCH_COST */++  /* use asa_opt to read in QUENCH USER_OPTIONS */+#if OPTIONS_FILE_DATA+#if QUENCH_COST+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &(USER_OPTIONS->User_Quench_Cost_Scale[0]));++#if QUENCH_PARAMETERS+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%s", read_option);+  for (index = 0; index < *parameter_dimension; ++index) {+#if INT_ALLOC+    fscanf (ptr_options, "%d", &read_index);+#else+#if INT_LONG+    fscanf (ptr_options, "%ld", &read_index);+#else+    fscanf (ptr_options, "%d", &read_index);+#endif+#endif+    fscanf (ptr_options, "%lf",+            &(USER_OPTIONS->User_Quench_Param_Scale[read_index]));+  }+#endif /* QUENCH_PARAMETERS */+#endif /* QUENCH_COST */+#endif /* OPTIONS_FILE_DATA */++#if RATIO_TEMPERATURE_SCALES+  if ((USER_OPTIONS->User_Temperature_Ratio =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Temperature_Ratio");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Temperature_Ratio[index] = 1.0;+#endif+#endif /* RATIO_TEMPERATURE_SCALES */+  /* Defines the limit of collection of sampled data by asa */+#if ASA_SAMPLE+  /* create memory for Bias_Generated[] */+  if ((USER_OPTIONS->Bias_Generated =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Bias_Generated");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif++#if ASA_RESOLUTION+  if ((USER_OPTIONS->Coarse_Resolution =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Coarse_Resolution");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->Coarse_Resolution[index] = 1.0;+#endif+#endif /* ASA_RESOLUTION */+#if ASA_QUEUE+#if ASA_RESOLUTION+  USER_OPTIONS->Queue_Resolution = USER_OPTIONS->Coarse_Resolution;+#else /* ASA_RESOLUTION */+  if ((USER_OPTIONS->Queue_Resolution =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Queue_Resolution");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* ASA_RESOLUTION */+#if ASA_TEMPLATE_QUEUE+  USER_OPTIONS->Queue_Size = 100;+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->Queue_Resolution[index] = 0.001;+#endif+#endif /* ASA_QUEUE */+#if MULTI_MIN+#if ASA_TEMPLATE+  USER_OPTIONS->Multi_Number = 2;+#endif+  if ((USER_OPTIONS->Multi_Cost =+       (double *) calloc (USER_OPTIONS->Multi_Number,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Multi_Cost");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((USER_OPTIONS->Multi_Grid =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Multi_Grid");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((USER_OPTIONS->Multi_Params =+       (double **) calloc (USER_OPTIONS->Multi_Number,+                           sizeof (double *))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Multi_Params");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  for (multi_index = 0; multi_index < USER_OPTIONS->Multi_Number;+       ++multi_index) {+    if ((USER_OPTIONS->Multi_Params[multi_index] =+         (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+      strcpy (user_exit_msg,+              "initialize_parameters(): USER_OPTIONS->Multi_Params[multi_index]");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  }+#if ASA_TEST+  for (index = 0; index < *parameter_dimension; ++index) {+    USER_OPTIONS->Multi_Grid[index] = 0.05;+  }+  USER_OPTIONS->Multi_Specify = 0;+#endif+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index) {+    USER_OPTIONS->Multi_Grid[index] =+      (parameter_upper_bound[index] - parameter_lower_bound[index]) / 100.0;+  }+  USER_OPTIONS->Multi_Specify = 0;+#endif /* ASA_TEMPLATE */+#endif /* MULTI_MIN */+  USER_OPTIONS->Asa_Recursive_Level = 0;++#if MY_TEMPLATE                 /* MY_TEMPLATE_params */+  /* If not using RECUR_OPTIONS_FILE_DATA or data read from asa_opt,+     store the parameter ranges+     store the parameter types+     store the initial parameter values+     other changes needed for initialization */+#endif /* MY_TEMPLATE params */++  return (0);+}++#if COST_FILE+#else+/***********************************************************************+* double cost_function+*	This is the users cost function to optimize+*	(find the minimum).+*	cost_flag is set to TRUE if the parameter set+*	does not violates any constraints+*       parameter_lower_bound and parameter_upper_bound may be+*       adaptively changed during the search.+***********************************************************************/++#if HAVE_ANSI+double+cost_function (double *x,+               double *parameter_lower_bound,+               double *parameter_upper_bound,+               double *cost_tangents,+               double *cost_curvature,+               ALLOC_INT * parameter_dimension,+               int *parameter_int_real,+               int *cost_flag, int *exit_code, USER_DEFINES * USER_OPTIONS)+#else+double+cost_function (x,+               parameter_lower_bound,+               parameter_upper_bound,+               cost_tangents,+               cost_curvature,+               parameter_dimension,+               parameter_int_real, cost_flag, exit_code, USER_OPTIONS)+     double *x;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+     int *cost_flag;+     int *exit_code;+     USER_DEFINES *USER_OPTIONS;+#endif+{++#if ASA_TEST                    /* ASA test problem */+  /* Objective function from+   * %A A. Corana+   * %A M. Marchesi+   * %A C. Martini+   * %A S. Ridella+   * %T Minimizing multimodal functions of continuous variables+   *    with the "simulated annealing" algorithm+   * %J ACM Trans. Mathl. Software+   * %V 13+   * %N 3+   * %P 262-279+   * %D 1987+   *+   * This function, when used with ASA_TEST_POINT set to TRUE, contains+   * 1.0E20 local minima.  When *parameter_dimension is equal to 4, visiting+   * each minimum for a millisecond would take about the present age of the+   * universe to visit all these minima. */++  /* defines for the test problem, which assume *parameter_dimension+     is a multiple of 4.  If this is set to a large number, you+     likely should set Curvature_0 to TRUE. */+  double q_n, d_i, s_i, t_i, z_i, c_r;+  int k_i;+#if ASA_TEST_POINT+  ALLOC_INT k_flag;+#endif+  ALLOC_INT i, j;+#if SELF_OPTIMIZE+#else+  static LONG_INT funevals = 0;+#endif+#if ASA_TEMPLATE_SAVE+  static int read_test = 0;+  FILE *ptr_read_test;+#endif++#if MY_TEMPLATE                 /* MY_TEMPLATE_diminishing_ranges */+  /* insert code to automate changing ranges of parameters */+#endif+#if ASA_TEMPLATE                /* example of diminishing ranges */+  if (USER_OPTIONS->Locate_Cost == 12 && *(USER_OPTIONS->Best_Cost) < 1.0) {+    fprintf (ptr_out, "best_cost = %g\n", *(USER_OPTIONS->Best_Cost));+    for (i = 0; i < *parameter_dimension; ++i) {+      parameter_lower_bound[i] = USER_OPTIONS->Best_Parameters[i]+        - 0.5 * fabs (parameter_lower_bound[i]+                      - USER_OPTIONS->Best_Parameters[i]);+      parameter_upper_bound[i] = USER_OPTIONS->Best_Parameters[i]+        + 0.5 * fabs (parameter_upper_bound[i]+                      - USER_OPTIONS->Best_Parameters[i]);+      parameter_lower_bound[i] = MIN (parameter_lower_bound[i],+                                      USER_OPTIONS->Best_Parameters[i] -+                                      0.01);+      parameter_upper_bound[i] =+        MAX (parameter_upper_bound[i],+             USER_OPTIONS->Best_Parameters[i] + 0.01);+    }+  }+#endif /* ASA_TEMPLATE */++  /* a_i = parameter_upper_bound[i] */+  s_i = 0.2;+  t_i = 0.05;+  c_r = 0.15;++#if ASA_TEST_POINT+  k_flag = 0;+  for (i = 0; i < *parameter_dimension; ++i) {+    if (fabs (parameter_upper_bound[i] - parameter_lower_bound[i]) <+        (double) EPS_DOUBLE)+      continue;++    if (x[i] > 0.0) {+      k_i = (int) (x[i] / s_i + 0.5);+    } else if (x[i] < 0.0) {+      k_i = (int) (x[i] / s_i - 0.5);+    } else {+      k_i = 0;+    }+    if (k_i == 0)+      ++k_flag;+  }+#endif /* ASA_TEST_POINT */++  q_n = 0.0;+  for (i = 0; i < *parameter_dimension; ++i) {+    if (fabs (parameter_upper_bound[i] - parameter_lower_bound[i]) <+        (double) EPS_DOUBLE)+      continue;++    j = i % 4;+    switch (j) {+    case 0:+      d_i = 1.0;+      break;+    case 1:+      d_i = 1000.0;+      break;+    case 2:+      d_i = 10.0;+      break;+    default:+      d_i = 100.0;+    }+    if (x[i] > 0.0) {+      k_i = (int) (x[i] / s_i + 0.5);+    } else if (x[i] < 0.0) {+      k_i = (int) (x[i] / s_i - 0.5);+    } else {+      k_i = 0;+    }++#if ASA_TEST_POINT+    if (fabs (k_i * s_i - x[i]) < t_i && k_flag != *parameter_dimension)+#else+    if (fabs (k_i * s_i - x[i]) < t_i)+#endif+    {+      if (k_i < 0) {+        z_i = k_i * s_i + t_i;+      } else if (k_i > 0) {+        z_i = k_i * s_i - t_i;+      } else {+        z_i = 0.0;+      }+      q_n += c_r * d_i * z_i * z_i;+    } else {+      q_n += d_i * x[i] * x[i];+    }+  }+  funevals = funevals + 1;++#if ASA_TEMPLATE_SAVE+  /* cause a crash */+  if ((ptr_read_test = fopen ("asa_save", "r")) == NULL) {+    read_test = 1;+    fclose (ptr_read_test);+  } else {+    fclose (ptr_read_test);+  }+  /* will need a few hundred if testing ASA_PARALLEL to get an asa_save */+  if (funevals == 50 && read_test == 1) {+    fprintf (ptr_out, "\n\n*** intended crash to test ASA_SAVE *** \n\n");+    fflush (ptr_out);+#if INCL_STDOUT+    printf ("\n\n*** intended crash to test ASA_SAVE *** \n\n");+#endif /* INCL_STDOUT */+    exit (2);+  }+#endif++  *cost_flag = TRUE;++#if SELF_OPTIMIZE+#else+#if TIME_CALC+  /* print the time every PRINT_FREQUENCY evaluations */+  if ((PRINT_FREQUENCY > 0) && ((funevals % PRINT_FREQUENCY) == 0)) {+    fprintf (ptr_out, "funevals = %ld  ", funevals);+#if INCL_STDOUT+    print_time ("", ptr_out);+#endif /* INCL_STDOUT */+  }+#endif+#endif++#if ASA_TEMPLATE_SAMPLE+  USER_OPTIONS->Cost_Acceptance_Flag = TRUE;+  if (USER_OPTIONS->User_Acceptance_Flag == FALSE && *cost_flag == TRUE)+    USER_OPTIONS->Acceptance_Test (q_n,+                                   parameter_lower_bound,+                                   parameter_upper_bound,+                                   *parameter_dimension, USER_OPTIONS);+#endif /* ASA_TEMPLATE_SAMPLE */++  return (q_n);+#endif /* ASA_TEST */+#if ASA_TEMPLATE_SAMPLE++  int n;+  double cost;++  if (*cost_flag == FALSE) {+    for (n = 0; n < *parameter_dimension; ++n)+      if (fabs (parameter_upper_bound[n] - parameter_lower_bound[n]) <+          (double) EPS_DOUBLE)+        continue;++    cost_tangents[n] = 2.0 * x[n];+  }++  cost = 0.0;+  for (n = 0; n < *parameter_dimension; ++n) {+    if (fabs (parameter_upper_bound[n] - parameter_lower_bound[n]) <+        (double) EPS_DOUBLE)+      continue;++    cost += (x[n] * x[n]);+  }++  *cost_flag = TRUE;++  USER_OPTIONS->Cost_Acceptance_Flag = TRUE;+  if (USER_OPTIONS->User_Acceptance_Flag == FALSE && *cost_flag == TRUE)+    USER_OPTIONS->Acceptance_Test (cost,+                                   parameter_lower_bound,+                                   parameter_upper_bound,+                                   *parameter_dimension, USER_OPTIONS);++  return (cost);+#endif /* ASA_TEMPLATE_SAMPLE */+#if MY_TEMPLATE                 /* MY_TEMPLATE_cost */+   return USER_OPTIONS->Asa_Data_Ptr(x,cost_flag); +  /* Use the parameter values x[] and define your cost_function.+     The {} brackets around this function are already in place. */+#endif /* MY_TEMPLATE cost */+}+#endif /* COST_FILE */++  /* Here is a good random number generator */++#define MULT ((LONG_INT) 25173)+#define MOD ((LONG_INT) 65536)+#define INCR ((LONG_INT) 13849)+#define FMOD ((double) 65536.0)+++/***********************************************************************+* double myrand - returns random number between 0 and 1+*	This routine returns the random number generator between 0 and 1+***********************************************************************/++static double+myrand (LONG_INT * rand_seed)+  /* returns random number in {0,1} */+{+#if TRUE                        /* (change to FALSE for alternative RNG) */+  *rand_seed = (LONG_INT) ((MULT * (*rand_seed) + INCR) % MOD);+  return ((double) (*rand_seed) / FMOD);+#else+  /* See "Random Number Generators: Good Ones Are Hard To Find,"+     Park & Miller, CACM 31 (10) (October 1988) pp. 1192-1201.+     ***********************************************************+     THIS IMPLEMENTATION REQUIRES AT LEAST 32 BIT INTEGERS+     *********************************************************** */+#define _A_MULTIPLIER  16807L+#define _M_MODULUS     2147483647L      /* (2**31)-1 */+#define _Q_QUOTIENT    127773L  /* 2147483647 / 16807 */+#define _R_REMAINDER   2836L    /* 2147483647 % 16807 */+  long lo;+  long hi;+  long test;++  hi = *rand_seed / _Q_QUOTIENT;+  lo = *rand_seed % _Q_QUOTIENT;+  test = _A_MULTIPLIER * lo - _R_REMAINDER * hi;+  if (test > 0) {+    *rand_seed = test;+  } else {+    *rand_seed = test + _M_MODULUS;+  }+  return ((double) *rand_seed / _M_MODULUS);+#endif /* alternative RNG */+}++/***********************************************************************+* double randflt+***********************************************************************/++static double+randflt (LONG_INT * rand_seed)+{+  return (resettable_randflt (rand_seed, 0));+}++/***********************************************************************+* double resettable_randflt+***********************************************************************/++static double+resettable_randflt (LONG_INT * rand_seed, int reset)+  /* shuffles random numbers in random_array[SHUFFLE] array */+{++  /* This RNG is a modified algorithm of that presented in+   * %A K. Binder+   * %A D. Stauffer+   * %T A simple introduction to Monte Carlo simulations and some+   *    specialized topics+   * %B Applications of the Monte Carlo Method in statistical physics+   * %E K. Binder+   * %I Springer-Verlag+   * %C Berlin+   * %D 1985+   * %P 1-36+   * where it is stated that such algorithms have been found to be+   * quite satisfactory in many statistical physics applications. */++  double rranf;+  unsigned kranf;+  int n;+  static int initial_flag = 0;+  LONG_INT initial_seed;+  static double random_array[SHUFFLE];  /* random variables */++  if (*rand_seed < 0)+    *rand_seed = -*rand_seed;++  if ((initial_flag == 0) || reset) {+    initial_seed = *rand_seed;++    for (n = 0; n < SHUFFLE; ++n)+      random_array[n] = myrand (&initial_seed);++    initial_flag = 1;++    for (n = 0; n < 1000; ++n)  /* warm up random generator */+      rranf = randflt (&initial_seed);++    rranf = randflt (rand_seed);++    return (rranf);+  }++  kranf = (unsigned) (myrand (rand_seed) * SHUFFLE) % SHUFFLE;+  rranf = *(random_array + kranf);+  *(random_array + kranf) = myrand (rand_seed);++  return (rranf);+}++#if USER_COST_SCHEDULE+#if HAVE_ANSI+double+user_cost_schedule (double test_temperature, USER_DEFINES * USER_OPTIONS)+#else+double+user_cost_schedule (test_temperature, USER_OPTIONS)+     double test_temperature;+     USER_DEFINES *USER_OPTIONS;+#endif /* HAVE_ANSI */+{+  double x;++#if ASA_TEMPLATE_SAMPLE+  x = F_POW (test_temperature, 0.15);+#endif+#if ASA_TEMPLATE+  x = test_temperature;+#endif++  return (x);+}+#endif /* USER_COST_SCHEDULE */++#if USER_ACCEPTANCE_TEST+#if HAVE_ANSI+void+user_acceptance_test (double current_cost,+                      double *parameter_lower_bound,+                      double *parameter_upper_bound,+                      ALLOC_INT * parameter_dimension,+                      USER_DEFINES * USER_OPTIONS)+#else+void+user_acceptance_test (current_cost, parameter_lower_bound,+                      parameter_upper_bound, parameter_dimension,+                      USER_OPTIONS)+     double current_cost;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     ALLOC_INT *parameter_dimension;+     USER_DEFINES *USER_OPTIONS;+#endif /* HAVE_ANSI */+{+  double uniform_test, curr_cost_temp;+#if USER_ACCEPT_ASYMP_EXP+  double x, q, delta_cost;+#endif++#if ASA_TEMPLATE                /* ASA cost index */+  /* Calculate the current ASA cost index.  This could be useful+     to define a new schedule for the cost temperature, beyond+     simple changes that can be made using USER_COST_SCHEDULE. */++  int index;+  double k_temperature, quench, y;+  double xparameter_dimension;++#if QUENCH_COST+  quench = USER_OPTIONS->User_Quench_Cost_Scale[0];+#else+  quench = 1.0;+#endif /* QUENCH_COST */+  xparameter_dimension = (double) *parameter_dimension;+  for (index = 0; index < *parameter_dimension; ++index)+    if (fabs (parameter_upper_bound[index] - parameter_lower_bound[index]) <+        (double) EPS_DOUBLE)+      *xparameter_dimension -= 1.0;++  y = -F_LOG (USER_OPTIONS->Cost_Temp_Curr+              / USER_OPTIONS->Cost_Temp_Init) / USER_OPTIONS->Cost_Temp_Scale;++  k_temperature = F_POW (y, xparameter_dimension / quench);+#endif /* ASA cost index */++  uniform_test = randflt (USER_OPTIONS->Random_Seed);+  curr_cost_temp = USER_OPTIONS->Cost_Temp_Curr;++#if ASA_TEMPLATE+#if USER_COST_SCHEDULE+  curr_cost_temp =+    (USER_OPTIONS->Cost_Schedule (USER_OPTIONS->Cost_Temp_Curr,+                                  USER_OPTIONS) + (double) EPS_DOUBLE);+#else+  curr_cost_temp = USER_OPTIONS->Cost_Temp_Curr;+#endif+#endif /* ASA_TEMPLATE */++  /* You must add in your own test here.  If USER_ACCEPT_ASYMP_EXP+     also is TRUE here, then you can use the default+     Asymp_Exp_Param=1 to replicate the code in asa.c. */++#if USER_ACCEPT_ASYMP_EXP+#if USER_COST_SCHEDULE+  curr_cost_temp =+    (USER_OPTIONS->Cost_Schedule (USER_OPTIONS->Cost_Temp_Curr,+                                  USER_OPTIONS) + (double) EPS_DOUBLE);+#endif++  delta_cost = (current_cost - *(USER_OPTIONS->Last_Cost))+    / (curr_cost_temp + (double) EPS_DOUBLE);++  /* The following asymptotic approximation to the exponential+   * function, "Tsallis statistics," was proposed in+   * %A T.J.P. Penna+   * %T Traveling salesman problem and Tsallis statistics+   * %J Phys. Rev. E+   * %V 50+   * %N 6+   * %P R1-R3+   * %D 1994+   * While the use of the TSP for a test case is of dubious value (since+   * there are many special algorithms for this problem), the use of this+   * function is another example of how to control the rate of annealing+   * of the acceptance criteria.  E.g., if you require a more moderate+   * acceptance test, then negative q may be helpful. */++  q = USER_OPTIONS->Asymp_Exp_Param;+  if (fabs (1.0 - q) < (double) EPS_DOUBLE)+    x = MIN (1.0, (F_EXP (-delta_cost)));       /* Boltzmann test */+  else if ((1.0 - (1.0 - q) * delta_cost) < (double) EPS_DOUBLE)+    x = MIN (1.0, (F_EXP (-delta_cost)));       /* Boltzmann test */+  else+    x = MIN (1.0, F_POW ((1.0 - (1.0 - q) * delta_cost), (1.0 / (1.0 - q))));++  USER_OPTIONS->Prob_Bias = x;+  if (x >= uniform_test)+    USER_OPTIONS->User_Acceptance_Flag = TRUE;+  else+    USER_OPTIONS->User_Acceptance_Flag = FALSE;++#endif /* USER_ACCEPT_ASYMP_EXP */+}+#endif /* USER_ACCEPTANCE_TEST */++#if USER_GENERATING_FUNCTION+#if HAVE_ANSI+double+user_generating_distrib (LONG_INT * seed,+                         ALLOC_INT * parameter_dimension,+                         ALLOC_INT index_v,+                         double temperature_v,+                         double init_param_temp_v,+                         double temp_scale_params_v,+                         double parameter_v,+                         double parameter_range_v,+                         double *last_saved_parameter,+                         USER_DEFINES * USER_OPTIONS)+#else+double+user_generating_distrib (seed,+                         parameter_dimension,+                         index_v,+                         temperature_v,+                         init_param_temp_v,+                         temp_scale_params_v,+                         parameter_v,+                         parameter_range_v,+                         last_saved_parameter, USER_OPTIONS)+     LONG_INT *seed;+     ALLOC_INT *parameter_dimension;+     ALLOC_INT index_v;+     double temperature_v;+     double init_param_temp_v;+     double temp_scale_params_v;+     double parameter_v;+     double parameter_range_v;+     double *last_saved_parameter;+     USER_DEFINES *USER_OPTIONS;+#endif+{+#if ASA_TEMPLATE+  double x, y, z;++  /* This is the ASA distribution.  A slower temperature schedule can be+     obtained here, e.g., temperature_v = pow(temperature_v, 0.5); */++  x = randflt (seed);+  y = x < 0.5 ? -1.0 : 1.0;+  z = y * temperature_v * (F_POW ((1.0 + 1.0 / temperature_v),+                                  fabs (2.0 * x - 1.0)) - 1.0);++  x = parameter_v + z * parameter_range_v;++  return (x);+#endif /* ASA_TEMPLATE */+}+#endif /* USER_GENERATING_FUNCTION */++#if USER_REANNEAL_COST+#if HAVE_ANSI+int+user_reanneal_cost (double *cost_best,+                    double *cost_last,+                    double *initial_cost_temperature,+                    double *current_cost_temperature,+                    USER_DEFINES * USER_OPTIONS)+#else+int+user_reanneal_cost (cost_best,+                    cost_last,+                    initial_cost_temperature,+                    current_cost_temperature, USER_OPTIONS)+     double *cost_best;+     double *cost_last;+     double *initial_cost_temperature;+     double *current_cost_temperature;+     USER_DEFINES *USER_OPTIONS;+#endif /* HAVE_ANSI */+{+  int cost_test;+  double tmp_dbl;++#if ASA_TEMPLATE+  static int first_time = 1;+  static double save_last[3];+  double average_cost_last;++  if (first_time == 1) {+    first_time = 0;+    save_last[0] = save_last[1] = save_last[2] = *cost_last;+  }++  save_last[2] = save_last[1];+  save_last[1] = save_last[0];+  save_last[0] = *cost_last;+  average_cost_last =+    fabs ((save_last[0] + save_last[1] + save_last[2]) / 3.0);++  tmp_dbl = MAX (fabs (*cost_best), average_cost_last);+  tmp_dbl = MAX ((double) EPS_DOUBLE, tmp_dbl);+  *initial_cost_temperature = MIN (*initial_cost_temperature, tmp_dbl);++  /* This test can be useful if your cost function goes from a positive+     to a negative value, and you do not want to get get stuck in a local+     minima around zero due to the default in reanneal().  Pick any+     number instead of 0.0001 */+  tmp_dbl = MIN (fabs (*cost_last), fabs (*cost_best));+  if (tmp_dbl < 0.0001)+    cost_test = FALSE;+  else+    cost_test = TRUE;+#endif /* ASA_TEMPLATE */++  tmp_dbl = MAX (fabs (cost_last), fabs (cost_best));+  tmp_dbl = MAX ((double) EPS_DOUBLE, tmp_dbl);+  *initial_cost_temperature = MIN (*initial_cost_temperature, tmp_dbl);++  *current_cost_temperature =+    MAX (fabs (cost_last - cost_best), *current_cost_temperature);+  *current_cost_temperature =+    MAX ((double) EPS_DOUBLE, *current_cost_temperature);+  *current_cost_temperature =+    MIN (*current_cost_temperature, *initial_cost_temperature);++  cost_test = TRUE;++  return (cost_test);+}+#endif /* USER_REANNEAL_COST */++#if USER_REANNEAL_PARAMETERS+#if HAVE_ANSI+double+user_reanneal_params (double current_temp,+                      double tangent,+                      double max_tangent, USER_DEFINES * USER_OPTIONS)+#else+double+user_reanneal_params (current_temp, tangent, max_tangent, USER_OPTIONS)+     double current_temp;+     double tangent;+     double max_tangent;+     USER_DEFINES *USER_OPTIONS;+#endif /* HAVE_ANSI */+{+#if ASA_TEMPLATE+  double x;++  x = current_temp * (max_tangent / tangent);++  return (x);+#endif+}+#endif /* USER_REANNEAL_PARAMETERS */++#if SELF_OPTIMIZE++/***********************************************************************+* main+*	This is a sample calling program to self-optimize ASA+***********************************************************************/+#if HAVE_ANSI++#if ASA_LIB+int+asa_main (+#if ASA_TEMPLATE_LIB+           double *main_recur_cost_value,+           double *main_recur_cost_parameters, int *main_recur_exit_code+#endif+  )+#else /* ASA_LIB */+int+main (int argc, char **argv)+#endif                          /* ASA_LIB */+#else /* HAVE_ANSI */++#if ASA_LIB+int+asa_main (+#if ASA_TEMPLATE_LIB+           main_recur_cost_value,+           main_recur_cost_parameters, main_recur_exit_code+#endif+  )+#if ASA_TEMPLATE_LIB+     double *main_recur_cost_value;+     double *main_recur_cost_parameters;+     int *main_recur_exit_code;+#endif++#else /* ASA_LIB */+int+main (argc, argv)+     int argc;+     char **argv;+#endif /* ASA_LIB */++#endif /* HAVE_ANSI */+{++  /* seed for random number generator */+  LONG_INT *recur_rand_seed;++#if RECUR_OPTIONS_FILE+  FILE *recur_ptr_options;+  char read_option[80];+  char read_if[4], read_FALSE[6], read_comm1[3], read_ASA_SAVE[9],+    read_comm2[3];+  int read_int;+#if INT_LONG+  LONG_INT read_long;+#endif+  double read_double;+#endif++  int *recur_exit_code;+#if MULTI_MIN+  int multi_index;+  ALLOC_INT n_param;+#endif++  double *recur_parameter_lower_bound, *recur_parameter_upper_bound;+  double *recur_cost_parameters, *recur_cost_tangents, *recur_cost_curvature;+  double recur_cost_value;++  ALLOC_INT *recur_parameter_dimension;+  int *recur_parameter_int_real;+  int *recur_cost_flag;+  int recur_initialize_parameters_value;+  ALLOC_INT recur_v;+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_main_decl */+  /* add some declarations if required */+#endif++  USER_DEFINES *RECUR_USER_OPTIONS;++  if ((recur_parameter_dimension =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_parameter_dimension");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((recur_exit_code = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_exit_code");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((recur_cost_flag = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_cost_flag");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((RECUR_USER_OPTIONS =+       (USER_DEFINES *) calloc (1, sizeof (USER_DEFINES))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): RECUR_USER_OPTIONS");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if RECUR_OPTIONS_FILE+  recur_ptr_options = fopen ("asa_opt_recur", "r");++  fscanf (recur_ptr_options, "%s%s%s%s%s",+          read_if, read_FALSE, read_comm1, read_ASA_SAVE, read_comm2);+  if (strcmp (read_if, "#if") || strcmp (read_FALSE, "FALSE") ||+      strcmp (read_comm1, "/*") || strcmp (read_ASA_SAVE, "ASA_SAVE") ||+      strcmp (read_comm2, "*/")) {+    fprintf (ptr_out, "\n\n*** not asa_opt_recur for this version *** \n\n");+    fflush (ptr_out);+#if INCL_STDOUT+    printf ("\n\n*** EXIT not asa_opt_recur for this version *** \n\n");+#endif /* INCL_STDOUT */+    return (-6);+  }+#if INT_LONG+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%ld", &read_long);+  RECUR_USER_OPTIONS->Limit_Acceptances = read_long;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%ld", &read_long);+  RECUR_USER_OPTIONS->Limit_Generated = read_long;+#else+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Limit_Acceptances = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Limit_Generated = read_int;+#endif+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Limit_Invalid_Generated_States = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Accepted_To_Generated_Ratio = read_double;++  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Cost_Precision = read_double;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Maximum_Cost_Repeat = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Number_Cost_Samples = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Temperature_Ratio_Scale = read_double;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Cost_Parameter_Scale_Ratio = read_double;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Temperature_Anneal_Scale = read_double;++  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Include_Integer_Parameters = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->User_Initial_Parameters = read_int;+#if INT_ALLOC+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Sequential_Parameters = read_int;+#else+#if INT_LONG+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%ld", &read_long);+  RECUR_USER_OPTIONS->Sequential_Parameters = read_long;+#else+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Sequential_Parameters = read_int;+#endif+#endif+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Initial_Parameter_Temperature = read_double;++  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Acceptance_Frequency_Modulus = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Generated_Frequency_Modulus = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Reanneal_Cost = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Reanneal_Parameters = read_int;++  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Delta_X = read_double;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->User_Tangents = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Curvature_0 = read_int;++#else /* RECUR_OPTIONS_FILE */+  RECUR_USER_OPTIONS->Limit_Acceptances = 100;+  RECUR_USER_OPTIONS->Limit_Generated = 1000;+  RECUR_USER_OPTIONS->Limit_Invalid_Generated_States = 1000;+  RECUR_USER_OPTIONS->Accepted_To_Generated_Ratio = 1.0E-4;++  RECUR_USER_OPTIONS->Cost_Precision = 1.0E-18;+  RECUR_USER_OPTIONS->Maximum_Cost_Repeat = 2;+  RECUR_USER_OPTIONS->Number_Cost_Samples = 2;+  RECUR_USER_OPTIONS->Temperature_Ratio_Scale = 1.0E-5;+  RECUR_USER_OPTIONS->Cost_Parameter_Scale_Ratio = 1.0;+  RECUR_USER_OPTIONS->Temperature_Anneal_Scale = 100.0;++  RECUR_USER_OPTIONS->Include_Integer_Parameters = FALSE;+  RECUR_USER_OPTIONS->User_Initial_Parameters = FALSE;+  RECUR_USER_OPTIONS->Sequential_Parameters = -1;+  RECUR_USER_OPTIONS->Initial_Parameter_Temperature = 1.0;++  RECUR_USER_OPTIONS->Acceptance_Frequency_Modulus = 15;+  RECUR_USER_OPTIONS->Generated_Frequency_Modulus = 10000;+  RECUR_USER_OPTIONS->Reanneal_Cost = FALSE;+  RECUR_USER_OPTIONS->Reanneal_Parameters = FALSE;++  RECUR_USER_OPTIONS->Delta_X = 1.0E-6;+  RECUR_USER_OPTIONS->User_Tangents = FALSE;+  RECUR_USER_OPTIONS->Curvature_0 = TRUE;++#endif /* RECUR_OPTIONS_FILE */++  /* the number of parameters for the recur_cost_function */+#if RECUR_OPTIONS_FILE_DATA+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%s", read_option);++#if INT_ALLOC+  fscanf (recur_ptr_options, "%d", &read_int);+  *recur_parameter_dimension = read_int;+#else+#if INT_LONG+  fscanf (recur_ptr_options, "%ld", &read_long);+  *recur_parameter_dimension = read_long;+#else+  fscanf (recur_ptr_options, "%d", &read_int);+  *recur_parameter_dimension = read_int;+#endif+#endif++#else /* RECUR_OPTIONS_FILE_DATA */+#if ASA_TEMPLATE_SELFOPT+  *recur_parameter_dimension = 2;+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_dim */+  /* If not using RECUR_OPTIONS_FILE_DATA or data read from recur_asa_opt,+     insert the number of parameters for the recur_cost_function */+#endif /* MY_TEMPLATE recur_dim */+#endif /* RECUR_OPTIONS_FILE_DATA */+  if ((recur_parameter_lower_bound =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_parameter_lower_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((recur_parameter_upper_bound =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_parameter_upper_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((recur_cost_parameters =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_cost_parameters");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((recur_parameter_int_real =+       (int *) calloc (*recur_parameter_dimension, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_parameter_int_real");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((recur_cost_tangents =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_cost_tangents");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if (RECUR_USER_OPTIONS->Curvature_0 == FALSE+      || RECUR_USER_OPTIONS->Curvature_0 == -1) {++    if ((recur_cost_curvature =+         (double *) calloc ((*recur_parameter_dimension)+                            * (*recur_parameter_dimension),+                            sizeof (double))) == NULL) {+      strcpy (user_exit_msg, "main()/asa_main(): recur_cost_curvature");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  } else {+    recur_cost_curvature = (double *) NULL;+  }++#if ASA_TEMPLATE_SELFOPT+  /* Set memory to that required for use. */+  RECUR_USER_OPTIONS->Asa_Data_Dim_Dbl = 1;+  if ((RECUR_USER_OPTIONS->Asa_Data_Dbl =+       (double *) calloc (RECUR_USER_OPTIONS->Asa_Data_Dim_Dbl,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "main()/asa_main(): RECUR_USER_OPTIONS->Asa_Data_Dbl");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* Use Asa_Data[0] as flag, e.g., if used with SELF_OPTIMIZE. */+  RECUR_USER_OPTIONS->Asa_Data_Dbl[0] = 0;+#endif /* ASA_TEMPLATE_SELFOPT */++#if OPTIONAL_DATA_PTR+#if ASA_TEMPLATE+  RECUR_USER_OPTIONS->Asa_Data_Dim_Ptr = 1;+  if ((RECUR_USER_OPTIONS->Asa_Data_Ptr =+       (OPTIONAL_PTR_TYPE *) calloc (RECUR_USER_OPTIONS->Asa_Data_Dim_Ptr,+                                     sizeof (OPTIONAL_PTR_TYPE))) == NULL) {+    strcpy (user_exit_msg,+            "main()/asa_main(): RECUR_USER_OPTIONS->Asa_Data_Ptr");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* ASA_TEMPLATE */+#endif /* OPTIONAL_DATA_PTR */++#if ASA_SAVE+  /* Such data could be saved in a user_save file, but for+     convenience here everything is saved in asa_save. */+  RECUR_USER_OPTIONS->Random_Array_Dim = SHUFFLE;+  RECUR_USER_OPTIONS->Random_Array = random_array;+#endif /* ASA_SAVE */++  /* open the output file */+#if ASA_SAVE+  if (!strcmp (USER_OUT, "STDOUT")) {+#if INCL_STDOUT+    ptr_out = stdout;+#endif /* INCL_STDOUT */+  } else {+    ptr_out = fopen (USER_OUT, "a");+  }+#else+  if (!strcmp (USER_OUT, "STDOUT")) {+#if INCL_STDOUT+    ptr_out = stdout;+#endif /* INCL_STDOUT */+  } else {+    ptr_out = fopen (USER_OUT, "w");+  }+#endif+//  fprintf (ptr_out, "%s\n\n", USER_ID);++  fflush (ptr_out);++  if ((recur_rand_seed =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_rand_seed");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  /* first value of *recur_rand_seed */+#if ASA_LIB+  *recur_rand_seed = (asa_rand_seed ? *asa_rand_seed : (LONG_INT) 696969);+#else+  *recur_rand_seed = 696969;+#endif++  randflt (recur_rand_seed);++#if USER_COST_SCHEDULE+  RECUR_USER_OPTIONS->Cost_Schedule = recur_user_cost_schedule;+#endif+#if USER_ACCEPTANCE_TEST+  RECUR_USER_OPTIONS->Acceptance_Test = recur_user_acceptance_test;+#endif+#if USER_ACCEPT_ASYMP_EXP+  RECUR_USER_OPTIONS->Asymp_Exp_Param = 1.0;+#endif+#if USER_GENERATING_FUNCTION+  RECUR_USER_OPTIONS->Generating_Distrib = recur_user_generating_distrib;+#endif+#if USER_REANNEAL_COST+  RECUR_USER_OPTIONS->Reanneal_Cost_Function = recur_user_reanneal_cost;+#endif+#if USER_REANNEAL_PARAMETERS+  RECUR_USER_OPTIONS->Reanneal_Params_Function = recur_user_reanneal_params;+#endif++#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_pre_initialize */+  /* last changes before entering recur_initialize_parameters() */+#endif++  /* initialize the users parameters, allocating space, etc.+     Note that the default is to have asa generate the initial+     recur_cost_parameters that satisfy the user's constraints. */++  recur_initialize_parameters_value =+    recur_initialize_parameters (recur_cost_parameters,+                                 recur_parameter_lower_bound,+                                 recur_parameter_upper_bound,+                                 recur_cost_tangents,+                                 recur_cost_curvature,+                                 recur_parameter_dimension,+                                 recur_parameter_int_real,+#if RECUR_OPTIONS_FILE_DATA+                                 recur_ptr_options,+#endif+                                 RECUR_USER_OPTIONS);+#if RECUR_OPTIONS_FILE+  fclose (recur_ptr_options);+#endif+  if (recur_initialize_parameters_value == -2)+    return (recur_initialize_parameters_value);++#if USER_ASA_OUT+  if ((RECUR_USER_OPTIONS->Asa_Out_File =+       (char *) calloc (80, sizeof (char))) == NULL) {+    strcpy (user_exit_msg,+            "main()/asa_main(): RECUR_USER_OPTIONS->Asa_Out_File");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE_SELFOPT+  strcpy (RECUR_USER_OPTIONS->Asa_Out_File, "asa_sfop");+#endif+#endif++  recur_cost_value = asa (RECUR_USER_COST_FUNCTION,+                          randflt,+                          recur_rand_seed,+                          recur_cost_parameters,+                          recur_parameter_lower_bound,+                          recur_parameter_upper_bound,+                          recur_cost_tangents,+                          recur_cost_curvature,+                          recur_parameter_dimension,+                          recur_parameter_int_real,+                          recur_cost_flag,+                          recur_exit_code, RECUR_USER_OPTIONS);+  if (*recur_exit_code == -1) {+#if INCL_STDOUT+    printf ("\n\n*** error in calloc in ASA ***\n\n");+#endif /* INCL_STDOUT */+    fprintf (ptr_out, "\n\n*** error in calloc in ASA ***\n\n");+    fflush (ptr_out);+    return (-1);+  }+#if MULTI_MIN+  fprintf (ptr_out, "Multi_Specify = %d\n",+           RECUR_USER_OPTIONS->Multi_Specify);+  for (n_param = 0; n_param < *recur_parameter_dimension; ++n_param) {+    fprintf (ptr_out,+#if INT_ALLOC+             "Multi_Grid[%d] = %12.7g\n",+#else+#if INT_LONG+             "Multi_Grid[%ld] = %12.7g\n",+#else+             "Multi_Grid[%d] = %12.7g\n",+#endif+#endif+             n_param, RECUR_USER_OPTIONS->Multi_Grid[n_param]);+  }+  fprintf (ptr_out, "\n");+  for (multi_index = 0; multi_index < RECUR_USER_OPTIONS->Multi_Number;+       ++multi_index) {+    fprintf (ptr_out, "\n");+    fprintf (ptr_out, "Multi_Cost[%d] = %12.7g\n",+             multi_index, RECUR_USER_OPTIONS->Multi_Cost[multi_index]);+    for (n_param = 0; n_param < *recur_parameter_dimension; ++n_param) {+      fprintf (ptr_out,+#if INT_ALLOC+               "Multi_Params[%d][%d] = %12.7g\n",+#else+#if INT_LONG+               "Multi_Params[%d][%ld] = %12.7g\n",+#else+               "Multi_Params[%d][%d] = %12.7g\n",+#endif+#endif+               multi_index, n_param,+               RECUR_USER_OPTIONS->Multi_Params[multi_index][n_param]);+    }+  }+  fprintf (ptr_out, "\n");+  fflush (ptr_out);+#endif /* MULTI_MIN */++#if FITLOC+  /* Fit_Local and Penalty may be set adaptively */+  RECUR_USER_OPTIONS->Penalty = 1000;+  RECUR_USER_OPTIONS->Fit_Local = 0;+  RECUR_USER_OPTIONS->Iter_Max = 500;+  if (RECUR_USER_OPTIONS->Fit_Local >= 1) {+    recur_cost_value = fitloc (RECUR_USER_COST_FUNCTION,+                               recur_cost_parameters,+                               recur_parameter_lower_bound,+                               recur_parameter_upper_bound,+                               recur_cost_tangents,+                               recur_cost_curvature,+                               recur_parameter_dimension,+                               recur_parameter_int_real,+                               recur_cost_flag,+                               recur_exit_code, RECUR_USER_OPTIONS, ptr_out);+  }+#endif /* FITLOC */++  fprintf (ptr_out, "\n\n recur_cost_value = %12.7g\n", recur_cost_value);+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_post_recur_asa */+#endif+#if ASA_TEMPLATE_LIB+  *main_recur_cost_value = recur_cost_value;+  for (recur_v = 0; recur_v < *recur_parameter_dimension; ++recur_v) {+    main_recur_cost_parameters[recur_v] = recur_cost_parameters[recur_v];+  }+  *main_recur_exit_code = *recur_exit_code;+#endif++  for (recur_v = 0; recur_v < *recur_parameter_dimension; ++recur_v)+#if INT_ALLOC+    fprintf (ptr_out, "recur_cost_parameters[%d] = %12.7g\n",+#else+#if INT_LONG+    fprintf (ptr_out, "recur_cost_parameters[%ld] = %12.7g\n",+#else+    fprintf (ptr_out, "recur_cost_parameters[%d] = %12.7g\n",+#endif+#endif+             recur_v, recur_cost_parameters[recur_v]);++  fprintf (ptr_out, "\n\n");+++  /* close all files */+  ptr_out != stdout && fclose (ptr_out);++#if OPTIONAL_DATA_DBL+  free (RECUR_USER_OPTIONS->Asa_Data_Dbl);+#endif+#if OPTIONAL_DATA_INT+  free (RECUR_USER_OPTIONS->Asa_Data_Int);+#endif+#if OPTIONAL_DATA_PTR+  free (RECUR_USER_OPTIONS->Asa_Data_Ptr);+#endif+#if USER_ASA_OUT+  free (RECUR_USER_OPTIONS->Asa_Out_File);+#endif+#if ASA_SAMPLE+  free (RECUR_USER_OPTIONS->Bias_Generated);+#endif+#if ASA_QUEUE+#if ASA_RESOLUTION+#else+  free (RECUR_USER_OPTIONS->Queue_Resolution);+#endif+#endif+#if ASA_RESOLUTION+  free (RECUR_USER_OPTIONS->Coarse_Resolution);+#endif+  if (RECUR_USER_OPTIONS->Curvature_0 == FALSE+      || RECUR_USER_OPTIONS->Curvature_0 == -1)+    free (recur_cost_curvature);+#if USER_INITIAL_PARAMETERS_TEMPS+  free (RECUR_USER_OPTIONS->User_Parameter_Temperature);+#endif+#if USER_INITIAL_COST_TEMP+  free (RECUR_USER_OPTIONS->User_Cost_Temperature);+#endif+#if DELTA_PARAMETERS+  free (RECUR_USER_OPTIONS->User_Delta_Parameter);+#endif+#if QUENCH_PARAMETERS+  free (RECUR_USER_OPTIONS->User_Quench_Param_Scale);+#endif+#if QUENCH_COST+  free (RECUR_USER_OPTIONS->User_Quench_Cost_Scale);+#endif+#if RATIO_TEMPERATURE_SCALES+  free (RECUR_USER_OPTIONS->User_Temperature_Ratio);+#endif+#if MULTI_MIN+  free (RECUR_USER_OPTIONS->Multi_Cost);+  free (RECUR_USER_OPTIONS->Multi_Grid);+  for (multi_index = 0; multi_index < RECUR_USER_OPTIONS->Multi_Number;+       ++multi_index) {+    free (RECUR_USER_OPTIONS->Multi_Params[multi_index]);+  }+  free (RECUR_USER_OPTIONS->Multi_Params);+#endif /* MULTI_MIN */+  free (RECUR_USER_OPTIONS);+  free (recur_parameter_dimension);+  free (recur_exit_code);+  free (recur_cost_flag);+  free (recur_parameter_lower_bound);+  free (recur_parameter_upper_bound);+  free (recur_cost_parameters);+  free (recur_parameter_int_real);+  free (recur_cost_tangents);+  free (recur_rand_seed);++  return (0);+  /* NOTREACHED */+}++/***********************************************************************+* recur_initialize_parameters+*	This depends on the users cost function to optimize (minimum).+*	The routine allocates storage needed for asa. The user should+*	define the number of parameters and their ranges,+*	and make sure the initial parameters are within+*	the minimum and maximum ranges. The array+*	recur_parameter_int_real should be REAL_TYPE (-1)+*       for real parameters,+***********************************************************************/+#if HAVE_ANSI+int+recur_initialize_parameters (double *recur_cost_parameters,+                             double *recur_parameter_lower_bound,+                             double *recur_parameter_upper_bound,+                             double *recur_cost_tangents,+                             double *recur_cost_curvature,+                             ALLOC_INT * recur_parameter_dimension,+                             int *recur_parameter_int_real,+#if RECUR_OPTIONS_FILE_DATA+                             FILE * recur_ptr_options,+#endif+                             USER_DEFINES * RECUR_USER_OPTIONS)+#else+int+recur_initialize_parameters (recur_cost_parameters,+                             recur_parameter_lower_bound,+                             recur_parameter_upper_bound,+                             recur_cost_tangents,+                             recur_cost_curvature,+                             recur_parameter_dimension,+                             recur_parameter_int_real,+#if RECUR_OPTIONS_FILE_DATA+                             recur_ptr_options,+#endif+                             RECUR_USER_OPTIONS)+     double *recur_parameter_lower_bound;+     double *recur_parameter_upper_bound;+     double *recur_cost_parameters;+     double *recur_cost_tangents;+     double *recur_cost_curvature;+     ALLOC_INT *recur_parameter_dimension;+     int *recur_parameter_int_real;+#if RECUR_OPTIONS_FILE_DATA+     FILE *recur_ptr_options;+#endif+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif+{+  ALLOC_INT index;+#if RECUR_OPTIONS_FILE_DATA+  char read_option[80];+  ALLOC_INT read_index;+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_init_decl */+  /* add some declarations if required */+#endif+#if MULTI_MIN+  int multi_index;+#endif++#if RECUR_OPTIONS_FILE_DATA+  fscanf (recur_ptr_options, "%s", read_option);++  for (index = 0; index < *recur_parameter_dimension; ++index) {+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_read_opt */+    /* put in some code as required to alter lines read from recur_asa_opt */+#endif+#if INT_ALLOC+    fscanf (recur_ptr_options, "%d", &read_index);+#else+#if INT_LONG+    fscanf (recur_ptr_options, "%ld", &read_index);+#else+    fscanf (recur_ptr_options, "%d", &read_index);+#endif+#endif+    fscanf (recur_ptr_options, "%lf%lf%lf%d",+            &(recur_parameter_lower_bound[read_index]),+            &(recur_parameter_upper_bound[read_index]),+            &(recur_cost_parameters[read_index]),+            &(recur_parameter_int_real[read_index]));+  }+#else /* RECUR_OPTIONS_FILE_DATA */+#if ASA_TEMPLATE_SELFOPT+  /*  NOTE:+     USER_OPTIONS->Temperature_Ratio_Scale = x[0];+     USER_OPTIONS->Cost_Parameter_Scale_Ratio = x[1];+   */++  /* store the initial parameter values */+  recur_cost_parameters[0] = 1.0E-5;+  recur_cost_parameters[1] = 1.0;++  recur_parameter_lower_bound[0] = 1.0E-6;+  recur_parameter_upper_bound[0] = 1.0E-4;++  recur_parameter_lower_bound[1] = 0.5;+  recur_parameter_upper_bound[1] = 3.0;++  /* store the initial parameter types */+  for (index = 0; index < *recur_parameter_dimension; ++index)+    recur_parameter_int_real[index] = REAL_TYPE;+#endif+#endif /* RECUR_OPTIONS_FILE_DATA */++#if USER_INITIAL_PARAMETERS_TEMPS+  if ((RECUR_USER_OPTIONS->User_Parameter_Temperature =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Parameter_Temperature");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Parameter_Temperature[index] = 1.0;+#endif /* USER_INITIAL_PARAMETERS_TEMPS */+#if USER_INITIAL_COST_TEMP+  if ((RECUR_USER_OPTIONS->User_Cost_Temperature =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Cost_Temperature");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  RECUR_USER_OPTIONS->User_Cost_Temperature[0] = 5.936648E+09;+#endif /* USER_INITIAL_COST_TEMP */+#if DELTA_PARAMETERS+  if ((RECUR_USER_OPTIONS->User_Delta_Parameter =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Delta_Parameter");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Delta_Parameter[index] = 0.001;+#endif /* DELTA_PARAMETERS */+#if QUENCH_PARAMETERS+  if ((RECUR_USER_OPTIONS->User_Quench_Param_Scale =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Quench_Param_Scale");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#endif /* QUENCH_PARAMETERS */+#if QUENCH_COST+  if ((RECUR_USER_OPTIONS->User_Quench_Cost_Scale =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Quench_Cost_Scale");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  RECUR_USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#endif /* QUENCH_COST */++  /* use asa_opt_recur to read in QUENCH RECUR_USER_OPTIONS */+#if RECUR_OPTIONS_FILE_DATA+#if QUENCH_COST+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf",+          &(RECUR_USER_OPTIONS->User_Quench_Cost_Scale[0]));++#if QUENCH_PARAMETERS+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%s", read_option);+  for (index = 0; index < *recur_parameter_dimension; ++index) {+#if INT_ALLOC+    fscanf (recur_ptr_options, "%d", &read_index);+#else+#if INT_LONG+    fscanf (recur_ptr_options, "%ld", &read_index);+#else+    fscanf (recur_ptr_options, "%d", &read_index);+#endif+#endif+    fscanf (recur_ptr_options, "%lf",+            &(RECUR_USER_OPTIONS->User_Quench_Param_Scale[read_index]));+  }+#endif /* QUENCH_PARAMETERS */+#endif /* QUENCH_COST */+#endif /* RECUR_OPTIONS_FILE_DATA */+#if RATIO_TEMPERATURE_SCALES+  if ((RECUR_USER_OPTIONS->User_Temperature_Ratio =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Temperature_Ratio");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Temperature_Ratio[index] = 1.0;+#endif+#endif /* RATIO_TEMPERATURE_SCALES */+  /* Defines the limit of collection of sampled data by asa */+#if ASA_SAMPLE+  /* create memory for Bias_Generated[] */+  if ((RECUR_USER_OPTIONS->Bias_Generated =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->Bias_Generated");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  RECUR_USER_OPTIONS->Limit_Weights = 1.0E-7;+#if QUENCH_COST+  RECUR_USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#if QUENCH_PARAMETERS+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#endif /* ASA_TEMPLATE */+#endif /* ASA_SAMPLE */++#if ASA_TEMPLATE+#if ASA_PARALLEL+  RECUR_USER_OPTIONS->Gener_Block = 1;+  RECUR_USER_OPTIONS->Gener_Block_Max = 1;+  RECUR_USER_OPTIONS->Gener_Mov_Avr = 1;+#endif+#endif+#if ASA_RESOLUTION+  if ((RECUR_USER_OPTIONS->Coarse_Resolution =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->Coarse_Resolution");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif+#if MULTI_MIN+#if ASA_TEMPLATE+  RECUR_USER_OPTIONS->Multi_Number = 2;+#endif+  if ((RECUR_USER_OPTIONS->Multi_Cost =+       (double *) calloc (RECUR_USER_OPTIONS->Multi_Number,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): RECUR_USER_OPTIONS->Multi_Cost");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((RECUR_USER_OPTIONS->Multi_Grid =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->Multi_Grid");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((RECUR_USER_OPTIONS->Multi_Params =+       (double **) calloc (RECUR_USER_OPTIONS->Multi_Number,+                           sizeof (double *))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): RECUR_USER_OPTIONS->Multi_Params");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  for (multi_index = 0; multi_index < RECUR_USER_OPTIONS->Multi_Number;+       ++multi_index) {+    if ((RECUR_USER_OPTIONS->Multi_Params[multi_index] =+         (double *) calloc (*recur_parameter_dimension,+                            sizeof (double))) == NULL) {+      strcpy (user_exit_msg,+              "recur_initialize_parameters(): RECUR_USER_OPTIONS->Multi_Params[multi_index]");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  }+#if ASA_TEST+  for (index = 0; index < *recur_parameter_dimension; ++index) {+    RECUR_USER_OPTIONS->Multi_Grid[index] = 0.05;+  }+  RECUR_USER_OPTIONS->Multi_Specify = 0;+#endif+#if ASA_TEMPLATE+  for (index = 0; index < *recur_parameter_dimension; ++index) {+    RECUR_USER_OPTIONS->Multi_Grid[index] =+      (recur_parameter_upper_bound[index] -+       recur_parameter_lower_bound[index]) / 100.0;+  }+  RECUR_USER_OPTIONS->Multi_Specify = 0;+#endif /* ASA_TEMPLATE */+#endif /* MULTI_MIN */+#if ASA_TEMPLATE_QUEUE+  RECUR_USER_OPTIONS->Queue_Size = 0;+#endif+#if ASA_QUEUE+#if ASA_RESOLUTION+  RECUR_USER_OPTIONS->Queue_Resolution =+    RECUR_USER_OPTIONS->Coarse_Resolution;+#else /* ASA_RESOLUTION */+  if ((RECUR_USER_OPTIONS->Queue_Resolution =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->Queue_Resolution");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* ASA_RESOLUTION */+#if ASA_TEMPLATE_QUEUE+  RECUR_USER_OPTIONS->Queue_Size = 0;+#endif+#endif /* ASA_QUEUE */+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_params */+  /* If not using RECUR_OPTIONS_FILE_DATA or data read from recur_asa_opt,+     store the recur_parameter ranges+     store the recur_parameter types+     store the initial recur_parameter values+     other changes needed for initialization */+#endif /* MY_TEMPLATE recur_params */+  RECUR_USER_OPTIONS->Asa_Recursive_Level = 1;++  return (0);+}++/***********************************************************************+* double recur_cost_function+*	This is the users cost function to optimize+*	(find the minimum).+*	cost_flag is set to TRUE if the parameter set+*	does not violates any constraints+*       recur_parameter_lower_bound and recur_parameter_upper_bound+*       may be adaptively changed during the search.+***********************************************************************/+#if HAVE_ANSI+double+recur_cost_function (double *x,+                     double *recur_parameter_lower_bound,+                     double *recur_parameter_upper_bound,+                     double *recur_cost_tangents,+                     double *recur_cost_curvature,+                     ALLOC_INT * recur_parameter_dimension,+                     int *recur_parameter_int_real,+                     int *recur_cost_flag,+                     int *recur_exit_code, USER_DEFINES * RECUR_USER_OPTIONS)+#else+double+recur_cost_function (x,+                     recur_parameter_lower_bound,+                     recur_parameter_upper_bound,+                     recur_cost_tangents,+                     recur_cost_curvature,+                     recur_parameter_dimension,+                     recur_parameter_int_real,+                     recur_cost_flag, recur_exit_code, RECUR_USER_OPTIONS)+     double *x;+     double *recur_parameter_lower_bound;+     double *recur_parameter_upper_bound;+     double *recur_cost_tangents;+     double *recur_cost_curvature;+     ALLOC_INT *recur_parameter_dimension;+     int *recur_parameter_int_real;+     int *recur_cost_flag;+     int *recur_exit_code;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif+{+  double cost_value;+  static LONG_INT recur_funevals = 0;+  int *exit_code;+#if OPTIONAL_DATA_PTR+  int data_ptr_flg;+#endif+#if OPTIONS_FILE+  FILE *ptr_options;+  char read_option[80];+  char read_if[4], read_FALSE[6], read_comm1[3], read_ASA_SAVE[9],+    read_comm2[3];+  int read_int;+#if INT_LONG+  LONG_INT read_long;+#endif+  double read_double;+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_cost_decl */+  /* add some declarations if required */+#endif++  double *parameter_lower_bound, *parameter_upper_bound;+  double *cost_parameters;+  double *cost_tangents, *cost_curvature;+  ALLOC_INT *parameter_dimension;+  int *parameter_int_real;+  int *cost_flag;+  static LONG_INT *rand_seed;+  static int initial_flag = 0;+#if MULTI_MIN+  int multi_index;+#endif++  USER_DEFINES *USER_OPTIONS;++  recur_funevals = recur_funevals + 1;++  if ((rand_seed = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): rand_seed");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((USER_OPTIONS =+       (USER_DEFINES *) calloc (1, sizeof (USER_DEFINES))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): USER_OPTIONS");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if OPTIONS_FILE+  /* Test to see if asa_opt is in correct directory.+     This is useful for some PC and Mac compilers. */+  if ((ptr_options = fopen ("asa_opt", "r")) == NULL) {+    fprintf (ptr_out, "\n\n*** fopen asa_opt failed *** \n\n");+    fflush (ptr_out);+#if INCL_STDOUT+    printf ("\n\n*** EXIT fopen asa_opt failed *** \n\n");+#endif /* INCL_STDOUT */+    return (6);+  }++  fscanf (ptr_options, "%s%s%s%s%s",+          read_if, read_FALSE, read_comm1, read_ASA_SAVE, read_comm2);+  if (strcmp (read_if, "#if") || strcmp (read_FALSE, "FALSE") ||+      strcmp (read_comm1, "/*") || strcmp (read_ASA_SAVE, "ASA_SAVE") ||+      strcmp (read_comm2, "*/")) {+    fprintf (ptr_out, "\n\n*** not asa_opt for this version *** \n\n");+    fflush (ptr_out);+#if INCL_STDOUT+    printf ("\n\n*** EXIT not asa_opt for this version *** \n\n");+#endif /* INCL_STDOUT */+    return (-6);+  }+#if INT_LONG+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%ld", &read_long);+  USER_OPTIONS->Limit_Acceptances = read_long;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%ld", &read_long);+  USER_OPTIONS->Limit_Generated = read_long;+#else+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Limit_Acceptances = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Limit_Generated = read_int;+#endif+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Limit_Invalid_Generated_States = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Accepted_To_Generated_Ratio = read_double;++  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Cost_Precision = read_double;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Maximum_Cost_Repeat = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Number_Cost_Samples = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Temperature_Ratio_Scale = read_double;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Cost_Parameter_Scale_Ratio = read_double;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Temperature_Anneal_Scale = read_double;++  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Include_Integer_Parameters = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->User_Initial_Parameters = read_int;+#if INT_ALLOC+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Sequential_Parameters = read_int;+#else+#if INT_LONG+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%ld", &read_long);+  USER_OPTIONS->Sequential_Parameters = read_long;+#else+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Sequential_Parameters = read_int;+#endif+#endif+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Initial_Parameter_Temperature = read_double;++  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Acceptance_Frequency_Modulus = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Generated_Frequency_Modulus = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Reanneal_Cost = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Reanneal_Parameters = read_int;++  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Delta_X = read_double;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->User_Tangents = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Curvature_0 = read_int;+#else /* OPTIONS_FILE */+  /* USER_OPTIONS->Limit_Acceptances = 10000; */+  USER_OPTIONS->Limit_Acceptances = 1000;+  USER_OPTIONS->Limit_Generated = 99999;+  USER_OPTIONS->Limit_Invalid_Generated_States = 1000;+  USER_OPTIONS->Accepted_To_Generated_Ratio = 1.0E-6;++  USER_OPTIONS->Cost_Precision = 1.0E-18;+  USER_OPTIONS->Maximum_Cost_Repeat = 2;+  USER_OPTIONS->Number_Cost_Samples = 2;++  /* These variables are set below in x[.] */+  /* USER_OPTIONS->Temperature_Ratio_Scale = 1.0E-5; */+  /* USER_OPTIONS->Cost_Parameter_Scale_Ratio = 1.0; */++  USER_OPTIONS->Temperature_Anneal_Scale = 100.;++  USER_OPTIONS->Include_Integer_Parameters = FALSE;+  USER_OPTIONS->User_Initial_Parameters = FALSE;+  USER_OPTIONS->Sequential_Parameters = -1;+  USER_OPTIONS->Initial_Parameter_Temperature = 1.0;++  USER_OPTIONS->Acceptance_Frequency_Modulus = 100;+  USER_OPTIONS->Generated_Frequency_Modulus = 10000;+  USER_OPTIONS->Reanneal_Cost = 1;+  USER_OPTIONS->Reanneal_Parameters = TRUE;++  USER_OPTIONS->Delta_X = 0.001;+  USER_OPTIONS->User_Tangents = FALSE;+  USER_OPTIONS->Curvature_0 = TRUE;+#endif /* OPTIONS_FILE */++  USER_OPTIONS->Temperature_Ratio_Scale = x[0];+  USER_OPTIONS->Cost_Parameter_Scale_Ratio = x[1];++  if (initial_flag == 0) {+    /* first value of *rand_seed */+#if ASA_LIB+    *rand_seed = (asa_rand_seed ? *asa_rand_seed : (LONG_INT) 696969);+#else+    *rand_seed = 696969;+#endif+  }++  if ((parameter_dimension =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): parameter_dimension");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((exit_code = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): exit_code");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((cost_flag = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): cost_flag");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  /* the number of parameters for the cost function */+#if OPTIONS_FILE_DATA+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%s", read_option);++#if INT_ALLOC+  fscanf (ptr_options, "%d", &read_int);+  *parameter_dimension = read_int;+#else+#if INT_LONG+  fscanf (ptr_options, "%ld", &read_long);+  *parameter_dimension = read_long;+#else+  fscanf (ptr_options, "%d", &read_int);+  *parameter_dimension = read_int;+#endif+#endif++#else /* OPTIONS_FILE_DATA */+#if ASA_TEST+  /* set parameter dimension if SELF_OPTIMIZE=TRUE */+  *parameter_dimension = 4;+#endif /* ASA_TEST */+#endif /* OPTIONS_FILE_DATA */+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_dim */+  /* If not using OPTIONS_FILE_DATA or data read from asa_opt,+     set parameter dimension if SELF_OPTIMIZE=TRUE */+#endif /* MY_TEMPLATE recur_dim */++  if ((parameter_lower_bound =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): parameter_lower_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((parameter_upper_bound =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): parameter_upper_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((cost_parameters =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): cost_parameters");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((parameter_int_real =+       (int *) calloc (*parameter_dimension, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): parameter_int_real");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((cost_tangents =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): cost_tangents");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if (USER_OPTIONS->Curvature_0 == FALSE || USER_OPTIONS->Curvature_0 == -1) {+    if ((cost_curvature =+         (double *) calloc ((*parameter_dimension) *+                            (*parameter_dimension),+                            sizeof (double))) == NULL) {+      strcpy (user_exit_msg, "recur_cost_function(): cost_curvature");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  } else {+    cost_curvature = (double *) NULL;+  }++#if ASA_TEMPLATE_SELFOPT+  /* Set memory to that required for use. */+  USER_OPTIONS->Asa_Data_Dim_Dbl = 2;+  if ((USER_OPTIONS->Asa_Data_Dbl =+       (double *) calloc (USER_OPTIONS->Asa_Data_Dim_Dbl,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_cost_function(): USER_OPTIONS->Asa_Data_Dbl");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* Use Asa_Data_Dbl[0] as flag, e.g., if used with SELF_OPTIMIZE. */+  USER_OPTIONS->Asa_Data_Dbl[0] = 1.0;+#endif /* ASA_TEMPLATE_SELFOPT */++#if USER_COST_SCHEDULE+  USER_OPTIONS->Cost_Schedule = user_cost_schedule;+#endif+#if USER_ACCEPTANCE_TEST+  USER_OPTIONS->Acceptance_Test = user_acceptance_test;+#endif+#if USER_ACCEPT_ASYMP_EXP+  USER_OPTIONS->Asymp_Exp_Param = 1.0;+#endif+#if USER_GENERATING_FUNCTION+  USER_OPTIONS->Generating_Distrib = user_generating_distrib;+#endif+#if USER_REANNEAL_COST+  USER_OPTIONS->Reanneal_Cost_Function = user_reanneal_cost;+#endif+#if USER_REANNEAL_PARAMETERS+  USER_OPTIONS->Reanneal_Params_Function = user_reanneal_params;+#endif++  initialize_parameters (cost_parameters,+                         parameter_lower_bound,+                         parameter_upper_bound,+                         cost_tangents,+                         cost_curvature,+                         parameter_dimension, parameter_int_real,+#if OPTIONS_FILE_DATA+                         ptr_options,+#endif+                         USER_OPTIONS);+#if OPTIONS_FILE+  fclose (ptr_options);+#endif++#if ASA_SAVE+  USER_OPTIONS->Random_Array_Dim = SHUFFLE;+  USER_OPTIONS->Random_Array = random_array;+#endif /* ASA_SAVE */++  /* It might be a good idea to place a loop around this call,+     and to average over several values of funevals returned by+     trajectories of cost_value. */++  funevals = 0;++#if USER_ASA_OUT+  if ((USER_OPTIONS->Asa_Out_File =+       (char *) calloc (80, sizeof (char))) == NULL) {+    strcpy (user_exit_msg,+            "recur_cost_function(): USER_OPTIONS->Asa_Out_File");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE_SELFOPT+  strcpy (USER_OPTIONS->Asa_Out_File, "asa_rcur");+#endif+#endif++#if OPTIONAL_DATA_PTR+  data_ptr_flg = 1;+#if ASA_TEMPLATE+  /* N.b.:  If OPTIONAL_DATA_PTR is being used for RECUR_USER_OPTIONS+   * as well as for USER_OPTIONS, do not create (or free) additional memory+   * in recur_cost_function() for Asa_Data_Dim_Ptr and Asa_Data_Ptr to+   * be passed to the inner cost_function(), but rather link pointers to+   * those in RECUR_USER_OPTIONS.  Typically, define separate structures+   * within the structure defined by Asa_Data_Ptr to access info depending+   * on whether the run in a particular level of cost function in this+   * recursive operation.  In this case, set * #if TRUE to #if FALSE just+   * below.  See the ASA-README for more discussion.+   */++#if TRUE+  USER_OPTIONS->Asa_Data_Dim_Ptr = 1;+  if ((USER_OPTIONS->Asa_Data_Ptr =+       (OPTIONAL_PTR_TYPE *) calloc (USER_OPTIONS->Asa_Data_Dim_Ptr,+                                     sizeof (OPTIONAL_PTR_TYPE))) == NULL) {+    strcpy (user_exit_msg,+            "recur_cost_function(): USER_OPTIONS->Asa_Data_Ptr");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#else+  USER_OPTIONS->Asa_Data_Dim_Ptr = RECUR_USER_OPTIONS->Asa_Data_Dim_Ptr;+  USER_OPTIONS->Asa_Data_Ptr = RECUR_USER_OPTIONS->Asa_Data_Ptr;+  data_ptr_flg = 0;+#endif+#endif /* ASA_TEMPLATE */+  USER_OPTIONS->Asa_Data_Dim_Ptr = 1;+  if ((USER_OPTIONS->Asa_Data_Ptr =+       (OPTIONAL_PTR_TYPE *) calloc (USER_OPTIONS->Asa_Data_Dim_Ptr,+                                     sizeof (OPTIONAL_PTR_TYPE))) == NULL) {+    strcpy (user_exit_msg,+            "recur_cost_function(): USER_OPTIONS->Asa_Data_Ptr");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* OPTIONAL_DATA_PTR */++  cost_value = asa (USER_COST_FUNCTION,+                    randflt,+                    rand_seed,+                    cost_parameters,+                    parameter_lower_bound,+                    parameter_upper_bound,+                    cost_tangents,+                    cost_curvature,+                    parameter_dimension,+                    parameter_int_real, cost_flag, exit_code, USER_OPTIONS);+  if (*exit_code == -1) {+#if INCL_STDOUT+    printf ("\n\n*** error in calloc in ASA ***\n\n");+#endif /* INCL_STDOUT */+    fprintf (ptr_out, "\n\n*** error in calloc in ASA ***\n\n");+    fflush (ptr_out);+    return (-1);+  }+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_post_asa */+#endif++  if (cost_value > .001) {+    *recur_cost_flag = FALSE;+  } else {+    *recur_cost_flag = TRUE;+  }++#if FALSE                       /* set to 1 to activate FAST EXIT */+  /* Make a quick exit */+  if (recur_funevals >= 10) {+    *recur_cost_flag = FALSE;+    RECUR_USER_OPTIONS->Limit_Invalid_Generated_States = 0;+    fprintf (ptr_out, "FAST EXIT set at recur_funevals = 10\n\n");+  }+#endif++#if TIME_CALC+  /* print every RECUR_PRINT_FREQUENCY evaluations */+  if ((RECUR_PRINT_FREQUENCY > 0) &&+      ((recur_funevals % RECUR_PRINT_FREQUENCY) == 0)) {+    USER_OPTIONS->Temperature_Ratio_Scale = x[0];+    fprintf (ptr_out, "USER_OPTIONS->Temperature_Ratio_Scale = %12.7g\n",+             USER_OPTIONS->Temperature_Ratio_Scale);+    USER_OPTIONS->Cost_Parameter_Scale_Ratio = x[1];+    fprintf (ptr_out, "USER_OPTIONS->Cost_Parameter_Scale_Ratio = %12.7g\n",+             USER_OPTIONS->Cost_Parameter_Scale_Ratio);+  }+  print_time ("", ptr_out);+#endif++  fprintf (ptr_out, "recur_funevals = %ld, *recur_cost_flag = %d\n",+           recur_funevals, *recur_cost_flag);+  /* cost function = number generated at best cost */+#if ASA_TEMPLATE_SELFOPT+  funevals = (LONG_INT) (USER_OPTIONS->Asa_Data_Dbl[1]);+  fprintf (ptr_out, "\tbest_funevals = %ld, cost_value = %12.7g\n\n",+           funevals, cost_value);+  /* cost function = total number generated during run */+#endif /* ASA_TEMPLATE_SELFOPT */++#if ASA_SAMPLE+  fprintf (ptr_out, "\tfunevals = %ld, cost_value = %12.7g\n\n",+           funevals, cost_value);+#endif+  fflush (ptr_out);++#if ASA_TEMPLATE_SAMPLE+  ptr_asa = fopen ("asa_out", "r");+  sample (ptr_out, ptr_asa);+#endif++#if OPTIONAL_DATA_DBL+  free (USER_OPTIONS->Asa_Data_Dbl);+#endif+#if OPTIONAL_DATA_INT+  free (USER_OPTIONS->Asa_Data_Int);+#endif+#if OPTIONAL_DATA_PTR+  if (data_ptr_flg == 1) {+    free (USER_OPTIONS->Asa_Data_Ptr);+  }+#endif+#if USER_ASA_OUT+  free (USER_OPTIONS->Asa_Out_File);+#endif+#if ASA_SAMPLE+  free (USER_OPTIONS->Bias_Generated);+#endif+#if ASA_QUEUE+#if ASA_RESOLUTION+#else+  free (USER_OPTIONS->Queue_Resolution);+#endif+#endif+#if ASA_RESOLUTION+  free (USER_OPTIONS->Coarse_Resolution);+#endif+  if (USER_OPTIONS->Curvature_0 == FALSE || USER_OPTIONS->Curvature_0 == -1)+    free (cost_curvature);+#if USER_INITIAL_PARAMETERS_TEMPS+  free (USER_OPTIONS->User_Parameter_Temperature);+#endif+#if USER_INITIAL_COST_TEMP+  free (USER_OPTIONS->User_Cost_Temperature);+#endif+#if DELTA_PARAMETERS+  free (USER_OPTIONS->User_Delta_Parameter);+#endif+#if QUENCH_PARAMETERS+  free (USER_OPTIONS->User_Quench_Param_Scale);+#endif+#if QUENCH_COST+  free (USER_OPTIONS->User_Quench_Cost_Scale);+#endif+#if RATIO_TEMPERATURE_SCALES+  free (USER_OPTIONS->User_Temperature_Ratio);+#endif+#if MULTI_MIN+  free (USER_OPTIONS->Multi_Grid);+  for (multi_index = 0; multi_index < USER_OPTIONS->Multi_Number;+       ++multi_index) {+    free (USER_OPTIONS->Multi_Params[multi_index]);+  }+#endif /* MULTI_MIN */+#if OPTIONAL_DATA_PTR+  if (data_ptr_flg == 0) {+    USER_OPTIONS = NULL;+  }+#endif+  free (USER_OPTIONS);+  free (parameter_dimension);+  free (exit_code);+  free (cost_flag);+  free (parameter_lower_bound);+  free (parameter_upper_bound);+  free (cost_parameters);+  free (parameter_int_real);+  free (cost_tangents);+  free (rand_seed);++  return ((double) funevals);+}++#if USER_COST_SCHEDULE+#if HAVE_ANSI+double+recur_user_cost_schedule (double test_temperature,+                          USER_DEFINES * RECUR_USER_OPTIONS)+#else+double+recur_user_cost_schedule (test_temperature, RECUR_USER_OPTIONS)+     double test_temperature;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif /* HAVE_ANSI */+{+#if ASA_TEMPLATE+  double x;++  x = test_temperature;++  return (x);+#endif+}+#endif /* USER_COST_SCHEDULE */++#if USER_ACCEPTANCE_TEST+#if HAVE_ANSI+void+recur_user_acceptance_test (double current_cost,+                            double *recur_parameter_lower_bound,+                            double *recur_parameter_upper_bound,+                            ALLOC_INT * recur_parameter_dimension,+                            USER_DEFINES * RECUR_USER_OPTIONS)+#else+void+recur_user_acceptance_test (current_cost, recur_parameter_lower_bound,+                            recur_parameter_upper_bound,+                            recur_parameter_dimension, RECUR_USER_OPTIONS)+     double current_cost;+     double *recur_parameter_lower_bound;+     double *recur_parameter_upper_bound;+     ALLOC_INT *recur_parameter_dimension;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif /* HAVE_ANSI */+{+  double uniform_test, curr_cost_temp;+#if USER_ACCEPT_ASYMP_EXP+  double x, q, delta_cost;+#endif++#if ASA_TEMPLATE                /* ASA cost index */+  /* Calculate the current ASA cost index.  This could be useful+     to define a new schedule for the cost temperature, beyond+     simple changes that can be made using USER_COST_SCHEDULE. */++  int index;+  double k_temperature, quench, y;+  double xrecur_parameter_dimension;++#if QUENCH_COST+  quench = RECUR_USER_OPTIONS->User_Quench_Cost_Scale[0];+#else+  quench = 1.0;+#endif /* QUENCH_COST */+  xrecur_parameter_dimension = (double) *recur_parameter_dimension;+  for (index = 0; index < *recur_parameter_dimension; ++index)+    if (fabs+        (recur_parameter_upper_bound[index] -+         recur_parameter_lower_bound[index]) < (double) EPS_DOUBLE)+      *xrecur_parameter_dimension -= 1.0;++  y = -F_LOG (RECUR_USER_OPTIONS->Cost_Temp_Curr+              / RECUR_USER_OPTIONS->Cost_Temp_Init)+    / RECUR_USER_OPTIONS->Cost_Temp_Scale;++  k_temperature = F_POW (y, xrecur_parameter_dimension / quench);+#endif /* ASA cost index */++  uniform_test = randflt (RECUR_USER_OPTIONS->Random_Seed);+  curr_cost_temp = RECUR_USER_OPTIONS->Cost_Temp_Curr;++#if ASA_TEMPLATE+#if USER_COST_SCHEDULE+  curr_cost_temp =+    (RECUR_USER_OPTIONS->Cost_Schedule (RECUR_USER_OPTIONS->Cost_Temp_Curr,+                                        RECUR_USER_OPTIONS)+     + (double) EPS_DOUBLE);+#else+  curr_cost_temp = RECUR_USER_OPTIONS->Cost_Temp_Curr;+#endif+#endif /* ASA_TEMPLATE */++#if USER_ACCEPT_ASYMP_EXP+#if USER_COST_SCHEDULE+  curr_cost_temp =+    (RECUR_USER_OPTIONS->Cost_Schedule (RECUR_USER_OPTIONS->Cost_Temp_Curr,+                                        RECUR_USER_OPTIONS)+     + (double) EPS_DOUBLE);+#endif++  delta_cost = (current_cost - *(RECUR_USER_OPTIONS->Last_Cost))+    / (curr_cost_temp + (double) EPS_DOUBLE);++  q = RECUR_USER_OPTIONS->Asymp_Exp_Param;+  if (fabs (1.0 - q) < (double) EPS_DOUBLE)+    x = MIN (1.0, (F_EXP (-delta_cost)));       /* Boltzmann test */+  else if ((1.0 - (1.0 - q) * delta_cost) < (double) EPS_DOUBLE)+    x = MIN (1.0, (F_EXP (-delta_cost)));       /* Boltzmann test */+  else+    x = MIN (1.0, F_POW ((1.0 - (1.0 - q) * delta_cost), (1.0 / (1.0 - q))));++  RECUR_USER_OPTIONS->Prob_Bias = x;+  if (x >= uniform_test)+    RECUR_USER_OPTIONS->User_Acceptance_Flag = TRUE;+  else+    RECUR_USER_OPTIONS->User_Acceptance_Flag = FALSE;++#endif /* USER_ACCEPT_ASYMP_EXP */+}+#endif /* USER_ACCEPTANCE_TEST */++#if USER_GENERATING_FUNCTION+#if HAVE_ANSI+double+recur_user_generating_distrib (LONG_INT * seed,+                               ALLOC_INT * recur_parameter_dimension,+                               ALLOC_INT index_v,+                               double temperature_v,+                               double init_param_temp_v,+                               double temp_scale_params_v,+                               double parameter_v,+                               double parameter_range_v,+                               double *last_saved_parameter,+                               USER_DEFINES * RECUR_USER_OPTIONS)+#else+double+recur_user_generating_distrib (seed,+                               recur_parameter_dimension,+                               index_v,+                               temperature_v,+                               init_param_temp_v,+                               temp_scale_params_v,+                               parameter_v,+                               parameter_range_v,+                               last_saved_parameter, RECUR_USER_OPTIONS)+     LONG_INT *seed;+     ALLOC_INT *recur_parameter_dimension;+     ALLOC_INT index_v;+     double temperature_v;+     double init_param_temp_v;+     double temp_scale_params_v;+     double parameter_v;+     double parameter_range_v;+     double *last_saved_parameter;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif+{+#if ASA_TEMPLATE+  double x, y, z;++  /* This is the ASA distribution.  A slower temperature schedule can be+     obtained here, e.g., temperature_v = pow(temperature_v, 0.5); */++  x = randflt (seed);+  y = x < 0.5 ? -1.0 : 1.0;+  z = y * temperature_v * (F_POW ((1.0 + 1.0 / temperature_v),+                                  fabs (2.0 * x - 1.0)) - 1.0);++  x = parameter_v + z * parameter_range_v;++  return (x);+#endif /* ASA_TEMPLATE */+}+#endif /* USER_GENERATING_FUNCTION */++#if USER_REANNEAL_COST+#if HAVE_ANSI+int+recur_user_reanneal_cost (double *cost_best,+                          double *cost_last,+                          double *initial_cost_temperature,+                          double *current_cost_temperature,+                          USER_DEFINES * RECUR_USER_OPTIONS)+#else+int+recur_user_reanneal_cost (cost_best,+                          cost_last,+                          initial_cost_temperature,+                          current_cost_temperature, RECUR_USER_OPTIONS)+     double *cost_best;+     double *cost_last;+     double *initial_cost_temperature;+     double *current_cost_temperature;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif /* HAVE_ANSI */+{+#if ASA_TEMPLATE+  double tmp_dbl;++  tmp_dbl = MAX (fabs (*cost_last), fabs (*cost_best));+  tmp_dbl = MAX ((double) EPS_DOUBLE, tmp_dbl);+  *initial_cost_temperature = MIN (*initial_cost_temperature, tmp_dbl);++  return (TRUE);+#endif+}+#endif /* USER_REANNEAL_COST */++#if USER_REANNEAL_PARAMETERS+#if HAVE_ANSI+double+recur_user_reanneal_params (double current_temp,+                            double tangent,+                            double max_tangent,+                            USER_DEFINES * RECUR_USER_OPTIONS)+#else+double+recur_user_reanneal_params (current_temp,+                            tangent, max_tangent, RECUR_USER_OPTIONS)+     double current_temp;+     double tangent;+     double max_tangent;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif /* HAVE_ANSI */+{+#if ASA_TEMPLATE+  double x;++  x = current_temp * (max_tangent / tangent);++  return (x);+#endif+}+#endif /* USER_REANNEAL_PARAMETERS */+#endif /* SELF_OPTIMIZE */++#if FITLOC+#if HAVE_ANSI+double+calcf (double (*user_cost_function)++        +       (double *, double *, double *, double *, double *, ALLOC_INT *, int *,+        int *, int *, USER_DEFINES *), double *xloc,+       double *parameter_lower_bound, double *parameter_upper_bound,+       double *cost_tangents, double *cost_curvature,+       ALLOC_INT * parameter_dimension, int *parameter_int_real,+       int *cost_flag, int *exit_code, USER_DEFINES * OPTIONS, FILE * ptr_out)+#else+double+calcf (user_cost_function,+       xloc,+       parameter_lower_bound,+       parameter_upper_bound,+       cost_tangents,+       cost_curvature,+       parameter_dimension,+       parameter_int_real, cost_flag, exit_code, OPTIONS, ptr_out)+     double (*user_cost_function) ();+     double *x;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+     int *cost_flag;+     int *exit_code;+     USER_DEFINES *OPTIONS;+     FILE *ptr_out;+#endif+{+  ALLOC_INT index_v;+#if FITLOC_ROUND+  double x, min_parameter_v, max_parameter_v, parameter_range_v;+#endif+  double floc;+#if ASA_RESOLUTION+  double xres, xint, xplus, xminus, dx, dxminus, dxplus;+#endif++#if FITLOC_ROUND+  /* The following section for adjustments of parameters is taken from+     generate_new_state() in asa.c */+  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    if (fabs+        (parameter_lower_bound[index_v] - parameter_upper_bound[index_v]) <+        EPS_DOUBLE)+      continue;++    x = xloc[index_v];++    min_parameter_v = parameter_lower_bound[index_v];+    max_parameter_v = parameter_upper_bound[index_v];+    parameter_range_v = max_parameter_v - min_parameter_v;++    /* Handle discrete parameters. */+#if ASA_RESOLUTION+    xres = OPTIONS->Coarse_Resolution[index_v];+    if (xres > EPS_DOUBLE) {+      min_parameter_v -= (xres / 2.0);+      max_parameter_v += (xres / 2.0);+      parameter_range_v = max_parameter_v - min_parameter_v;+    }+#endif /* ASA_RESOLUTION */+    if (parameter_int_real[index_v] > 0) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        min_parameter_v -= 0.5;+        max_parameter_v += 0.5;+        parameter_range_v = max_parameter_v - min_parameter_v;+      }+#if ASA_RESOLUTION+    }+#endif+#if ASA_RESOLUTION+    if (xres > EPS_DOUBLE) {+      xint = xres * (double) ((LONG_INT) (x / xres));+      xplus = xint + xres;+      xminus = xint - xres;+      dx = fabs (xint - x);+      dxminus = fabs (xminus - x);+      dxplus = fabs (xplus - x);++      if (dx < dxminus && dx < dxplus)+        x = xint;+      else if (dxminus < dxplus)+        x = xminus;+      else+        x = xplus;+    }+#endif /* ASA_RESOLUTION */++    /* Handle discrete parameters.+       You might have to check rounding on your machine. */+    if (parameter_int_real[index_v] > 0) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        if (x < min_parameter_v + 0.5)+          x = min_parameter_v + 0.5 + (double) EPS_DOUBLE;+        if (x > max_parameter_v - 0.5)+          x = max_parameter_v - 0.5 + (double) EPS_DOUBLE;++        if (x + 0.5 > 0.0) {+          x = (double) ((LONG_INT) (x + 0.5));+        } else {+          x = (double) ((LONG_INT) (x - 0.5));+        }+        if (x > parameter_upper_bound[index_v])+          x = parameter_upper_bound[index_v];+        if (x < parameter_lower_bound[index_v])+          x = parameter_lower_bound[index_v];+      }+#if ASA_RESOLUTION+    }+    if (xres > EPS_DOUBLE) {+      if (x < min_parameter_v + xres / 2.0)+        x = min_parameter_v + xres / 2.0 + (double) EPS_DOUBLE;+      if (x > max_parameter_v - xres / 2.0)+        x = max_parameter_v - xres / 2.0 + (double) EPS_DOUBLE;++      if (x > parameter_upper_bound[index_v])+        x = parameter_upper_bound[index_v];+      if (x < parameter_lower_bound[index_v])+        x = parameter_lower_bound[index_v];+    }+#endif /* ASA_RESOLUTION */+    if ((x < parameter_lower_bound[index_v])+        || (x > parameter_upper_bound[index_v])) {+      ;+    } else {+      xloc[index_v] = x;+    }+  }+#endif /* FITLOC_ROUND */++  floc = user_cost_function (xloc,+                             parameter_lower_bound,+                             parameter_upper_bound,+                             cost_tangents,+                             cost_curvature,+                             parameter_dimension,+                             parameter_int_real,+                             cost_flag, exit_code, OPTIONS);++  if (*cost_flag == FALSE) {+    floc += OPTIONS->Penalty;+  }++  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    if (parameter_upper_bound[index_v] - xloc[index_v] < EPS_DOUBLE)+      floc += OPTIONS->Penalty;+    else if (xloc[index_v] - parameter_lower_bound[index_v] < EPS_DOUBLE)+      floc += OPTIONS->Penalty;+  }++  return (floc);+}++#if HAVE_ANSI+double+fitloc (double (*user_cost_function)++         +        (double *, double *, double *, double *, double *, ALLOC_INT *, int *,+         int *, int *, USER_DEFINES *), double *xloc,+        double *parameter_lower_bound, double *parameter_upper_bound,+        double *cost_tangents, double *cost_curvature,+        ALLOC_INT * parameter_dimension, int *parameter_int_real,+        int *cost_flag, int *exit_code, USER_DEFINES * OPTIONS,+        FILE * ptr_out)+#else+double+fitloc (user_cost_function,+        xloc,+        parameter_lower_bound,+        parameter_upper_bound,+        cost_tangents,+        cost_curvature,+        parameter_dimension,+        parameter_int_real, cost_flag, exit_code, OPTIONS, ptr_out)+     double (*user_cost_function) ();+     double *xloc;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+     int *cost_flag;+     int *exit_code;+     USER_DEFINES *OPTIONS;+     FILE *ptr_out;+#endif+{+  double x;+  ALLOC_INT index_v;+#if FITLOC_ROUND+  double min_parameter_v, max_parameter_v, parameter_range_v;+#endif+  double *xsave;+  double tol1, tol2, alpha, beta1, beta2, gamma, delta, floc, fsave, ffinal;+  int no_progress, tot_iters, locflg, bndflg;+#if ASA_RESOLUTION+  double xres, xint, xminus, xplus, dx, dxminus, dxplus;+#endif++#if FITLOC_PRINT+  if (OPTIONS->Fit_Local >= 1) {+    fprintf (ptr_out, "\n\nSTART LOCAL FIT\n");+  } else {+    fprintf (ptr_out, "\n\nSTART LOCAL FIT Independent of ASA\n");+  }+  fflush (ptr_out);+#endif /* FITLOC_PRINT */++  xsave = (double *) calloc (*parameter_dimension, sizeof (double));+  bndflg = 0;++  /* The following simplex parameters may need adjustments for your system. */+  tol1 = EPS_DOUBLE;+  tol2 = EPS_DOUBLE * 100.;+  no_progress = 4;+  alpha = 1.0;+  beta1 = 0.75;+  beta2 = 0.75;+  gamma = 1.25;+  delta = 2.50;++  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    xsave[index_v] = xloc[index_v];+  }++  fsave = user_cost_function (xloc,+                              parameter_lower_bound,+                              parameter_upper_bound,+                              cost_tangents,+                              cost_curvature,+                              parameter_dimension,+                              parameter_int_real,+                              cost_flag, exit_code, OPTIONS);++  tot_iters = simplex (user_cost_function,+                       xloc,+                       parameter_lower_bound,+                       parameter_upper_bound,+                       cost_tangents,+                       cost_curvature,+                       parameter_dimension,+                       parameter_int_real,+                       cost_flag,+                       exit_code,+                       OPTIONS,+                       ptr_out,+                       tol1,+                       tol2, no_progress, alpha, beta1, beta2, gamma, delta);+  fflush (ptr_out);++  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    x = xloc[index_v];+    if ((x < parameter_lower_bound[index_v])+        || (x > parameter_upper_bound[index_v])) {+      bndflg = 1;+    }+  }++  /* The following section for adjustments of parameters is taken from+     generate_new_state() in asa.c */+#if FITLOC_ROUND+  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    if (fabs+        (parameter_lower_bound[index_v] - parameter_upper_bound[index_v]) <+        EPS_DOUBLE)+      continue;++    x = xloc[index_v];++    min_parameter_v = parameter_lower_bound[index_v];+    max_parameter_v = parameter_upper_bound[index_v];+    parameter_range_v = max_parameter_v - min_parameter_v;++    /* Handle discrete parameters. */+#if ASA_RESOLUTION+    xres = OPTIONS->Coarse_Resolution[index_v];+    if (xres > EPS_DOUBLE) {+      min_parameter_v -= (xres / 2.0);+      max_parameter_v += (xres / 2.0);+      parameter_range_v = max_parameter_v - min_parameter_v;+    }+#endif /* ASA_RESOLUTION */+    if (parameter_int_real[index_v] > 0) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        min_parameter_v -= 0.5;+        max_parameter_v += 0.5;+        parameter_range_v = max_parameter_v - min_parameter_v;+      }+#if ASA_RESOLUTION+    }+#endif+#if ASA_RESOLUTION+    if (xres > EPS_DOUBLE) {+      xint = xres * (double) ((LONG_INT) (x / xres));+      xplus = xint + xres;+      xminus = xint - xres;+      dx = fabs (xint - x);+      dxminus = fabs (xminus - x);+      dxplus = fabs (xplus - x);++      if (dx < dxminus && dx < dxplus)+        x = xint;+      else if (dxminus < dxplus)+        x = xminus;+      else+        x = xplus;+    }+#endif /* ASA_RESOLUTION */++    /* Handle discrete parameters.+       You might have to check rounding on your machine. */+    if (parameter_int_real[index_v] > 0) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        if (x < min_parameter_v + 0.5)+          x = min_parameter_v + 0.5 + (double) EPS_DOUBLE;+        if (x > max_parameter_v - 0.5)+          x = max_parameter_v - 0.5 + (double) EPS_DOUBLE;++        if (x + 0.5 > 0.0) {+          x = (double) ((LONG_INT) (x + 0.5));+        } else {+          x = (double) ((LONG_INT) (x - 0.5));+        }+        if (x > parameter_upper_bound[index_v])+          x = parameter_upper_bound[index_v];+        if (x < parameter_lower_bound[index_v])+          x = parameter_lower_bound[index_v];+      }+#if ASA_RESOLUTION+    }+    if (xres > EPS_DOUBLE) {+      if (x < min_parameter_v + xres / 2.0)+        x = min_parameter_v + xres / 2.0 + (double) EPS_DOUBLE;+      if (x > max_parameter_v - xres / 2.0)+        x = max_parameter_v - xres / 2.0 + (double) EPS_DOUBLE;++      if (x > parameter_upper_bound[index_v])+        x = parameter_upper_bound[index_v];+      if (x < parameter_lower_bound[index_v])+        x = parameter_lower_bound[index_v];+    }+#endif /* ASA_RESOLUTION */+    if ((x < parameter_lower_bound[index_v])+        || (x > parameter_upper_bound[index_v])) {+      bndflg = 1;+#if FITLOC_PRINT+      if (OPTIONS->Fit_Local == 2)+        fprintf (ptr_out, "IGNORE FITLOC: OUT OF BOUNDS xloc[%ld] = %g\n",+                 index_v, xloc[index_v]);+      else+        fprintf (ptr_out, "OUT OF BOUNDS xloc[%ld] = %g\n",+                 index_v, xloc[index_v]);+#else+      ;+#endif /* FITLOC_PRINT */+    } else {+      xloc[index_v] = x;+    }+  }+#endif /* FITLOC_ROUND */++  floc = user_cost_function (xloc,+                             parameter_lower_bound,+                             parameter_upper_bound,+                             cost_tangents,+                             cost_curvature,+                             parameter_dimension,+                             parameter_int_real,+                             cost_flag, exit_code, OPTIONS);++  if (fabs (floc - fsave) < (double) EPS_DOUBLE) {+    locflg = 1;+    ffinal = fsave;+#if FITLOC_PRINT+    fprintf (ptr_out, "\nsame global cost = %g\tlocal cost = %g\n\n",+             fsave, floc);+#endif /* FITLOC_PRINT */+  } else {+    if (floc < fsave) {+      if (OPTIONS->Fit_Local == 2 && bndflg == 1) {+        locflg = 1;+        ffinal = fsave;+      } else {+        locflg = 0;+        ffinal = floc;+      }+    } else {+      locflg = 1;+      ffinal = fsave;+    }+#if FITLOC_PRINT+    fprintf (ptr_out, "\nDIFF global cost = %g\tlocal cost = %g\n\n",+             fsave, floc);+#endif /* FITLOC_PRINT */+  }++  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    if (fabs (xloc[index_v] - xsave[index_v]) < (double) EPS_DOUBLE) {+#if FITLOC_PRINT+      fprintf (ptr_out, "same global param[%ld] = %g\tlocal param = %g\n",+               index_v, xsave[index_v], xloc[index_v]);+#else+      ;+#endif /* FITLOC_PRINT */+    } else {+#if FITLOC_PRINT+      fprintf (ptr_out, "DIFF global param[%ld] = %g\tlocal param = %g\n",+               index_v, xsave[index_v], xloc[index_v]);+#else+      ;+#endif /* FITLOC_PRINT */+      if (locflg == 1) {+        xloc[index_v] = xsave[index_v];+      }+    }+  }++#if FITLOC_PRINT+  fprintf (ptr_out, "\n");+  fflush (ptr_out);+#endif /* FITLOC_PRINT */++  free (xsave);++  return (ffinal);+}++/*+   Written by Mark Johnson <mjohnson@netcom.com>, based on ++   %A J.A. Nelder+   %A R. Mead+   %T A simplex method for function minimization+   %J Computer J. (UK)+   %V 7+   %D 1964+   %P 308-313++   with improvements from++   %A G.P. Barabino+   %A G.S. Barabino+   %A B. Bianco+   %A M. Marchesi+   %T A study on the performances of simplex methods for function minimization+   %B Proc. IEEE Int. Conf. Circuits and Computers+   %D 1980+   %P 1150-1153++   adapted for use in ASA by Lester Ingber <ingber@ingber.com>+ */++#if HAVE_ANSI+int+simplex (double (*user_cost_function)++          +         (double *, double *, double *, double *, double *, ALLOC_INT *,+          int *, int *, int *, USER_DEFINES *), double *x,+         double *parameter_lower_bound, double *parameter_upper_bound,+         double *cost_tangents, double *cost_curvature,+         ALLOC_INT * parameter_dimension, int *parameter_int_real,+         int *cost_flag, int *exit_code, USER_DEFINES * OPTIONS,+         FILE * ptr_out, double tol1, double tol2, int no_progress,+         double alpha, double beta1, double beta2, double gamma, double delta)+#else+int+simplex (user_cost_function,+         x,+         parameter_lower_bound,+         parameter_upper_bound,+         cost_tangents,+         cost_curvature,+         parameter_dimension,+         parameter_int_real,+         cost_flag,+         exit_code,+         OPTIONS,+         ptr_out, tol1, tol2, no_progress, alpha, beta1, beta2, gamma, delta)+     double (*user_cost_function) ();+     double *x;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+     int *cost_flag;+     int *exit_code;+     USER_DEFINES *OPTIONS;+     FILE *ptr_out;+     double tol1;+     double tol2;+     int no_progress;+     double alpha;+     double beta1;+     double beta2;+     double gamma;+     double delta;+#endif+{+  double fs, fl, fh, fr, fe, fc1, fc2, ftmp, flast;+  double err1;+  double *fvals;+  double **splx;                /* the simplex of points */+  double *x0;                   /* centroid of simplex */+  double *xr;                   /* point for a reflection */+  double *xe;                   /* point for an expansion */+  double *xc1;                  /* point for a minor contraction */+  double *xc2;                  /* point for a major contraction */+  int s, l, h;+  int i, j, iters, futility;+  int lastprint;++  fvals = (double *) calloc (*parameter_dimension + 1, sizeof (double));+  splx = (double **) calloc (*parameter_dimension + 1, sizeof (double *));+  for (i = 0; i <= *parameter_dimension; i++)+    splx[i] = (double *) calloc (*parameter_dimension, sizeof (double));+  x0 = (double *) calloc (*parameter_dimension, sizeof (double));+  xr = (double *) calloc (*parameter_dimension, sizeof (double));+  xe = (double *) calloc (*parameter_dimension, sizeof (double));+  xc1 = (double *) calloc (*parameter_dimension, sizeof (double));+  xc2 = (double *) calloc (*parameter_dimension, sizeof (double));++  /* build the initial simplex */+  for (i = 0; i < *parameter_dimension; i++) {+    splx[0][i] = x[i];+  }+  for (i = 1; i <= *parameter_dimension; i++) {+    for (j = 0; j < *parameter_dimension; j++) {+      if ((j + 1) == i)+        splx[i][j] = (x[j] * 2.25) + tol2;+      else+        splx[i][j] = x[j];+      xr[j] = splx[i][j];+    }+    fvals[i] = calcf (user_cost_function,+                      xr,+                      parameter_lower_bound,+                      parameter_upper_bound,+                      cost_tangents,+                      cost_curvature,+                      parameter_dimension,+                      parameter_int_real,+                      cost_flag, exit_code, OPTIONS, ptr_out);+  }++  /* and of course compute function at starting point */+  fvals[0] = calcf (user_cost_function,+                    x,+                    parameter_lower_bound,+                    parameter_upper_bound,+                    cost_tangents,+                    cost_curvature,+                    parameter_dimension,+                    parameter_int_real,+                    cost_flag, exit_code, OPTIONS, ptr_out);++  /* now find the largest, 2nd largest, smallest f values */+  if (fvals[0] > fvals[1]) {+    h = 0;+    s = 1;+    l = 1;+  } else {+    h = 1;+    s = 0;+    l = 0;+  }+  fh = fvals[h];+  fs = fvals[s];+  fl = fvals[l];+  for (i = 2; i <= *parameter_dimension; i++) {+    if (fvals[i] <= fvals[l]) {+      l = i;+      fl = fvals[i];+    } else {+      if (fvals[i] >= fvals[h]) {+        s = h;+        fs = fh;+        h = i;+        fh = fvals[i];+      } else if (fvals[i] >= fvals[s]) {+        s = i;+        fs = fvals[i];+      }+    }+  }+#if FITLOC_PRINT+  if ((s == h) || (s == l) || (h == l))+    fprintf (ptr_out, "\nPANIC: s,l,h not unique %d %d %d\n", s, h, l);++  fprintf (ptr_out, "INITIAL SIMPLEX:\n");+  for (i = 0; i <= *parameter_dimension; i++) {+    for (j = 0; j < *parameter_dimension; j++) {+      fprintf (ptr_out, "   %11.4g", splx[i][j]);+    }+    fprintf (ptr_out, "      f = %12.5g", fvals[i]);+    if (i == h)+      fprintf (ptr_out, "  HIGHEST");+    if (i == s)+      fprintf (ptr_out, "  SECOND HIGHEST");+    if (i == l)+      fprintf (ptr_out, "  LOWEST");+    fprintf (ptr_out, "\n");+  }+#endif /* FITLOC_PRINT */++/* MAJOR LOOP */++  flast = fl;+  futility = 0;+  lastprint = 0;+  iters = 0;+  err1 = 1.1 + (1.1 * tol1);+  while ((err1 > tol1) && (iters < OPTIONS->Iter_Max) &&+         (futility < (*parameter_dimension * no_progress))) {+    iters++;++    /* now find the largest, 2nd largest, smallest f values */+    if (fvals[0] > fvals[1]) {+      h = 0;+      s = 1;+      l = 1;+    } else {+      h = 1;+      s = 0;+      l = 0;+    }+    fh = fvals[h];+    fs = fvals[s];+    fl = fvals[l];+    for (i = 2; i <= *parameter_dimension; i++) {+      if (fvals[i] <= fvals[l]) {+        l = i;+        fl = fvals[i];+      } else {+        if (fvals[i] >= fvals[h]) {+          s = h;+          fs = fh;+          h = i;+          fh = fvals[i];+        } else if (fvals[i] >= fvals[s]) {+          s = i;+          fs = fvals[i];+        }+      }+    }+#if FITLOC_PRINT+    if ((s == h) || (s == l) || (h == l))+      fprintf (ptr_out, "\nPANIC: s,l,h not unique %d %d %d\n", s, h, l);+#endif++    /* compute the centroid */+    for (j = 0; j < *parameter_dimension; j++) {+      x0[j] = 0.0;+      for (i = 0; i <= *parameter_dimension; i++) {+        if (i != h)+          x0[j] += splx[i][j];+      }+      x0[j] /= ((double) *parameter_dimension);+    }++    if (fl < flast) {+      flast = fl;+      futility = 0;+    } else+      futility += 1;++#if FITLOC_PRINT+    fprintf (ptr_out, "Iteration %3d f(best) = %12.6g halt? = %11.5g\n",+             iters, fl, err1);+    if ((iters - lastprint) >= 100) {+      fprintf (ptr_out, "\n     Best point seen so far:\n");+      for (i = 0; i < *parameter_dimension; i++) {+        fprintf (ptr_out, "     x[%3d] = %15.7g\n", i, splx[l][i]);+      }+      lastprint = iters;+      fprintf (ptr_out, "\n");+    }+    fflush (ptr_out);+#endif /* FITLOC_PRINT */++    /* STEP 1: compute a reflected point xr */+    for (i = 0; i < *parameter_dimension; i++) {+      xr[i] = ((1.0 + alpha) * x0[i]) - (alpha * splx[h][i]);+    }+    fr = calcf (user_cost_function,+                xr,+                parameter_lower_bound,+                parameter_upper_bound,+                cost_tangents,+                cost_curvature,+                parameter_dimension,+                parameter_int_real, cost_flag, exit_code, OPTIONS, ptr_out);++    /* typical outcome: <2nd-biggest , >lowest .  Go again */+    if ((fr < fs) && (fr > fl)) {+      for (i = 0; i < *parameter_dimension; i++) {+        splx[h][i] = xr[i];+      }+      fvals[h] = fr;+      goto more_iterations;+    }++    /* STEP 2: if reflected point is favorable, expand the simplex */+    if (fr < fl) {+      for (i = 0; i < *parameter_dimension; i++) {+        xe[i] = (gamma * xr[i]) + ((1.0 - gamma) * x0[i]);+      }+      fe = calcf (user_cost_function,+                  xe,+                  parameter_lower_bound,+                  parameter_upper_bound,+                  cost_tangents,+                  cost_curvature,+                  parameter_dimension,+                  parameter_int_real, cost_flag, exit_code, OPTIONS, ptr_out);+      if (fe < fr) {            /* win big; expansion point tiny */+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xe[i];+        }+        fvals[h] = fh = fe;+      } else+        /* still ok; reflection point a winner */+      {+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xr[i];+        }+        fvals[h] = fh = fr;+      }+      goto more_iterations;+    }++    /* STEP 3: if reflected point is unfavorable, contract simplex */+    if (fr > fs) {+      if (fr < fh) {            /* may as well replace highest pt */+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xr[i];+        }+        fvals[h] = fh = fr;+      }+      for (i = 0; i < *parameter_dimension; i++) {+        xc1[i] = (beta1 * xr[i]) + ((1.0 - beta1) * x0[i]);+      }+      fc1 = calcf (user_cost_function,+                   xc1,+                   parameter_lower_bound,+                   parameter_upper_bound,+                   cost_tangents,+                   cost_curvature,+                   parameter_dimension,+                   parameter_int_real,+                   cost_flag, exit_code, OPTIONS, ptr_out);+      if (fc1 < fh) {           /* slight contraction worked */+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xc1[i];+        }+        fvals[h] = fh = fc1;+        goto more_iterations;+      }+      /* now have to try strong contraction */+      for (i = 0; i < *parameter_dimension; i++) {+        xc2[i] = (beta2 * splx[h][i]) + ((1.0 - beta2) * x0[i]);+      }+      fc2 = calcf (user_cost_function,+                   xc2,+                   parameter_lower_bound,+                   parameter_upper_bound,+                   cost_tangents,+                   cost_curvature,+                   parameter_dimension,+                   parameter_int_real,+                   cost_flag, exit_code, OPTIONS, ptr_out);+      if (fc2 < fh) {           /* strong contraction worked */+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xc2[i];+        }+        fvals[h] = fh = fc2;+        goto more_iterations;+      }+    }++    /* STEP 4: nothing worked.  collapse the simplex around xl */+    for (i = 0; i <= *parameter_dimension; i++) {+      if (i != l) {+        for (j = 0; j < *parameter_dimension; j++) {+          splx[i][j] = (splx[i][j] + splx[l][j]) / delta;+          xr[j] = splx[i][j];+        }+        fvals[i] = calcf (user_cost_function,+                          xr,+                          parameter_lower_bound,+                          parameter_upper_bound,+                          cost_tangents,+                          cost_curvature,+                          parameter_dimension,+                          parameter_int_real,+                          cost_flag, exit_code, OPTIONS, ptr_out);+      }+    }++  more_iterations:++    ftmp = 0.00;+    for (i = 0; i <= *parameter_dimension; i++) {+      ftmp += fvals[i];+    }+    ftmp /= ((double) (*parameter_dimension + 1));++    err1 = 0.00;+    for (i = 0; i <= *parameter_dimension; i++) {+      err1 += ((fvals[i] - ftmp) * (fvals[i] - ftmp));+    }+    err1 /= ((double) (*parameter_dimension + 1));+    err1 = sqrt (err1);+  }                             /* end of major while loop */++  /* find the smallest f value */+  l = 0;+  fl = fvals[0];+  for (i = 1; i <= *parameter_dimension; i++) {+    if (fvals[i] < fvals[l])+      l = i;+  }++  /* give it back to the user */+  for (i = 0; i < *parameter_dimension; i++) {+    x[i] = splx[l][i];+  }++  free (fvals);+  for (i = 0; i <= *parameter_dimension; i++)+    free (splx[i]);+  free (splx);+  free (x0);+  free (xr);+  free (xe);+  free (xc1);+  free (xc2);++  return (iters);+}+#else+#endif /* FITLOC */++#if ASA_TEMPLATE_SAMPLE++#if HAVE_ANSI+void+sample (FILE * ptr_out, FILE * ptr_asa)+#else+void+sample (ptr_out, ptr_asa)+     FILE *ptr_out;+     FILE *ptr_asa;+#endif+{+  int ind, n_samples, n_accept, index, dim;+  double cost, cost_temp, bias_accept;+  double param, temp, bias_gener, aver_weight, range;+  double sum, norm, answer, prod, binsize;+  char ch[80], sample[8];++  /*+     This is a demonstration of using ASA_SAMPLE to perform the double integral+     of exp(-x^2 - y^2) for x and y between 0 and 2.  The mesh is quite crude.++     The temperature-dependent acceptance and generated biases factor are+     divided out, and the actual cost function weights each point.+   */++  dim = 2;+  norm = sum = 0.;+  n_samples = 0;++  fprintf (ptr_out,+           ":SAMPLE:   n_accept   cost        cost_temp    bias_accept    \+ aver_weight\n");+  fprintf (ptr_out,+           ":SAMPLE:   index      param[]     temp[]       bias_gener[]   \+ range[]\n");+  for (;;) {+    fscanf (ptr_asa, "%s", ch);+    if (!strcmp (ch, "exit_status")) {+      break;+    }+    if (strcmp (ch, ":SAMPLE#")) {+      continue;+    }+    ++n_samples;+    fprintf (ptr_out, "%s\n", ch);+    fflush (ptr_out);+    fscanf (ptr_asa, "%s%d%lf%lf%lf%lf",+            sample, &n_accept, &cost, &cost_temp, &bias_accept, &aver_weight);+    if (strcmp (sample, ":SAMPLE+")) {+      fprintf (ptr_out, "%s %11d %12.7g %12.7g %12.7g %12.7g\n",+               sample, n_accept, cost, cost_temp, bias_accept, aver_weight);+    } else {+      fprintf (ptr_out, "%s %10d %12.7g %12.7g %12.7g %12.7g\n",+               sample, n_accept, cost, cost_temp, bias_accept, aver_weight);+    }+    prod = bias_accept;+    binsize = 1.0;+    for (ind = 0; ind < dim; ++ind) {+      fscanf (ptr_asa, "%s%d%lf%lf%lf%lf",+              sample, &index, &param, &temp, &bias_gener, &range);+      fprintf (ptr_out, "%s %11d %12.7g %12.7g %12.7g %12.7g\n",+               sample, index, param, temp, bias_gener, range);+      prod *= bias_gener;+      binsize *= range;+    }+    /* In this example, retrieve integrand from sampling function */+    sum += ((F_EXP (-cost) * binsize) / prod);+    norm += (binsize / prod);+  }+  sum /= norm;++  answer = 1.0;+  for (ind = 0; ind < dim; ++ind) {+    answer *= (0.5 * sqrt (3.14159265) * erf (2.0));+  }++  fprintf (ptr_out, "\n");+  fprintf (ptr_out, "sum = %12.7g, answer = %12.7g\n", sum, answer);+  fprintf (ptr_out, "n_samples = %d, norm = %12.7g\n", n_samples, norm);+  fflush (ptr_out);++}+#endif /* ASA_TEMPLATE_SAMPLE */+#if ASA_TEMPLATE_LIB+int+main ()+{+  double main_cost_value;+  double *main_cost_parameters;+  int main_exit_code;+  LONG_INT number_params;+  ALLOC_INT n_param;+  FILE *ptr_main;++#if INCL_STDOUT+  ptr_main = stdout;+#endif /* INCL_STDOUT */++  /* Note this assumes the *parameter_dimension = 4 */+  number_params = 4;++  if ((main_cost_parameters =+       (double *) calloc (number_params, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "ASA_TEMPLATE_LIB main(): main_cost_parameters");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  asa_seed (696969);            /* This is the default random seed. */+  asa_main (&main_cost_value, main_cost_parameters, &main_exit_code);++  fprintf (ptr_main, "main_exit_code = %d\n", main_exit_code);+  fprintf (ptr_main, "main_cost_value = %12.7g\n", main_cost_value);+  fprintf (ptr_main, "parameter\tvalue\n");+  for (n_param = 0; n_param < number_params; ++n_param) {+    fprintf (ptr_main,+#if INT_ALLOC+             "%d\t\t%12.7g\n",+#else+#if INT_LONG+             "%ld\t\t%12.7g\n",+#else+             "%d\t\t%12.7g\n",+#endif+#endif+             n_param, main_cost_parameters[n_param]);+  }++  free (main_cost_parameters);++  return (0);+/* NOTREACHED */+}+#endif /* ASA_TEMPLATE_LIB */++void+Exit_USER (char *statement)+{+#if INCL_STDOUT+  printf ("\n\n*** EXIT calloc failed *** %s\n\n", statement);+#else+  ;+#endif /* INCL_STDOUT */+}
+ cbits/asa.c view
@@ -0,0 +1,6387 @@+/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+***********************************************************************/++#define ASA_ID \+"/* $Id: asa.c,v 25.15 2004/09/23 18:10:46 ingber Exp ingber $ */"++#include "asa.h"+static int asa_recursive_max = 0;       /* record of max recursions */++/***********************************************************************+* asa+*       This procedure implements the full ASA function optimization.+***********************************************************************/+#if HAVE_ANSI+double+asa (double (*user_cost_function)++      +     (double *, double *, double *, double *, double *, ALLOC_INT *, int *,+      int *, int *, USER_DEFINES *),+     double (*user_random_generator) (LONG_INT *), LONG_INT * seed,+     double *parameter_initial_final, double *parameter_minimum,+     double *parameter_maximum, double *tangents, double *curvature,+     ALLOC_INT * number_parameters, int *parameter_type,+     int *valid_state_generated_flag, int *exit_status,+     USER_DEFINES * OPTIONS)+#else+double+asa (user_cost_function,+     user_random_generator,+     seed,+     parameter_initial_final,+     parameter_minimum,+     parameter_maximum,+     tangents,+     curvature,+     number_parameters,+     parameter_type, valid_state_generated_flag, exit_status, OPTIONS)+     double (*user_cost_function) ();+     double (*user_random_generator) ();+     LONG_INT *seed;+     double *parameter_initial_final;+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *curvature;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     int *valid_state_generated_flag;+     int *exit_status;+     USER_DEFINES *OPTIONS;+#endif /* HAVE_ANSI */+{+#if USER_INITIAL_COST_TEMP+#if USER_REANNEAL_COST+#else+  int index_cost_constraint;    /* index cost functions averaged */+#endif /* USER_REANNEAL_COST */+#else /* USER_INITIAL_COST_TEMP */+  int index_cost_constraint;    /* index cost functions averaged */+#endif /* USER_INITIAL_COST_TEMP */++  int index_cost_repeat,        /* test OPTIONS->Cost_Precision when =+                                   OPTIONS->Maximum_Cost_Repeat */+    tmp_var_int, tmp_var_int1, tmp_var_int2;    /* temporary integers */++  ALLOC_INT index_v,            /* iteration index */+   *start_sequence;             /* initial OPTIONS->Sequential_Parameters+                                   used if >= 0 */+  double final_cost,            /* best cost to return to user */+    tmp_var_db, tmp_var_db1, tmp_var_db2;       /* temporary doubles */+  int *curvature_flag;+  FILE *ptr_asa_out;            /* file ptr to output file */++  /* The 3 states that are kept track of during the annealing process */+  STATE *current_generated_state, *last_saved_state, *best_generated_state;++#if ASA_SAVE+  FILE *ptr_save, *ptr_comm;+  int asa_read;+  char asa_save_comm[100];+#if ASA_SAVE_OPT+  char read_option[80];+  char read_if[4], read_FALSE[6], read_comm1[3], read_ASA_SAVE[9],+    read_comm2[3];+  int read_int;+#if INT_LONG+  LONG_INT read_long;+#endif+  double read_double;+  FILE *ptr_save_opt;+#endif+#endif /* ASA_SAVE */++#if ASA_PIPE_FILE+  FILE *ptr_asa_pipe;+#endif++  int immediate_flag;           /* save Immediate_Exit */+  int asa_exit_value;++  double xnumber_parameters[1];++  /* The array of tangents (absolute value of the numerical derivatives),+     and the maximum |tangent| of the array */+  double *maximum_tangent;++  /* ratio of acceptances to generated points - determines when to+     test/reanneal */+  double *accepted_to_generated_ratio;++  /* temperature parameters */+  double temperature_scale, *temperature_scale_parameters;+  /* relative scalings of cost and parameters to temperature_scale */+  double *temperature_scale_cost;+  double *current_user_parameter_temp;+  double *initial_user_parameter_temp;+  double *current_cost_temperature;+  double *initial_cost_temperature;+  double log_new_temperature_ratio;     /* current *temp = initial *temp *+                                           exp(log_new_temperature_ratio) */+  ALLOC_INT *index_exit_v;      /* information for asa_exit */++  /* counts of generated states and acceptances */+  LONG_INT *index_parameter_generations;+  LONG_INT *number_generated, *best_number_generated_saved;+  LONG_INT *recent_number_generated, *number_accepted;+  LONG_INT *recent_number_acceptances, *index_cost_acceptances;+  LONG_INT *number_acceptances_saved, *best_number_accepted_saved;++  /* Flag indicates that the parameters generated were+     invalid according to the cost function validity criteria. */+  LONG_INT *number_invalid_generated_states;+  LONG_INT repeated_invalid_states;++#if ASA_QUEUE+  int queue_new;                /* flag to add new entry */+  int *save_queue_flag;         /* save valid_state_generated_flag */+  LONG_INT queue;               /* index of queue */+  LONG_INT queue_v;             /* index of parameters in queue */+  LONG_INT save_queue_test;     /* test if all parameters are present */+  LONG_INT save_queue;          /* last filled position in queue */+  LONG_INT save_queue_indx;     /* current position in queue */+  double *save_queue_cost, *save_queue_param;   /* saved states */+  ALLOC_INT queue_size_tmp;+#endif++#if MULTI_MIN+  int multi_index;+  int multi_test, multi_test_cmp, multi_test_dim;+  int *multi_sort;+  double *multi_cost;+  double **multi_params;+#endif /* MULTI_MIN */++#if ASA_PARALLEL+  LONG_INT *parallel_sort;+  LONG_INT index_parallel, sort_index;  /* count of parallel generated states */+  LONG_INT parallel_generated;  /* saved *recent_number_generated */+  LONG_INT parallel_block_max;  /* saved OPTIONS->Gener_Block_Max */+  STATE *gener_block_state;+#endif++  /* used to index repeated and recursive calls to asa */+  /* This assumes that multiple calls (>= 1) _or_ recursive+     calls are being made to asa */+  static int asa_open = FALSE;+  static int number_asa_open = 0;+  static int recursive_asa_open = 0;++  /* initializations */++  if ((curvature_flag = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (exit_msg, "asa(): curvature_flag");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((maximum_tangent = (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): maximum_tangent");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((accepted_to_generated_ratio =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): accepted_to_generated_ratio");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((temperature_scale_cost =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): temperature_scale_cost");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((current_cost_temperature =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): current_cost_temperature");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((initial_cost_temperature =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): initial_cost_temperature");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((index_exit_v = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): index_exit_v");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((start_sequence = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): start_sequence");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((number_generated =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): number_generated");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((best_number_generated_saved =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): best_number_generated_saved");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((recent_number_generated =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): recent_number_generated");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((number_accepted =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): number_accepted");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((recent_number_acceptances =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): recent_number_acceptances");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((index_cost_acceptances =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): index_cost_acceptances");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((number_acceptances_saved =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): number_acceptances_saved");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((best_number_accepted_saved =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): best_number_accepted_saved");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((number_invalid_generated_states =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): number_invalid_generated_states");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }++  if ((current_generated_state =+       (STATE *) calloc (1, sizeof (STATE))) == NULL) {+    strcpy (exit_msg, "asa(): current_generated_state");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((last_saved_state = (STATE *) calloc (1, sizeof (STATE))) == NULL) {+    strcpy (exit_msg, "asa(): last_saved_state");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((best_generated_state = (STATE *) calloc (1, sizeof (STATE))) == NULL) {+    strcpy (exit_msg, "asa(): best_generated_state");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#if ASA_PARALLEL+  if ((gener_block_state =+       (STATE *) calloc (OPTIONS->Gener_Block_Max, sizeof (STATE))) == NULL) {+    strcpy (exit_msg, "asa(): gener_block_state");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  gener_block_state_qsort = gener_block_state;+  if ((parallel_sort =+       (LONG_INT *) calloc (OPTIONS->Gener_Block_Max,+                            sizeof (LONG_INT))) == NULL) {+    strcpy (exit_msg, "asa(): parallel_sort");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#endif++  /* set default */+  ptr_asa_out = (FILE *) NULL;++  OPTIONS->Immediate_Exit = FALSE;++  if (asa_open == FALSE) {+    asa_open = TRUE;+    ++number_asa_open;+#if ASA_PRINT+    if (number_asa_open == 1) {+      /* open the output file */+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+#if ASA_SAVE+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");+#else+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "w");+#endif+      }+#else /* USER_ASA_OUT */+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+#if ASA_SAVE+        ptr_asa_out = fopen (ASA_OUT, "a");+#else+        ptr_asa_out = fopen (ASA_OUT, "w");+#endif+      }+#endif /* USER_ASA_OUT */+    } else {+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");+      }+#else+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (ASA_OUT, "a");+      }+#endif+      fprintf (ptr_asa_out, "\n\n\t\t number_asa_open = %d\n",+               number_asa_open);+    }+#endif /* ASA_PRINT */+  } else {+    ++recursive_asa_open;+#if ASA_PRINT+    if (recursive_asa_open == 1) {+      /* open the output file */+#if ASA_SAVE+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");+      }+#else+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (ASA_OUT, "a");+      }+#endif+#else /* ASA_SAVE */+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "w");+      }+#else+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (ASA_OUT, "w");+      }+#endif+#endif /* ASA_SAVE */+    } else {+#if USER_ASA_OUT+      if (!strcmp (OPTIONS->Asa_Out_File, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (OPTIONS->Asa_Out_File, "a");+      }+#else+      if (!strcmp (ASA_OUT, "STDOUT")) {+#if INCL_STDOUT+        ptr_asa_out = stdout;+#endif /* INCL_STDOUT */+      } else {+        ptr_asa_out = fopen (ASA_OUT, "a");+      }+#endif+      fprintf (ptr_asa_out, "\n\n\t\t recursive_asa_open = %d\n",+               recursive_asa_open);+    }+#endif /* ASA_PRINT */+  }++#if ASA_PIPE_FILE+  ptr_asa_pipe = fopen ("asa_pipe", "a");+  fprintf (ptr_asa_pipe, "%s", "%generate");+  fprintf (ptr_asa_pipe, "\t%s", "accept");+  fprintf (ptr_asa_pipe, "\t%s", "best_cost");+  VFOR (index_v)+#if INT_ALLOC+    fprintf (ptr_asa_pipe, "\t%s-%d", "param", index_v);+#else+#if INT_LONG+    fprintf (ptr_asa_pipe, "\t%s-%ld", "param", index_v);+#else+    fprintf (ptr_asa_pipe, "\t%s-%d", "param", index_v);+#endif+#endif+  fprintf (ptr_asa_pipe, "\t%s", "cost_temp");+  VFOR (index_v)+#if INT_ALLOC+    fprintf (ptr_asa_pipe, "\t%s-%d", "param_temp", index_v);+#else+#if INT_LONG+    fprintf (ptr_asa_pipe, "\t%s-%ld", "param_temp", index_v);+#else+    fprintf (ptr_asa_pipe, "\t%s-%d", "param_temp", index_v);+#endif+#endif+  fprintf (ptr_asa_pipe, "\t%s", "last_cost");+  fprintf (ptr_asa_pipe, "\n");+  fflush (ptr_asa_pipe);+#endif /* ASA_PIPE_FILE */++#if ASA_PRINT+  /* print header information as defined by user */+  print_asa_options (ptr_asa_out, OPTIONS);++  fflush (ptr_asa_out);+#endif /* ASA_PRINT */++  /* set indices and counts to 0 */+  *best_number_generated_saved =+    *number_generated =+    *recent_number_generated = *recent_number_acceptances = 0;+  *index_cost_acceptances =+    *best_number_accepted_saved =+    *number_accepted = *number_acceptances_saved = 0;+  index_cost_repeat = 0;++  OPTIONS->N_Accepted = *number_accepted;+  OPTIONS->N_Generated = *number_generated;++#if ASA_SAMPLE+  OPTIONS->N_Generated = 0;+  OPTIONS->Average_Weights = 1.0;+#endif++  /* do not calculate curvatures initially */+  *curvature_flag = FALSE;++  /* allocate storage for all parameters */+  if ((current_generated_state->parameter =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): current_generated_state->parameter");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((last_saved_state->parameter =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): last_saved_state->parameter");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((best_generated_state->parameter =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): best_generated_state->parameter");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#if ASA_PARALLEL+  parallel_block_max = OPTIONS->Gener_Block_Max;+  parallel_generated = OPTIONS->Gener_Block;++  for (index_parallel = 0; index_parallel < parallel_block_max;+       ++index_parallel) {+    if ((gener_block_state[index_parallel].parameter =+         (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+      strcpy (exit_msg, "asa(): gener_block_state[index_parallel].parameter");+      Exit_ASA (exit_msg);+      *exit_status = CALLOC_FAILED;+      return (-1);+    }+  }+#endif++  OPTIONS->Best_Cost = &(best_generated_state->cost);+  OPTIONS->Best_Parameters = best_generated_state->parameter;+  OPTIONS->Last_Cost = &(last_saved_state->cost);+  OPTIONS->Last_Parameters = last_saved_state->parameter;++  if ((initial_user_parameter_temp =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): initial_user_parameter_temp");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((index_parameter_generations =+       (ALLOC_INT *) calloc (*number_parameters,+                             sizeof (ALLOC_INT))) == NULL) {+    strcpy (exit_msg, "asa(): index_parameter_generations");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }++  /* set all temperatures */+  if ((current_user_parameter_temp =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): current_user_parameter_temp");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#if USER_INITIAL_PARAMETERS_TEMPS+  VFOR (index_v)+    current_user_parameter_temp[index_v] =+    initial_user_parameter_temp[index_v] =+    OPTIONS->User_Parameter_Temperature[index_v];+#else+  VFOR (index_v)+    current_user_parameter_temp[index_v] =+    initial_user_parameter_temp[index_v] =+    OPTIONS->Initial_Parameter_Temperature;+#endif++  if ((temperature_scale_parameters =+       (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): temperature_scale_parameters");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#if ASA_QUEUE+  if (OPTIONS->Queue_Size > 0) {+    queue_size_tmp = OPTIONS->Queue_Size;+  } else {+    queue_size_tmp = 1;+  }+  if ((save_queue_flag =+       (int *) calloc (queue_size_tmp, sizeof (int))) == NULL) {+    strcpy (exit_msg, "asa(): save_queue_flag");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((save_queue_cost =+       (double *) calloc (queue_size_tmp, sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): save_queue_cost");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((save_queue_param =+       (double *) calloc ((*number_parameters) * queue_size_tmp,+                          sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): save_queue_param");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+#endif /* ASA_QUEUE */++#if MULTI_MIN+  if ((multi_cost =+       (double *) calloc (OPTIONS->Multi_Number + 1,+                          sizeof (double))) == NULL) {+    strcpy (exit_msg, "asa(): *multi_cost");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  multi_cost_qsort = multi_cost;+  if ((multi_sort =+       (int *) calloc (OPTIONS->Multi_Number + 1, sizeof (int))) == NULL) {+    strcpy (exit_msg, "asa(): *multi_sort");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  if ((multi_params =+       (double **) calloc (OPTIONS->Multi_Number + 1,+                           sizeof (double *))) == NULL) {+    strcpy (exit_msg, "asa(): *multi_params");+    Exit_ASA (exit_msg);+    *exit_status = CALLOC_FAILED;+    return (-1);+  }+  for (multi_index = 0; multi_index <= OPTIONS->Multi_Number; ++multi_index) {+    if ((multi_params[multi_index] =+         (double *) calloc (*number_parameters, sizeof (double))) == NULL) {+      strcpy (exit_msg, "asa(): multi_params[multi_index]");+      Exit_ASA (exit_msg);+      *exit_status = CALLOC_FAILED;+      return (-1);+    }+  }+#endif /* MULTI_MIN */++#if USER_INITIAL_COST_TEMP+#if USER_ACCEPTANCE_TEST+  OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =+#endif+    *initial_cost_temperature = *current_cost_temperature =+    OPTIONS->User_Cost_Temperature[0];+#endif++  /* set parameters to the initial parameter values */+  VFOR (index_v)+    last_saved_state->parameter[index_v] =+    current_generated_state->parameter[index_v] =+    parameter_initial_final[index_v];+#if USER_ACCEPTANCE_TEST+  OPTIONS->Random_Seed = seed;+  OPTIONS->Random_Seed[0] = *seed;+  OPTIONS->User_Acceptance_Flag = TRUE;+  OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif++#if ASA_PRINT+#if INT_LONG+  fprintf (ptr_asa_out, "Initial Random Seed = %ld\n\n", *seed);+#else+  fprintf (ptr_asa_out, "Initial Random Seed = %d\n\n", *seed);+#endif+#endif /* ASA_PRINT */++  /* save initial user value of OPTIONS->Sequential_Parameters */+  *start_sequence = OPTIONS->Sequential_Parameters;++#if ASA_PRINT+  fprintf (ptr_asa_out,+#if INT_ALLOC+           "*number_parameters = %d\n\n", *number_parameters);+#else+#if INT_LONG+           "*number_parameters = %ld\n\n", *number_parameters);+#else+           "*number_parameters = %d\n\n", *number_parameters);+#endif+#endif++  /* print the min, max, current values, and types of parameters */+  fprintf (ptr_asa_out, "index_v parameter_minimum parameter_maximum\+ parameter_value parameter_type \n");++#if ASA_PRINT_INTERMED+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          " %-8d %-*.*g \t\t %-*.*g \t %-*.*g %-7d\n",+#else+#if INT_LONG+                          " %-8ld %-*.*g \t\t %-*.*g \t %-*.*g %-7d\n",+#else+                          " %-8d %-*.*g \t\t %-*.*g \t %-*.*g %-7d\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION, parameter_minimum[index_v],+                          G_FIELD, G_PRECISION, parameter_maximum[index_v],+                          G_FIELD, G_PRECISION,+                          current_generated_state->parameter[index_v],+                          parameter_type[index_v]);++  fprintf (ptr_asa_out, "\n\n");+#endif /* ASA_PRINT_INTERMED */+  /* Print out user-defined OPTIONS */++#if DELTA_PARAMETERS+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          "OPTIONS->User_Delta_Parameter[%d] = %*.*g\n",+#else+#if INT_LONG+                          "OPTIONS->User_Delta_Parameter[%ld] = %*.*g\n",+#else+                          "OPTIONS->User_Delta_Parameter[%d] = %*.*g\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION,+                          OPTIONS->User_Delta_Parameter[index_v]);+  fprintf (ptr_asa_out, "\n");+#endif /* DELTA_PARAMETERS */++#if QUENCH_PARAMETERS+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          "OPTIONS->User_Quench_Param_Scale[%d] = %*.*g\n",+#else+#if INT_LONG+                          "OPTIONS->User_Quench_Param_Scale[%ld] = %*.*g\n",+#else+                          "OPTIONS->User_Quench_Param_Scale[%d] = %*.*g\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION,+                          OPTIONS->User_Quench_Param_Scale[index_v]);+#endif /* QUENCH_PARAMETERS */++#if QUENCH_COST+  fprintf (ptr_asa_out,+           "\nOPTIONS->User_Quench_Cost_Scale = %*.*g\n\n",+           G_FIELD, G_PRECISION, OPTIONS->User_Quench_Cost_Scale[0]);+#endif /* QUENCH_COST */++#if USER_INITIAL_PARAMETERS_TEMPS+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          "OPTIONS->User_Parameter_Temperature[%d] = %*.*g\n",+#else+#if INT_LONG+                          "OPTIONS->User_Parameter_Temperature[%ld] = %*.*g\n",+#else+                          "OPTIONS->User_Parameter_Temperature[%d] = %*.*g\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION,+                          initial_user_parameter_temp[index_v]);+#endif /* USER_INITIAL_PARAMETERS_TEMPS */++#if RATIO_TEMPERATURE_SCALES+  VFOR (index_v) fprintf (ptr_asa_out,+#if INT_ALLOC+                          "OPTIONS->User_Temperature_Ratio[%d] = %*.*g\n",+#else+#if INT_LONG+                          "OPTIONS->User_Temperature_Ratio[%ld] = %*.*g\n",+#else+                          "OPTIONS->User_Temperature_Ratio[%d] = %*.*g\n",+#endif+#endif+                          index_v,+                          G_FIELD, G_PRECISION,+                          OPTIONS->User_Temperature_Ratio[index_v]);+#endif /* RATIO_TEMPERATURE_SCALES */++#if USER_INITIAL_COST_TEMP+  fprintf (ptr_asa_out,+           "OPTIONS->User_Cost_Temperature[0] = %*.*g\n",+           G_FIELD, G_PRECISION, *initial_cost_temperature);+#endif /* USER_INITIAL_COST_TEMP */++  fflush (ptr_asa_out);+#endif /* ASA_PRINT */++#if MULTI_MIN+#if ASA_PRINT+  fprintf (ptr_asa_out, "\n");+  fprintf (ptr_asa_out, "Multi_Number = %d\n", OPTIONS->Multi_Number);+  fprintf (ptr_asa_out, "Multi_Specify = %d\n", OPTIONS->Multi_Specify);+#if ASA_RESOLUTION+#else+  VFOR (index_v) {+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "Multi_Grid[%d] = %*.*g\n",+#else+#if INT_LONG+             "Multi_Grid[%ld] = %*.*g\n",+#else+             "Multi_Grid[%d] = %*.*g\n",+#endif+#endif+             index_v, G_FIELD, G_PRECISION, OPTIONS->Multi_Grid[index_v]);+  }+#endif /* ASA_RESOLUTION */+  fprintf (ptr_asa_out, "\n");+  fflush (ptr_asa_out);+#endif /* ASA_PRINT */+#endif /* MULTI_MIN */++#if ASA_PARALLEL+#if ASA_PRINT+  fprintf (ptr_asa_out,+#if INT_LONG+           "Initial ASA_PARALLEL OPTIONS->\n\t Gener_Block = %ld\n\+ \t Gener_Block_Max = %ld\n \t Gener_Mov_Avr= %d\n\n",+#else+           "ASA_PARALLEL OPTIONS->\n\t Gener_Block = %d\n\+ \t Gener_Block_Max = %d\n \t Gener_Mov_Avr= %d\n\n",+#endif+           OPTIONS->Gener_Block, OPTIONS->Gener_Block_Max,+           OPTIONS->Gener_Mov_Avr);+#endif+#endif /* ASA_PARALLEL */++#if ASA_SAMPLE+#if ASA_PRINT+  fprintf (ptr_asa_out, "OPTIONS->Limit_Weights = %*.*g\n\n",+           G_FIELD, G_PRECISION, OPTIONS->Limit_Weights);+#endif+#endif+  if (OPTIONS->Asa_Recursive_Level > asa_recursive_max)+    asa_recursive_max = OPTIONS->Asa_Recursive_Level;+#if ASA_SAVE+  if (OPTIONS->Asa_Recursive_Level > 0)+    sprintf (asa_save_comm, "asa_save_%d", OPTIONS->Asa_Recursive_Level);+  else+    sprintf (asa_save_comm, "asa_save");+  if ((ptr_save = fopen (asa_save_comm, "r")) == NULL) {+    asa_read = FALSE;+  } else {+#if ASA_PRINT+    fprintf (ptr_asa_out, "\n\n\trestart after ASA_SAVE\n\n");+#endif+    fclose (ptr_save);+    asa_read = TRUE;++    /* give some value to avoid any problems with other OPTIONS */+#if USER_ACCEPTANCE_TEST+    OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =+#endif+      current_generated_state->cost+      = *initial_cost_temperature = *current_cost_temperature = 3.1416;+  }+#endif++  tmp_var_int = cost_function_test (current_generated_state->cost,+                                    current_generated_state->parameter,+                                    parameter_minimum,+                                    parameter_maximum, number_parameters,+                                    xnumber_parameters);++  /* compute temperature scales */+  tmp_var_db1 = -F_LOG ((OPTIONS->Temperature_Ratio_Scale));+  tmp_var_db2 = F_LOG (OPTIONS->Temperature_Anneal_Scale);+  temperature_scale =+    tmp_var_db1 * F_EXP (-tmp_var_db2 / *xnumber_parameters);++  /* set here in case not used */+  tmp_var_db = ZERO;++#if QUENCH_PARAMETERS+#if RATIO_TEMPERATURE_SCALES+  VFOR (index_v) temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP+#if QUENCH_PARAMETERS_SCALE+    (-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])+#else+    (-(tmp_var_db2)+#endif+     / *xnumber_parameters)+    * OPTIONS->User_Temperature_Ratio[index_v];+#else+  VFOR (index_v) temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP+#if QUENCH_PARAMETERS_SCALE+    (-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])+#else+    (-(tmp_var_db2)+#endif+     / *xnumber_parameters);+#endif /* RATIO_TEMPERATURE_SCALES */+#else /* QUENCH_PARAMETERS */+#if RATIO_TEMPERATURE_SCALES+  VFOR (index_v)+    temperature_scale_parameters[index_v] =+    tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters)+    * OPTIONS->User_Temperature_Ratio[index_v];+#else+  VFOR (index_v)+    temperature_scale_parameters[index_v] =+    tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters);+#endif /* RATIO_TEMPERATURE_SCALES */+#endif /* QUENCH_PARAMETERS */++#if USER_ACCEPTANCE_TEST+  OPTIONS->Cost_Temp_Scale =+#endif+    *temperature_scale_cost =+#if QUENCH_COST+#if QUENCH_COST_SCALE+    tmp_var_db1 * F_EXP (-(tmp_var_db2 * OPTIONS->User_Quench_Cost_Scale[0])+#else+    tmp_var_db1 * F_EXP (-(tmp_var_db2)+#endif+                         / *xnumber_parameters) *+    OPTIONS->Cost_Parameter_Scale_Ratio;+#else /* QUENCH_COST */+    tmp_var_db1 * F_EXP (-(tmp_var_db2)+                         / *xnumber_parameters) *+    OPTIONS->Cost_Parameter_Scale_Ratio;+#endif /* QUENCH_COST */++  /* set the initial index of parameter generations to 1 */+  VFOR (index_v) index_parameter_generations[index_v] = 1;++  /* test user-defined options before calling cost function */+  tmp_var_int = asa_test_asa_options (seed,+                                      parameter_initial_final,+                                      parameter_minimum,+                                      parameter_maximum,+                                      tangents,+                                      curvature,+                                      number_parameters,+                                      parameter_type,+                                      valid_state_generated_flag,+                                      exit_status, ptr_asa_out, OPTIONS);+  if (tmp_var_int > 0) {+#if ASA_PRINT+    fprintf (ptr_asa_out, "total number invalid OPTIONS = %d\n", tmp_var_int);+    fflush (ptr_asa_out);+#endif+    *exit_status = INVALID_USER_INPUT;+    goto EXIT_ASA;+  }+#if USER_INITIAL_COST_TEMP+#else+#if ASA_SAVE+  if (asa_read == TRUE)+    OPTIONS->Number_Cost_Samples = 1;+#endif+  /* calculate the average cost over samplings of the cost function */+  if (OPTIONS->Number_Cost_Samples < -1) {+    tmp_var_db1 = ZERO;+    tmp_var_db2 = ZERO;+    tmp_var_int = -OPTIONS->Number_Cost_Samples;+  } else {+    tmp_var_db1 = ZERO;+    tmp_var_int = OPTIONS->Number_Cost_Samples;+  }++  OPTIONS->Locate_Cost = 0;     /* initial cost temp */++  for (index_cost_constraint = 0;+       index_cost_constraint < tmp_var_int; ++index_cost_constraint) {+    *number_invalid_generated_states = 0;+    repeated_invalid_states = 0;+    OPTIONS->Sequential_Parameters = *start_sequence - 1;+    do {+      ++(*number_invalid_generated_states);+      generate_new_state (user_random_generator,+                          seed,+                          parameter_minimum,+                          parameter_maximum, current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                          initial_user_parameter_temp,+                          temperature_scale_parameters,+#endif+                          number_parameters,+                          parameter_type,+                          current_generated_state, last_saved_state, OPTIONS);+      *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+      OPTIONS->User_Acceptance_Flag = TRUE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+      tmp_var_db =+        user_cost_function (current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum,+                            tangents,+                            curvature,+                            number_parameters,+                            parameter_type,+                            valid_state_generated_flag, exit_status, OPTIONS);+      if (cost_function_test+          (tmp_var_db, current_generated_state->parameter,+           parameter_minimum, parameter_maximum, number_parameters,+           xnumber_parameters) == 0) {+        *exit_status = INVALID_COST_FUNCTION;+        goto EXIT_ASA;+      }++      ++repeated_invalid_states;+      if (repeated_invalid_states > OPTIONS->Limit_Invalid_Generated_States) {+        *exit_status = TOO_MANY_INVALID_STATES;+        goto EXIT_ASA;+      }+    }+    while (*valid_state_generated_flag == FALSE);+    --(*number_invalid_generated_states);++    if (OPTIONS->Number_Cost_Samples < -1) {+      tmp_var_db1 += tmp_var_db;+      tmp_var_db2 += (tmp_var_db * tmp_var_db);+    } else {+      tmp_var_db1 += fabs (tmp_var_db);+    }+  }+  if (OPTIONS->Number_Cost_Samples < -1) {+    tmp_var_db1 /= (double) tmp_var_int;+    tmp_var_db2 /= (double) tmp_var_int;+    tmp_var_db = sqrt (fabs ((tmp_var_db2 - tmp_var_db1 * tmp_var_db1)+                             * ((double) tmp_var_int+                                / ((double) tmp_var_int - ONE))))+      + (double) EPS_DOUBLE;+  } else {+    tmp_var_db = tmp_var_db1 / tmp_var_int;+  }++#if USER_ACCEPTANCE_TEST+  OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =+#endif+    *initial_cost_temperature = *current_cost_temperature = tmp_var_db;+#endif /* USER_INITIAL_COST_TEMP */++  /* set all parameters to the initial parameter values */+  VFOR (index_v)+    best_generated_state->parameter[index_v] =+    last_saved_state->parameter[index_v] =+    current_generated_state->parameter[index_v] =+    parameter_initial_final[index_v];++  OPTIONS->Locate_Cost = 1;     /* initial cost value */++  /* if using user's initial parameters */+  if (OPTIONS->User_Initial_Parameters == TRUE) {+    *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+    OPTIONS->User_Acceptance_Flag = TRUE;+    OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+#if ASA_SAVE+    if (asa_read == FALSE)+#endif+      current_generated_state->cost =+        user_cost_function (current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum,+                            tangents,+                            curvature,+                            number_parameters,+                            parameter_type,+                            valid_state_generated_flag, exit_status, OPTIONS);+    if (cost_function_test+        (current_generated_state->cost, current_generated_state->parameter,+         parameter_minimum, parameter_maximum, number_parameters,+         xnumber_parameters) == 0) {+      *exit_status = INVALID_COST_FUNCTION;+      goto EXIT_ASA;+    }+#if ASA_PRINT+    if (*valid_state_generated_flag == FALSE)+      fprintf (ptr_asa_out, "user's initial parameters generated \+FALSE *valid_state_generated_flag\n");+#endif+  } else {+    /* let asa generate valid initial parameters */+    repeated_invalid_states = 0;+    OPTIONS->Sequential_Parameters = *start_sequence - 1;+    do {+      ++(*number_invalid_generated_states);+      generate_new_state (user_random_generator,+                          seed,+                          parameter_minimum,+                          parameter_maximum, current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                          initial_user_parameter_temp,+                          temperature_scale_parameters,+#endif+                          number_parameters,+                          parameter_type,+                          current_generated_state, last_saved_state, OPTIONS);+      *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+      OPTIONS->User_Acceptance_Flag = TRUE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+      current_generated_state->cost =+        user_cost_function (current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum,+                            tangents,+                            curvature,+                            number_parameters,+                            parameter_type,+                            valid_state_generated_flag, exit_status, OPTIONS);+      if (cost_function_test+          (current_generated_state->cost,+           current_generated_state->parameter, parameter_minimum,+           parameter_maximum, number_parameters, xnumber_parameters) == 0) {+        *exit_status = INVALID_COST_FUNCTION;+        goto EXIT_ASA;+      }+      ++repeated_invalid_states;+      if (repeated_invalid_states > OPTIONS->Limit_Invalid_Generated_States) {+        *exit_status = TOO_MANY_INVALID_STATES;+        goto EXIT_ASA;+      }+    }+    while (*valid_state_generated_flag == FALSE);+    --(*number_invalid_generated_states);+  }                             /* OPTIONS->User_Initial_Parameters */++  /* set all states to the last one generated */+  VFOR (index_v) {+#if DROPPED_PARAMETERS+    /* ignore parameters that have too small a range */+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+#endif+    best_generated_state->parameter[index_v] =+      last_saved_state->parameter[index_v] =+      current_generated_state->parameter[index_v];+  }++  /* set all costs to the last one generated */+  best_generated_state->cost = last_saved_state->cost =+    current_generated_state->cost;++  *accepted_to_generated_ratio = ONE;++  /* do not calculate curvatures initially */+  *curvature_flag = FALSE;++#if ASA_PRINT+  fprintf (ptr_asa_out,+           "temperature_scale = %*.*g\n",+           G_FIELD, G_PRECISION, temperature_scale);+#if RATIO_TEMPERATURE_SCALES+#if ASA_PRINT_INTERMED+  VFOR (index_v) {+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "temperature_scale_parameters[%d] = %*.*g\n",+#else+#if INT_LONG+             "temperature_scale_parameters[%ld] = %*.*g\n",+#else+             "temperature_scale_parameters[%d] = %*.*g\n",+#endif+#endif+             index_v,+             G_FIELD, G_PRECISION, temperature_scale_parameters[index_v]);+  }+#endif+#else+  fprintf (ptr_asa_out,+           "temperature_scale_parameters[0] = %*.*g\n",+           G_FIELD, G_PRECISION, temperature_scale_parameters[0]);+#endif /* RATIO_TEMPERATURE_SCALES */+  fprintf (ptr_asa_out,+           "*temperature_scale_cost = %*.*g\n",+           G_FIELD, G_PRECISION, *temperature_scale_cost);+  fprintf (ptr_asa_out, "\n\n");++#if ASA_PRINT_INTERMED+  print_state (parameter_minimum,+               parameter_maximum,+               tangents,+               curvature,+               current_cost_temperature,+               current_user_parameter_temp,+               accepted_to_generated_ratio,+               number_parameters,+               curvature_flag,+               number_accepted,+               index_cost_acceptances,+               number_generated,+               number_invalid_generated_states,+               last_saved_state, best_generated_state, ptr_asa_out, OPTIONS);+#endif+  fprintf (ptr_asa_out, "\n");++  fflush (ptr_asa_out);+#endif++#if ASA_SAMPLE+#if ASA_PRINT+  fprintf (ptr_asa_out,+           ":SAMPLE:   n_accept   cost        cost_temp    bias_accept    \+ aver_weight\n");+  fprintf (ptr_asa_out,+           ":SAMPLE:   index      param[]     temp[]       bias_gener[]   \+ range[]\n");+#endif+#endif++  /* reset the current cost and the number of generations performed */+  *number_invalid_generated_states = 0;+  *best_number_generated_saved =+    *number_generated = *recent_number_generated = 0;+  OPTIONS->N_Generated = *number_generated;+  VFOR (index_v) {+    /* ignore parameters that have too small a range */+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    index_parameter_generations[index_v] = 1;+  }+#if USER_ACCEPTANCE_TEST+  OPTIONS->User_Acceptance_Flag = FALSE;+  OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif++#if ASA_QUEUE+#if ASA_PRINT+#if INT_ALLOC+  fprintf (ptr_asa_out, "OPTIONS->Queue_Size = %d\n", OPTIONS->Queue_Size);+#else+#if INT_LONG+  fprintf (ptr_asa_out, "OPTIONS->Queue_Size = %ld\n", OPTIONS->Queue_Size);+#else+  fprintf (ptr_asa_out, "OPTIONS->Queue_Size = %d\n", OPTIONS->Queue_Size);+#endif+#endif+  VFOR (index_v) {+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "Queue_Resolution[%d] = %*.*g\n",+#else+#if INT_LONG+             "Queue_Resolution[%ld] = %*.*g\n",+#else+             "Queue_Resolution[%d] = %*.*g\n",+#endif+#endif+             index_v,+             G_FIELD, G_PRECISION, OPTIONS->Queue_Resolution[index_v]);+  }+#endif /* ASA_PRINT */++  /* fill arrays to check allocated memory */+  for (queue = 0; queue < queue_size_tmp; ++queue) {+    VFOR (index_v) {+      if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+        continue;+      }+      queue_v = index_v + queue * (LONG_INT) (*number_parameters);+      save_queue_param[queue_v] = current_generated_state->parameter[index_v];+    }+    save_queue_cost[queue] = current_generated_state->cost;+    save_queue_flag[queue] = *valid_state_generated_flag;+  }+  save_queue = save_queue_indx = 0;+#endif /* ASA_QUEUE */++#if ASA_RESOLUTION+#if ASA_PRINT+  VFOR (index_v) {+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "Coarse_Resolution[%d] = %*.*g\n",+#else+#if INT_LONG+             "Coarse_Resolution[%ld] = %*.*g\n",+#else+             "Coarse_Resolution[%d] = %*.*g\n",+#endif+#endif+             index_v,+             G_FIELD, G_PRECISION, OPTIONS->Coarse_Resolution[index_v]);+  }+#endif /* ASA_PRINT */+#endif /* ASA_RESOLUTION */++#if MULTI_MIN+  multi_sort[OPTIONS->Multi_Number] = OPTIONS->Multi_Number;+  multi_cost[OPTIONS->Multi_Number] = current_generated_state->cost;+  VFOR (index_v) {+    multi_params[OPTIONS->Multi_Number][index_v] =+      current_generated_state->parameter[index_v];+  }+  for (multi_index = 0; multi_index < OPTIONS->Multi_Number; ++multi_index) {+    multi_sort[multi_index] = multi_index;+    multi_cost[multi_index] = OPTIONS->Multi_Cost[multi_index] =+      current_generated_state->cost;+    VFOR (index_v) {+      multi_params[multi_index][index_v] =+        OPTIONS->Multi_Params[multi_index][index_v] =+        current_generated_state->parameter[index_v];+    }+  }+#endif /* MULTI_MIN */++  OPTIONS->Sequential_Parameters = *start_sequence - 1;++  /* MAIN ANNEALING LOOP */+  while (((*number_accepted <= OPTIONS->Limit_Acceptances)+          || (OPTIONS->Limit_Acceptances == 0))+         && ((*number_generated <= OPTIONS->Limit_Generated)+             || (OPTIONS->Limit_Generated == 0))) {++    tmp_var_db1 = -F_LOG ((OPTIONS->Temperature_Ratio_Scale));++    /* compute temperature scales */+    tmp_var_db2 = F_LOG (OPTIONS->Temperature_Anneal_Scale);+    temperature_scale = tmp_var_db1 *+      F_EXP (-tmp_var_db2 / *xnumber_parameters);++#if QUENCH_PARAMETERS+#if RATIO_TEMPERATURE_SCALES+    VFOR (index_v)+      temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP+#if QUENCH_PARAMETERS_SCALE+      (-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])+#else+      (-(tmp_var_db2)+#endif+       / *xnumber_parameters)+      * OPTIONS->User_Temperature_Ratio[index_v];+#else+    VFOR (index_v)+      temperature_scale_parameters[index_v] = tmp_var_db1 * F_EXP+#if QUENCH_PARAMETERS_SCALE+      (-(tmp_var_db2 * OPTIONS->User_Quench_Param_Scale[index_v])+#else+      (-(tmp_var_db2)+#endif+       / *xnumber_parameters);+#endif /* RATIO_TEMPERATURE_SCALES */+#else /* QUENCH_PARAMETERS */+#if RATIO_TEMPERATURE_SCALES+    VFOR (index_v)+      temperature_scale_parameters[index_v] =+      tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters)+      * OPTIONS->User_Temperature_Ratio[index_v];+#else+    VFOR (index_v)+      temperature_scale_parameters[index_v] =+      tmp_var_db1 * F_EXP (-(tmp_var_db2) / *xnumber_parameters);+#endif /* RATIO_TEMPERATURE_SCALES */+#endif /* QUENCH_PARAMETERS */++#if USER_ACCEPTANCE_TEST+    OPTIONS->Cost_Temp_Scale =+#endif+      *temperature_scale_cost =+#if QUENCH_COST+#if QUENCH_COST_SCALE+      tmp_var_db1 * F_EXP (-(tmp_var_db2 * OPTIONS->User_Quench_Cost_Scale[0])+#else+      tmp_var_db1 * F_EXP (-(tmp_var_db2)+#endif+                           / *xnumber_parameters) *+      OPTIONS->Cost_Parameter_Scale_Ratio;+#else /* QUENCH_COST */+      tmp_var_db1 * F_EXP (-(tmp_var_db2)+                           / *xnumber_parameters) *+      OPTIONS->Cost_Parameter_Scale_Ratio;+#endif /* QUENCH_COST */++    /* CALCULATE NEW TEMPERATURES */++    /* calculate new parameter temperatures */+    VFOR (index_v) {+      /* skip parameters with too small a range */+      if (PARAMETER_RANGE_TOO_SMALL (index_v))+        continue;++      log_new_temperature_ratio =+        -temperature_scale_parameters[index_v] *+        F_POW ((double) index_parameter_generations[index_v],+#if QUENCH_PARAMETERS+               OPTIONS->User_Quench_Param_Scale[index_v]+#else /* QUENCH_PARAMETERS */+               ONE+#endif /* QUENCH_PARAMETERS */+               / *xnumber_parameters);+      /* check (and correct) for too large an exponent */+      log_new_temperature_ratio = EXPONENT_CHECK (log_new_temperature_ratio);+      current_user_parameter_temp[index_v] =+        initial_user_parameter_temp[index_v]+        * F_EXP (log_new_temperature_ratio);++#if NO_PARAM_TEMP_TEST+      if (current_user_parameter_temp[index_v] < (double) EPS_DOUBLE)+        current_user_parameter_temp[index_v] = (double) EPS_DOUBLE;+#else+      /* check for too small a parameter temperature */+      if (current_user_parameter_temp[index_v] < (double) EPS_DOUBLE) {+        *exit_status = P_TEMP_TOO_SMALL;+        *index_exit_v = index_v;+        goto EXIT_ASA;+      }+#endif+    }++    /* calculate new cost temperature */+    log_new_temperature_ratio =+      -*temperature_scale_cost * F_POW ((double) *index_cost_acceptances,+#if QUENCH_COST+                                        OPTIONS->User_Quench_Cost_Scale[0]+#else+                                        ONE+#endif+                                        / *xnumber_parameters);+    log_new_temperature_ratio = EXPONENT_CHECK (log_new_temperature_ratio);+#if USER_ACCEPTANCE_TEST+    OPTIONS->Cost_Temp_Curr = OPTIONS->Cost_Temp_Init =+#endif+      *current_cost_temperature = *initial_cost_temperature+      * F_EXP (log_new_temperature_ratio);++#if NO_COST_TEMP_TEST+    if (*current_cost_temperature < (double) EPS_DOUBLE)+#if USER_ACCEPTANCE_TEST+      OPTIONS->Cost_Temp_Curr =+#endif+        *current_cost_temperature = (double) EPS_DOUBLE;+#else+    /* check for too small a cost temperature */+    if (*current_cost_temperature < (double) EPS_DOUBLE) {+      *exit_status = C_TEMP_TOO_SMALL;+      goto EXIT_ASA;+    }+#endif++#if ASA_SAVE+    if (asa_read == TRUE && OPTIONS->Asa_Recursive_Level == asa_recursive_max) {+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "asa_save_%d", OPTIONS->Asa_Recursive_Level);+      else+        sprintf (asa_save_comm, "asa_save");+      ptr_save = fopen (asa_save_comm, "r");++      fread (number_parameters, sizeof (ALLOC_INT), 1, ptr_save);+      fread (xnumber_parameters, sizeof (double), 1, ptr_save);+      fread (parameter_minimum, sizeof (double),+             *number_parameters, ptr_save);+      fread (parameter_maximum, sizeof (double),+             *number_parameters, ptr_save);+      fread (tangents, sizeof (double), *number_parameters, ptr_save);+      fread (current_user_parameter_temp, sizeof (double),+             *number_parameters, ptr_save);+      fread (initial_user_parameter_temp, sizeof (double),+             *number_parameters, ptr_save);+      fread (temperature_scale_parameters, sizeof (double),+             *number_parameters, ptr_save);++      fread (parameter_type, sizeof (int), *number_parameters, ptr_save);+      fread (&index_cost_repeat, sizeof (int), 1, ptr_save);+      fread (&asa_open, sizeof (int), 1, ptr_save);+      fread (&number_asa_open, sizeof (int), 1, ptr_save);+      fread (&recursive_asa_open, sizeof (int), 1, ptr_save);++      fread (current_cost_temperature, sizeof (double), 1, ptr_save);+      fread (initial_cost_temperature, sizeof (double), 1, ptr_save);+      fread (temperature_scale_cost, sizeof (double), 1, ptr_save);+      fread (accepted_to_generated_ratio, sizeof (double), 1, ptr_save);++      fread (curvature_flag, sizeof (int), 1, ptr_save);++      fread (seed, sizeof (LONG_INT), 1, ptr_save);+      fread (number_generated, sizeof (LONG_INT), 1, ptr_save);+      fread (number_accepted, sizeof (LONG_INT), 1, ptr_save);+      fread (number_acceptances_saved, sizeof (LONG_INT), 1, ptr_save);+      fread (recent_number_acceptances, sizeof (LONG_INT), 1, ptr_save);+      fread (recent_number_generated, sizeof (LONG_INT), 1, ptr_save);+      fread (number_invalid_generated_states, sizeof (LONG_INT), 1, ptr_save);+      fread (index_cost_acceptances, sizeof (LONG_INT), 1, ptr_save);+      fread (best_number_generated_saved, sizeof (LONG_INT), 1, ptr_save);+      fread (best_number_accepted_saved, sizeof (LONG_INT), 1, ptr_save);++      fread (index_parameter_generations, sizeof (LONG_INT),+             *number_parameters, ptr_save);++      fread (current_generated_state->parameter,+             sizeof (double), *number_parameters, ptr_save);+      fread (last_saved_state->parameter,+             sizeof (double), *number_parameters, ptr_save);+      fread (best_generated_state->parameter,+             sizeof (double), *number_parameters, ptr_save);+      fread (&(current_generated_state->cost), sizeof (double), 1, ptr_save);+      fread (&(last_saved_state->cost), sizeof (double), 1, ptr_save);+      fread (&(best_generated_state->cost), sizeof (double), 1, ptr_save);++      fread (&(OPTIONS->Limit_Acceptances), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Limit_Generated), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Limit_Invalid_Generated_States), sizeof (int),+             1, ptr_save);+      fread (&(OPTIONS->Accepted_To_Generated_Ratio), sizeof (double),+             1, ptr_save);+      fread (&(OPTIONS->Cost_Precision), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->Maximum_Cost_Repeat), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Number_Cost_Samples), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Temperature_Ratio_Scale), sizeof (double),+             1, ptr_save);+      fread (&(OPTIONS->Cost_Parameter_Scale_Ratio), sizeof (double),+             1, ptr_save);+      fread (&(OPTIONS->Temperature_Anneal_Scale), sizeof (double),+             1, ptr_save);+      fread (&(OPTIONS->Include_Integer_Parameters), sizeof (int),+             1, ptr_save);+      fread (&(OPTIONS->User_Initial_Parameters), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Sequential_Parameters), sizeof (ALLOC_INT), 1,+             ptr_save);+      fread (&(OPTIONS->Initial_Parameter_Temperature), sizeof (double), 1,+             ptr_save);+      fread (&(OPTIONS->Acceptance_Frequency_Modulus), sizeof (int), 1,+             ptr_save);+      fread (&(OPTIONS->Generated_Frequency_Modulus), sizeof (int), 1,+             ptr_save);+      fread (&(OPTIONS->Reanneal_Cost), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Reanneal_Parameters), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Delta_X), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->User_Tangents), sizeof (int), 1, ptr_save);++#if USER_INITIAL_COST_TEMP+      fread (&(OPTIONS->User_Cost_Temperature), sizeof (double), 1, ptr_save);+#endif+#if RATIO_TEMPERATURE_SCALES+      fread (OPTIONS->User_Temperature_Ratio, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if USER_INITIAL_PARAMETERS_TEMPS+      fread (OPTIONS->User_Parameter_Temperature, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if DELTA_PARAMETERS+      fread (OPTIONS->User_Delta_Parameter, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if QUENCH_PARAMETERS+      fread (OPTIONS->User_Quench_Param_Scale, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if QUENCH_COST+      fread (OPTIONS->User_Quench_Cost_Scale, sizeof (double), 1, ptr_save);+#endif+      fread (&(OPTIONS->N_Accepted), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->N_Generated), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Locate_Cost), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Immediate_Exit), sizeof (int), 1, ptr_save);+#if OPTIONAL_DATA_DBL+      fread (&(OPTIONS->Asa_Data_Dim_Dbl), sizeof (ALLOC_INT), 1, ptr_save);+      fread (OPTIONS->Asa_Data_Dbl, sizeof (double),+             OPTIONS->Asa_Data_Dim_Dbl, ptr_save);+#endif+      fread (&(OPTIONS->Random_Array_Dim), sizeof (ALLOC_INT), 1, ptr_save);+      fread (OPTIONS->Random_Array, sizeof (double),+             OPTIONS->Random_Array_Dim, ptr_save);+      fread (&(OPTIONS->Asa_Recursive_Level), sizeof (int), 1, ptr_save);+#if OPTIONAL_DATA_INT+      fread (&(OPTIONS->Asa_Data_Dim_Int), sizeof (ALLOC_INT), 1, ptr_save);+      fread (OPTIONS->Asa_Data_Int, sizeof (LONG_INT),+             OPTIONS->Asa_Data_Dim_Int, ptr_save);+#endif+#if OPTIONAL_DATA_PTR+      fread (&(OPTIONS->Asa_Data_Dim_Ptr), sizeof (ALLOC_INT), 1, ptr_save);+      if (OPTIONS->Asa_Recursive_Level == 0)+        fread (OPTIONS->Asa_Data_Ptr, sizeof (OPTIONAL_PTR_TYPE),+               OPTIONS->Asa_Data_Dim_Ptr, ptr_save);+#if ASA_TEMPLATE_SELFOPT+      if (OPTIONS->Asa_Recursive_Level == 1)+        fread (OPTIONS->Asa_Data_Ptr, sizeof (RECUR_OPTIONAL_PTR_TYPE),+               OPTIONS->Asa_Data_Dim_Ptr, ptr_save);+#endif+#endif+#if USER_ASA_OUT+      fread (OPTIONS->Asa_Out_File, sizeof (char), 1, ptr_save);+#endif+#if USER_COST_SCHEDULE+      fread (&(OPTIONS->Cost_Schedule), sizeof (char), 1, ptr_save);+#endif+#if USER_ACCEPT_ASYMP_EXP+      fread (&(OPTIONS->Asymp_Exp_Param), sizeof (double), 1, ptr_save);+#endif+#if USER_ACCEPTANCE_TEST+      fread (&(OPTIONS->Acceptance_Test), sizeof (char), 1, ptr_save);+      fread (&(OPTIONS->User_Acceptance_Flag), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Cost_Acceptance_Flag), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Cost_Temp_Curr), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->Cost_Temp_Init), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->Cost_Temp_Scale), sizeof (double), 1, ptr_save);+#endif+#if USER_GENERATING_FUNCTION+      fread (&(OPTIONS->Generating_Distrib), sizeof (char), 1, ptr_save);+#endif+#if USER_REANNEAL_COST+      fread (&(OPTIONS->Reanneal_Cost_Function), sizeof (char), 1, ptr_save);+#endif+#if USER_REANNEAL_PARAMETERS+      fread (&(OPTIONS->Reanneal_Params_Function), sizeof (char),+             1, ptr_save);+#endif+#if ASA_SAMPLE+      fread (&(OPTIONS->Bias_Acceptance), sizeof (double), 1, ptr_save);+      fread (OPTIONS->Bias_Generated, sizeof (double),+             *number_parameters, ptr_save);+      fread (&(OPTIONS->Average_Weights), sizeof (double), 1, ptr_save);+      fread (&(OPTIONS->Limit_Weights), sizeof (double), 1, ptr_save);+#endif+#if ASA_QUEUE+      fread (save_queue, sizeof (LONG_INT), 1, ptr_save);+      fread (save_queue_indx, sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Queue_Size), sizeof (ALLOC_INT), 1, ptr_save);+      fread (save_queue_flag, sizeof (int), save_queue, ptr_save);+      fread (save_queue_cost, sizeof (double), save_queue, ptr_save);+      fread (save_queue_param, sizeof (double),+             (*number_parameters) * (OPTIONS->Queue_Size), ptr_save);+#if ASA_RESOLUTION+#else+      fread (OPTIONS->Queue_Resolution, sizeof (double),+             *number_parameters, ptr_save);+#endif+#endif+#if ASA_RESOLUTION+      fread (OPTIONS->Coarse_Resolution, sizeof (double),+             *number_parameters, ptr_save);+#endif+#if FITLOC+      fread (&(OPTIONS->Fit_Local), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Iter_Max), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Penalty), sizeof (double), 1, ptr_save);+#endif+#if MULTI_MIN+      fread (OPTIONS->Multi_Number, sizeof (int), 1, ptr_save);+      fread (OPTIONS->Multi_Grid,+             sizeof (double), *number_parameters, ptr_save);+      fread (&(OPTIONS->Multi_Specify), sizeof (int), 1, ptr_save);+      for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+           ++multi_index) {+        fread (&(OPTIONS->Multi_Cost[multi_index]), sizeof (double), 1,+               ptr_save);+        fread (&(OPTIONS->Multi_Params[multi_index]), sizeof (double),+               *number_parameters, ptr_save);+      }+#endif+#if ASA_PARALLEL+      fread (&parallel_generated, sizeof (LONG_INT), 1, ptr_save);+      fread (&parallel_block_max, sizeof (LONG_INT), 1, ptr_save);+      for (index_parallel = 0; index_parallel < parallel_block_max;+           ++index_parallel) {+        fread (gener_block_state[index_parallel].parameter,+               sizeof (double), *number_parameters, ptr_save);+        fread (&(gener_block_state[index_parallel].cost),+               sizeof (double), 1, ptr_save);+#if USER_ACCEPTANCE_TEST+        fread (&+               (gener_block_state[index_parallel].par_user_accept_flag),+               sizeof (int), 1, ptr_save);+        fread (&+               (gener_block_state[index_parallel].par_cost_accept_flag),+               sizeof (int), 1, ptr_save);+#endif+      }+      fread (&(OPTIONS->Gener_Mov_Avr), sizeof (int), 1, ptr_save);+      fread (&(OPTIONS->Gener_Block), sizeof (LONG_INT), 1, ptr_save);+      fread (&(OPTIONS->Gener_Block_Max), sizeof (LONG_INT), 1, ptr_save);+#endif++      fclose (ptr_save);++      asa_read = FALSE;+#if ASA_PRINT+      print_state (parameter_minimum,+                   parameter_maximum,+                   tangents,+                   curvature,+                   current_cost_temperature,+                   current_user_parameter_temp,+                   accepted_to_generated_ratio,+                   number_parameters,+                   curvature_flag,+                   number_accepted,+                   index_cost_acceptances,+                   number_generated,+                   number_invalid_generated_states,+                   last_saved_state,+                   best_generated_state, ptr_asa_out, OPTIONS);+#endif /* ASA_PRINT */++#include "asa_opt"+#if ASA_SAVE_OPT+      if ((ptr_save_opt = fopen ("asa_save_opt", "r")) == NULL) {+#if INCL_STDOUT+        printf ("\n\n*** WARNING fopen asa_save_opt failed *** \n\n");+#endif /* INCL_STDOUT */+#if ASA_PRINT+        fprintf (ptr_asa_out,+                 "\n\n*** WARNING fopen asa_save_opt failed *** \n\n");+        fflush (ptr_asa_out);+#endif+      } else {+        fscanf (ptr_save_opt, "%s%s%s%s%s",+                read_if, read_FALSE, read_comm1, read_ASA_SAVE, read_comm2);+        if (strcmp (read_if, "#if") || strcmp (read_FALSE, "FALSE")+            || strcmp (read_comm1, "/*")+            || strcmp (read_ASA_SAVE, "ASA_SAVE")+            || strcmp (read_comm2, "*/")) {+#if INCL_STDOUT+          printf ("\n\n*** EXIT not asa_save_opt for this version *** \n\n");+#endif /* INCL_STDOUT */+#if ASA_PRINT+          fprintf (ptr_asa_out,+                   "\n\n*** not asa_save_opt for this version *** \n\n");+          fflush (ptr_asa_out);+#endif+          *exit_status = INVALID_USER_INPUT;+          goto EXIT_ASA;+        }+#if INT_LONG+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%ld", &read_long);+        OPTIONS->Limit_Acceptances = read_long;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%ld", &read_long);+        OPTIONS->Limit_Generated = read_long;+#else+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Limit_Acceptances = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Limit_Generated = read_int;+#endif+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Limit_Invalid_Generated_States = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Accepted_To_Generated_Ratio = read_double;++        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Cost_Precision = read_double;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Maximum_Cost_Repeat = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Number_Cost_Samples = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Temperature_Ratio_Scale = read_double;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Cost_Parameter_Scale_Ratio = read_double;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Temperature_Anneal_Scale = read_double;++        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Include_Integer_Parameters = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->User_Initial_Parameters = read_int;+#if INT_ALLOC+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Sequential_Parameters = read_int;+#else+#if INT_LONG+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%ld", &read_long);+        OPTIONS->Sequential_Parameters = read_long;+#else+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Sequential_Parameters = read_int;+#endif+#endif+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Initial_Parameter_Temperature = read_double;++        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Acceptance_Frequency_Modulus = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Generated_Frequency_Modulus = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Reanneal_Cost = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Reanneal_Parameters = read_int;++        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%lf", &read_double);+        OPTIONS->Delta_X = read_double;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->User_Tangents = read_int;+        fscanf (ptr_save_opt, "%s", read_option);+        fscanf (ptr_save_opt, "%d", &read_int);+        OPTIONS->Curvature_0 = read_int;++        fclose (ptr_save_opt);+      }+#endif /* ASA_SAVE_OPT */++      goto SAVED_ASA;+    }+#endif /* ASA_SAVE */++    /* GENERATE NEW PARAMETERS */++    /* generate a new valid set of parameters */+#if ASA_PARALLEL+    /* *** ENTER CODE TO SPAWN OFF PARALLEL GENERATED STATES *** */++    /* check if need more memory allocated to gener_block_state */+    if (OPTIONS->Gener_Block_Max > parallel_block_max) {+      for (index_parallel = 0; index_parallel < parallel_block_max;+           ++index_parallel) {+        free (gener_block_state[index_parallel].parameter);+      }+      free (gener_block_state);++      if ((gener_block_state =+           (STATE *) calloc (OPTIONS->Gener_Block_Max,+                             sizeof (STATE))) == NULL) {+        strcpy (exit_msg, "asa(): gener_block_state");+        Exit_ASA (exit_msg);+        *exit_status = CALLOC_FAILED;+        return (-1);+      }++      parallel_block_max = OPTIONS->Gener_Block_Max;++      for (index_parallel = 0; index_parallel < parallel_block_max;+           ++index_parallel) {+        if ((gener_block_state[index_parallel].parameter =+             (double *) calloc (*number_parameters,+                                sizeof (double))) == NULL) {+          strcpy (exit_msg,+                  "asa(): gener_block_state[index_parallel].parameter");+          Exit_ASA (exit_msg);+          *exit_status = CALLOC_FAILED;+          return (-1);+        }+      }+    }+#if ASA_TEMPLATE_PARALLEL+    for (index_parallel = 0; index_parallel < OPTIONS->Gener_Block;+         ++index_parallel) {+#endif /* ASA_TEMPLATE_PARALLEL */+#endif /* ASA_PARALLEL */++      if (OPTIONS->Locate_Cost < 0) {+        OPTIONS->Locate_Cost = 12;      /* generate new state from new best */+      } else {+        OPTIONS->Locate_Cost = 2;       /* generate new state */+      }++      repeated_invalid_states = 0;+      do {+        ++(*number_invalid_generated_states);+        generate_new_state (user_random_generator,+                            seed,+                            parameter_minimum,+                            parameter_maximum, current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                            initial_user_parameter_temp,+                            temperature_scale_parameters,+#endif+                            number_parameters,+                            parameter_type,+                            current_generated_state,+                            last_saved_state, OPTIONS);++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = FALSE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+#if ASA_QUEUE+        /* Binary trees do not seem necessary since we are assuming+           that the cost function calculation is the bottleneck.+           However, see the MISC.DIR/asa_contrib file for+           source code for doubly-linked and hashed lists. */+        if (OPTIONS->Queue_Size == 0) {+          queue_new = 1;+        } else {+          queue_new = 1;+          for (queue = 0; queue < save_queue; ++queue) {+            save_queue_test = 0;+            VFOR (index_v) {+              if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+                ++save_queue_test;+              } else {+                queue_v = index_v + queue * (LONG_INT) (*number_parameters);+                if (fabs+                    (current_generated_state->parameter[index_v] -+                     save_queue_param[queue_v]) <=+                    (OPTIONS->Queue_Resolution[index_v] + EPS_DOUBLE)) {+                  ++save_queue_test;+                }+              }+            }+            if (save_queue_test == *number_parameters) {+              tmp_var_db = save_queue_cost[queue];+              *valid_state_generated_flag = save_queue_flag[queue];+              queue_new = 0;+              --(*number_generated);+#if ASA_PRINT_MORE+#if INT_LONG+              fprintf (ptr_asa_out, "ASA_QUEUE: %ld \t %*.*g\n",+                       OPTIONS->N_Generated,+                       G_FIELD, G_PRECISION, tmp_var_db);+#else+              fprintf (ptr_asa_out, "ASA_QUEUE: %d \t %*.*g\n",+                       OPTIONS->N_Generated,+                       G_FIELD, G_PRECISION, tmp_var_db);+#endif+#endif+              break;+            }+          }+        }+        if (queue_new == 1) {+          tmp_var_db =+            user_cost_function (current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum,+                                tangents,+                                curvature,+                                number_parameters,+                                parameter_type,+                                valid_state_generated_flag,+                                exit_status, OPTIONS);+          if (cost_function_test (tmp_var_db,+                                  current_generated_state->parameter,+                                  parameter_minimum,+                                  parameter_maximum,+                                  number_parameters,+                                  xnumber_parameters) == 0) {+            *exit_status = INVALID_COST_FUNCTION;+            goto EXIT_ASA;+          }+          if (OPTIONS->Queue_Size > 0) {        /* in case recursive use */+            VFOR (index_v) {+              if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+                continue;+              }+              queue_v = index_v + save_queue_indx+                * (LONG_INT) (*number_parameters);+              save_queue_param[queue_v] =+                current_generated_state->parameter[index_v];+            }+            save_queue_cost[save_queue_indx] = tmp_var_db;+            save_queue_flag[save_queue_indx]+              = *valid_state_generated_flag;++            ++save_queue;+            if (save_queue == (LONG_INT) OPTIONS->Queue_Size)+              --save_queue;++            ++save_queue_indx;+            if (save_queue_indx == (LONG_INT) OPTIONS->Queue_Size)+              save_queue_indx = 0;+          }+        }+#else /* ASA_QUEUE */+        tmp_var_db =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (tmp_var_db,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION;+          goto EXIT_ASA;+        }+#endif /* ASA_QUEUE */+        current_generated_state->cost = tmp_var_db;+        ++repeated_invalid_states;+        if (repeated_invalid_states > OPTIONS->Limit_Invalid_Generated_States) {+          *exit_status = TOO_MANY_INVALID_STATES;+          goto EXIT_ASA;+        }+      }+      while (*valid_state_generated_flag == FALSE);+      --(*number_invalid_generated_states);+#if ASA_PARALLEL+      gener_block_state[index_parallel].cost = current_generated_state->cost;+#if USER_ACCEPTANCE_TEST+      gener_block_state[index_parallel].par_user_accept_flag =+        OPTIONS->User_Acceptance_Flag;+      gener_block_state[index_parallel].par_cost_accept_flag =+        OPTIONS->Cost_Acceptance_Flag;+#endif+      VFOR (index_v) {+        /* ignore parameters with too small a range */+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+        gener_block_state[index_parallel].parameter[index_v] =+          current_generated_state->parameter[index_v];+      }+#if ASA_TEMPLATE_PARALLEL+    }+#endif /* ASA_TEMPLATE_PARALLEL */+    /* *** EXIT CODE SPAWNING OFF PARALLEL GENERATED STATES *** */+#endif /* ASA_PARALLEL */++    /* ACCEPT/REJECT NEW PARAMETERS */++#if ASA_PARALLEL+    for (sort_index = 0; sort_index < OPTIONS->Gener_Block; ++sort_index)+      parallel_sort[sort_index] = sort_index;+    qsort (parallel_sort, OPTIONS->Gener_Block, sizeof (LONG_INT),+           sort_parallel);++    for (sort_index = 0; sort_index < OPTIONS->Gener_Block; ++sort_index) {+      index_parallel = parallel_sort[sort_index];+      current_generated_state->cost = gener_block_state[index_parallel].cost;+#if USER_ACCEPTANCE_TEST+      OPTIONS->User_Acceptance_Flag =+        gener_block_state[index_parallel].par_user_accept_flag;+      OPTIONS->Cost_Acceptance_Flag =+        gener_block_state[index_parallel].par_cost_accept_flag;+#endif+      VFOR (index_v) {+        /* ignore parameters with too small a range */+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+        current_generated_state->parameter[index_v] =+          gener_block_state[index_parallel].parameter[index_v];+      }+#endif /* ASA_PARALLEL */+      /* decide to accept/reject the new state */+      accept_new_state (user_random_generator,+                        seed,+                        parameter_minimum,+                        parameter_maximum, current_cost_temperature,+#if ASA_SAMPLE+                        current_user_parameter_temp,+#endif+                        number_parameters,+                        recent_number_acceptances,+                        number_accepted,+                        index_cost_acceptances,+                        number_acceptances_saved,+                        recent_number_generated,+                        number_generated,+                        index_parameter_generations,+                        current_generated_state, last_saved_state,+#if ASA_SAMPLE+                        ptr_asa_out,+#endif+                        OPTIONS);++#if ASA_PARALLEL+#else+#if ASA_PIPE_FILE+#if INT_ALLOC+      fprintf (ptr_asa_pipe, "%d", *number_generated);+#else+#if INT_LONG+      fprintf (ptr_asa_pipe, "%ld", *number_generated);+#else+      fprintf (ptr_asa_pipe, "%d", *number_generated);+#endif+#endif+#if INT_ALLOC+      fprintf (ptr_asa_pipe, "\t%d", *number_accepted);+#else+#if INT_LONG+      fprintf (ptr_asa_pipe, "\t%ld", *number_accepted);+#else+      fprintf (ptr_asa_pipe, "\t%d", *number_accepted);+#endif+#endif+      fprintf (ptr_asa_pipe, "\t%g", best_generated_state->cost);+      VFOR (index_v)+        fprintf (ptr_asa_pipe, "\t%g",+                 best_generated_state->parameter[index_v]);+      fprintf (ptr_asa_pipe, "\t%g", *current_cost_temperature);+      VFOR (index_v)+        fprintf (ptr_asa_pipe, "\t%g", current_user_parameter_temp[index_v]);+      fprintf (ptr_asa_pipe, "\t%g", last_saved_state->cost);+      fprintf (ptr_asa_pipe, "\n");+      fflush (ptr_asa_pipe);+#endif /* ASA_PIPE_FILE */+#if INCL_STDOUT+#if ASA_PIPE+#if INT_ALLOC+      printf ("%d", *number_generated);+#else+#if INT_LONG+      printf ("%ld", *number_generated);+#else+      printf ("%d", *number_generated);+#endif+#endif+#if INT_ALLOC+      printf ("\t%d", *number_accepted);+#else+#if INT_LONG+      printf ("\t%ld", *number_accepted);+#else+      printf ("\t%d", *number_accepted);+#endif+#endif+      printf ("\t%g", best_generated_state->cost);+      VFOR (index_v)+        printf ("\t%g", best_generated_state->parameter[index_v]);+      printf ("\t%g", *current_cost_temperature);+      VFOR (index_v)+        printf ("\t%g", current_user_parameter_temp[index_v]);+      printf ("\n");+#endif /* ASA_PIPE */+#endif /* INCL_STDOUT */+#endif /* ASA_PARALLEL */++      /* calculate the ratio of acceptances to generated states */+      *accepted_to_generated_ratio =+        (double) (*recent_number_acceptances + 1) /+        (double) (*recent_number_generated + 1);++#if MULTI_MIN+      if (((OPTIONS->Multi_Specify == 0)+           && (current_generated_state->cost <= best_generated_state->cost))+          || ((OPTIONS->Multi_Specify == 1)+              && (current_generated_state->cost <+                  best_generated_state->cost))) {+#if ASA_RESOLUTION+        VFOR (index_v) {+          if (OPTIONS->Multi_Grid[index_v] <+              OPTIONS->Coarse_Resolution[index_v])+            OPTIONS->Multi_Grid[index_v] =+              OPTIONS->Coarse_Resolution[index_v];+        }+#endif /* ASA_RESOLUTION */+        VFOR (index_v) {+          if (OPTIONS->Multi_Grid[index_v] < EPS_DOUBLE)+            OPTIONS->Multi_Grid[index_v] = EPS_DOUBLE;+        }++        multi_test = 0;+        for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+             ++multi_index) {+          multi_test_cmp = 0;+          multi_test_dim = 0;+          VFOR (index_v) {+            if (PARAMETER_RANGE_TOO_SMALL (index_v))+              continue;+            ++multi_test_dim;+            if (fabs (current_generated_state->parameter[index_v]+                      - OPTIONS->Multi_Params[multi_index][index_v])+                < OPTIONS->Multi_Grid[index_v])+              ++multi_test_cmp;+          }+          if (multi_test_cmp == multi_test_dim)+            multi_test = 1;+          if (OPTIONS->Multi_Specify == 1)+            break;+        }++        if (multi_test == 0) {+          multi_cost[OPTIONS->Multi_Number] = current_generated_state->cost;+          VFOR (index_v) {+            multi_params[OPTIONS->Multi_Number][index_v] =+              current_generated_state->parameter[index_v];+          }+          for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+               ++multi_index) {+            multi_cost[multi_index] = OPTIONS->Multi_Cost[multi_index];+            VFOR (index_v) {+              multi_params[multi_index][index_v] =+                OPTIONS->Multi_Params[multi_index][index_v];+            }+          }++          qsort (multi_sort, OPTIONS->Multi_Number + 1, sizeof (int),+                 multi_compare);+          for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+               ++multi_index) {+            OPTIONS->Multi_Cost[multi_index] =+              multi_cost[multi_sort[multi_index]];+            VFOR (index_v) {+              OPTIONS->Multi_Params[multi_index][index_v] =+                multi_params[multi_sort[multi_index]][index_v];+            }+          }+        }+      }+#endif /* MULTI_MIN */++      /* CHECK FOR NEW MINIMUM */++      if (current_generated_state->cost < best_generated_state->cost) {+        /* NEW MINIMUM FOUND */++        OPTIONS->Locate_Cost = -1;++        /* reset the recent acceptances and generated counts */+#if ASA_PARALLEL+        parallel_generated = *recent_number_generated;+#endif+        *recent_number_acceptances = *recent_number_generated = 0;+        *best_number_generated_saved = *number_generated;+        *best_number_accepted_saved = *number_accepted;+        index_cost_repeat = 0;++        /* copy the current state into the best_generated state */+        best_generated_state->cost = current_generated_state->cost;+        VFOR (index_v) {+#if DROPPED_PARAMETERS+          /* ignore parameters that have too small a range */+          if (PARAMETER_RANGE_TOO_SMALL (index_v))+            continue;+#endif+          best_generated_state->parameter[index_v] =+            current_generated_state->parameter[index_v];+        }++        /* printout the new minimum state and value */+#if ASA_PRINT+        fprintf (ptr_asa_out,+#if INT_LONG+                 "best...->cost=%-*.*g  \+*number_accepted=%ld  *number_generated=%ld\n", G_FIELD, G_PRECISION, best_generated_state->cost,+#else+                 "best...->cost=%-*.*g  \+*number_accepted=%d  *number_generated=%d\n", G_FIELD, G_PRECISION, best_generated_state->cost,+#endif /* INT_LONG */+                 *number_accepted, *number_generated);+#if ASA_PARALLEL+        /* print OPTIONS->Gener_Block just used */+        fprintf (ptr_asa_out,+#if INT_LONG+                 "OPTIONS->Gener_Block = %ld\n",+#else+                 "OPTIONS->Gener_Block = %d\n",+#endif /* INT_LONG */+                 OPTIONS->Gener_Block);+#endif /* ASA_PARALLEL */+#if ASA_PRINT_MORE+#if INT_ALLOC+        fprintf (ptr_asa_out, "Present Random Seed = %d\n\n", *seed);+#else+#if INT_LONG+        fprintf (ptr_asa_out, "Present Random Seed = %ld\n\n", *seed);+#else+        fprintf (ptr_asa_out, "Present Random Seed = %d\n\n", *seed);+#endif+#endif+        print_state (parameter_minimum,+                     parameter_maximum,+                     tangents,+                     curvature,+                     current_cost_temperature,+                     current_user_parameter_temp,+                     accepted_to_generated_ratio,+                     number_parameters,+                     curvature_flag,+                     number_accepted,+                     index_cost_acceptances,+                     number_generated,+                     number_invalid_generated_states,+                     last_saved_state,+                     best_generated_state, ptr_asa_out, OPTIONS);+#endif /* ASA_PRINT_MORE */+        fflush (ptr_asa_out);+#endif /* ASA_PRINT */++#if ASA_PARALLEL+        /* leave index_parallel loop after new minimum */+        break;+#endif /* ASA_PARALLEL */+      }+#if ASA_PARALLEL+    }+#endif /* ASA_PARALLEL */++#if ASA_PARALLEL+    if (OPTIONS->Gener_Mov_Avr > 0) {+      OPTIONS->Gener_Block = (LONG_INT)+        ((((double) OPTIONS->Gener_Mov_Avr - ONE)+          * (double) (OPTIONS->Gener_Block) + (double) parallel_generated)+         / (double) (OPTIONS->Gener_Mov_Avr));+      OPTIONS->Gener_Block = MIN (OPTIONS->Gener_Block, parallel_block_max);+    }+#endif /* ASA_PARALLEL */++#if ASA_SAVE+    /* These writes are put here with these tests, instead of just+       after a new best state is found, to prevent any confusion with+       any parallel code that might be added by users. */+    if (*recent_number_acceptances == 0+        && *recent_number_generated == 0+        && *best_number_generated_saved == *number_generated+        && *best_number_accepted_saved == *number_accepted+        && OPTIONS->Asa_Recursive_Level == asa_recursive_max+        && index_cost_repeat == 0) {+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "asa_save_%d", OPTIONS->Asa_Recursive_Level);+      else+        sprintf (asa_save_comm, "asa_save");+      ptr_save = fopen (asa_save_comm, "w");++      fwrite (number_parameters, sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (xnumber_parameters, sizeof (double), 1, ptr_save);+      fwrite (parameter_minimum, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (parameter_maximum, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (tangents, sizeof (double), *number_parameters, ptr_save);+      fwrite (current_user_parameter_temp, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (initial_user_parameter_temp, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (temperature_scale_parameters, sizeof (double),+              *number_parameters, ptr_save);++      fwrite (parameter_type, sizeof (int), *number_parameters, ptr_save);+      fwrite (&index_cost_repeat, sizeof (int), 1, ptr_save);+      fwrite (&asa_open, sizeof (int), 1, ptr_save);+      fwrite (&number_asa_open, sizeof (int), 1, ptr_save);+      fwrite (&recursive_asa_open, sizeof (int), 1, ptr_save);++      fwrite (current_cost_temperature, sizeof (double), 1, ptr_save);+      fwrite (initial_cost_temperature, sizeof (double), 1, ptr_save);+      fwrite (temperature_scale_cost, sizeof (double), 1, ptr_save);+      fwrite (accepted_to_generated_ratio, sizeof (double), 1, ptr_save);++      fwrite (curvature_flag, sizeof (int), 1, ptr_save);++      fwrite (seed, sizeof (LONG_INT), 1, ptr_save);+      fwrite (number_generated, sizeof (LONG_INT), 1, ptr_save);+      fwrite (number_accepted, sizeof (LONG_INT), 1, ptr_save);+      fwrite (number_acceptances_saved, sizeof (LONG_INT), 1, ptr_save);+      fwrite (recent_number_acceptances, sizeof (LONG_INT), 1, ptr_save);+      fwrite (recent_number_generated, sizeof (LONG_INT), 1, ptr_save);+      fwrite (number_invalid_generated_states, sizeof (LONG_INT),+              1, ptr_save);+      fwrite (index_cost_acceptances, sizeof (LONG_INT), 1, ptr_save);+      fwrite (best_number_generated_saved, sizeof (LONG_INT), 1, ptr_save);+      fwrite (best_number_accepted_saved, sizeof (LONG_INT), 1, ptr_save);++      fwrite (index_parameter_generations, sizeof (LONG_INT),+              *number_parameters, ptr_save);++      fwrite (current_generated_state->parameter,+              sizeof (double), *number_parameters, ptr_save);+      fwrite (last_saved_state->parameter,+              sizeof (double), *number_parameters, ptr_save);+      fwrite (best_generated_state->parameter,+              sizeof (double), *number_parameters, ptr_save);+      fwrite (&(current_generated_state->cost), sizeof (double), 1, ptr_save);+      fwrite (&(last_saved_state->cost), sizeof (double), 1, ptr_save);+      fwrite (&(best_generated_state->cost), sizeof (double), 1, ptr_save);++      fwrite (&(OPTIONS->Limit_Acceptances), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Limit_Generated), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Limit_Invalid_Generated_States), sizeof (int),+              1, ptr_save);+      fwrite (&(OPTIONS->Accepted_To_Generated_Ratio), sizeof (double),+              1, ptr_save);+      fwrite (&(OPTIONS->Cost_Precision), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->Maximum_Cost_Repeat), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Number_Cost_Samples), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Temperature_Ratio_Scale), sizeof (double),+              1, ptr_save);+      fwrite (&(OPTIONS->Cost_Parameter_Scale_Ratio), sizeof (double),+              1, ptr_save);+      fwrite (&(OPTIONS->Temperature_Anneal_Scale), sizeof (double),+              1, ptr_save);+      fwrite (&(OPTIONS->Include_Integer_Parameters), sizeof (int),+              1, ptr_save);+      fwrite (&(OPTIONS->User_Initial_Parameters), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Sequential_Parameters), sizeof (ALLOC_INT), 1,+              ptr_save);+      fwrite (&(OPTIONS->Initial_Parameter_Temperature), sizeof (double), 1,+              ptr_save);+      fwrite (&(OPTIONS->Acceptance_Frequency_Modulus), sizeof (int), 1,+              ptr_save);+      fwrite (&(OPTIONS->Generated_Frequency_Modulus), sizeof (int), 1,+              ptr_save);+      fwrite (&(OPTIONS->Reanneal_Cost), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Reanneal_Parameters), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Delta_X), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->User_Tangents), sizeof (int), 1, ptr_save);++#if USER_INITIAL_COST_TEMP+      fwrite (&(OPTIONS->User_Cost_Temperature), sizeof (double),+              1, ptr_save);+#endif+#if RATIO_TEMPERATURE_SCALES+      fwrite (OPTIONS->User_Temperature_Ratio, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if USER_INITIAL_PARAMETERS_TEMPS+      fwrite (OPTIONS->User_Parameter_Temperature, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if DELTA_PARAMETERS+      fwrite (OPTIONS->User_Delta_Parameter, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if QUENCH_PARAMETERS+      fwrite (OPTIONS->User_Quench_Param_Scale, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if QUENCH_COST+      fwrite (OPTIONS->User_Quench_Cost_Scale, sizeof (double), 1, ptr_save);+#endif+      fwrite (&(OPTIONS->N_Accepted), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->N_Generated), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Locate_Cost), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Immediate_Exit), sizeof (int), 1, ptr_save);+#if OPTIONAL_DATA_DBL+      fwrite (&(OPTIONS->Asa_Data_Dim_Dbl), sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (OPTIONS->Asa_Data_Dbl, sizeof (double),+              OPTIONS->Asa_Data_Dim_Dbl, ptr_save);+#endif+      fwrite (&(OPTIONS->Random_Array_Dim), sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (OPTIONS->Random_Array, sizeof (double),+              OPTIONS->Random_Array_Dim, ptr_save);+      fwrite (&(OPTIONS->Asa_Recursive_Level), sizeof (int), 1, ptr_save);+#if OPTIONAL_DATA_INT+      fwrite (&(OPTIONS->Asa_Data_Dim_Int), sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (OPTIONS->Asa_Data_Int, sizeof (LONG_INT),+              OPTIONS->Asa_Data_Dim_Int, ptr_save);+#endif+#if OPTIONAL_DATA_PTR+      fwrite (&(OPTIONS->Asa_Data_Dim_Ptr), sizeof (ALLOC_INT), 1, ptr_save);+      if (OPTIONS->Asa_Recursive_Level == 0)+        fwrite (OPTIONS->Asa_Data_Ptr, sizeof (OPTIONAL_PTR_TYPE),+                OPTIONS->Asa_Data_Dim_Ptr, ptr_save);+#if ASA_TEMPLATE_SELFOPT+      if (OPTIONS->Asa_Recursive_Level == 1)+        fwrite (OPTIONS->Asa_Data_Ptr, sizeof (RECUR_OPTIONAL_PTR_TYPE),+                OPTIONS->Asa_Data_Dim_Ptr, ptr_save);+#endif+#endif+#if USER_ASA_OUT+      fwrite (OPTIONS->Asa_Out_File, sizeof (char), 1, ptr_save);+#endif+#if USER_COST_SCHEDULE+      fwrite (&(OPTIONS->Cost_Schedule), sizeof (char), 1, ptr_save);+#endif+#if USER_ACCEPT_ASYMP_EXP+      fwrite (&(OPTIONS->Asymp_Exp_Param), sizeof (double), 1, ptr_save);+#endif+#if USER_ACCEPTANCE_TEST+      fwrite (&(OPTIONS->Acceptance_Test), sizeof (char), 1, ptr_save);+      fwrite (&(OPTIONS->User_Acceptance_Flag), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Cost_Acceptance_Flag), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Cost_Temp_Curr), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->Cost_Temp_Init), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->Cost_Temp_Scale), sizeof (double), 1, ptr_save);+#endif+#if USER_GENERATING_FUNCTION+      fwrite (&(OPTIONS->Generating_Distrib), sizeof (char), 1, ptr_save);+#endif+#if USER_REANNEAL_COST+      fwrite (&(OPTIONS->Reanneal_Cost_Function), sizeof (char), 1, ptr_save);+#endif+#if USER_REANNEAL_PARAMETERS+      fwrite (&(OPTIONS->Reanneal_Params_Function), sizeof (char),+              1, ptr_save);+#endif+#if ASA_SAMPLE+      fwrite (&(OPTIONS->Bias_Acceptance), sizeof (double), 1, ptr_save);+      fwrite (OPTIONS->Bias_Generated, sizeof (double),+              *number_parameters, ptr_save);+      fwrite (&(OPTIONS->Average_Weights), sizeof (double), 1, ptr_save);+      fwrite (&(OPTIONS->Limit_Weights), sizeof (double), 1, ptr_save);+#endif+#if ASA_QUEUE+      fwrite (save_queue, sizeof (LONG_INT), 1, ptr_save);+      fwrite (save_queue_indx, sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Queue_Size), sizeof (ALLOC_INT), 1, ptr_save);+      fwrite (save_queue_flag, sizeof (int), save_queue, ptr_save);+      fwrite (save_queue_cost, sizeof (double), save_queue, ptr_save);+      fwrite (save_queue_param, sizeof (double),+              (*number_parameters) * (OPTIONS->Queue_Size), ptr_save);+#if ASA_RESOLUTION+#else+      fwrite (OPTIONS->Queue_Resolution, sizeof (double),+              *number_parameters, ptr_save);+#endif+#endif+#if ASA_RESOLUTION+      fwrite (OPTIONS->Coarse_Resolution, sizeof (double),+              *number_parameters, ptr_save);+#endif+#if FITLOC+      fwrite (&(OPTIONS->Fit_Local), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Iter_Max), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Penalty), sizeof (double), 1, ptr_save);+#endif+#if MULTI_MIN+      fwrite (OPTIONS->Multi_Number, sizeof (int), 1, ptr_save);+      fwrite (OPTIONS->Multi_Grid,+              sizeof (double), *number_parameters, ptr_save);+      fwrite (&(OPTIONS->Multi_Specify), sizeof (int), 1, ptr_save);+      for (multi_index = 0; multi_index < OPTIONS->Multi_Number;+           ++multi_index) {+        fwrite (&(OPTIONS->Multi_Cost[multi_index]), sizeof (double), 1,+                ptr_save);+        fwrite (&(OPTIONS->Multi_Params[multi_index]), sizeof (double),+                *number_parameters, ptr_save);+      }+#endif+#if ASA_PARALLEL+      fwrite (&parallel_generated, sizeof (LONG_INT), 1, ptr_save);+      fwrite (&parallel_block_max, sizeof (LONG_INT), 1, ptr_save);+      for (index_parallel = 0; index_parallel < parallel_block_max;+           ++index_parallel) {+        fwrite (gener_block_state[index_parallel].parameter,+                sizeof (double), *number_parameters, ptr_save);+        fwrite (&(gener_block_state[index_parallel].cost),+                sizeof (double), 1, ptr_save);+#if USER_ACCEPTANCE_TEST+        fwrite (&+                (gener_block_state[index_parallel].+                 par_user_accept_flag), sizeof (int), 1, ptr_save);+        fwrite (&+                (gener_block_state[index_parallel].+                 par_cost_accept_flag), sizeof (int), 1, ptr_save);+#endif+      }+      fwrite (&(OPTIONS->Gener_Mov_Avr), sizeof (int), 1, ptr_save);+      fwrite (&(OPTIONS->Gener_Block), sizeof (LONG_INT), 1, ptr_save);+      fwrite (&(OPTIONS->Gener_Block_Max), sizeof (LONG_INT), 1, ptr_save);+#endif++      fclose (ptr_save);++    SAVED_ASA:+      ;++#if SYSTEM_CALL+#if ASA_SAVE_BACKUP+#if INT_LONG+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "/bin/cp asa_save_%d asa_save_%d.%ld",+                 OPTIONS->Asa_Recursive_Level,+                 OPTIONS->Asa_Recursive_Level, OPTIONS->N_Accepted);+      else+        sprintf (asa_save_comm, "/bin/cp asa_save asa_save.%ld",+                 OPTIONS->N_Accepted);+#else+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "/bin/cp asa_save_%d asa_save_%d.%d",+                 OPTIONS->Asa_Recursive_Level,+                 OPTIONS->Asa_Recursive_Level, OPTIONS->N_Accepted);+      else+        sprintf (asa_save_comm, "/bin/cp asa_save asa_save.%d",+                 OPTIONS->N_Accepted);+#endif+      ptr_comm = popen (asa_save_comm, "r");+      pclose (ptr_comm);+#else /* ASA_SAVE_BACKUP */+      /* extra protection in case run aborts during write */+      if (OPTIONS->Asa_Recursive_Level > 0)+        sprintf (asa_save_comm, "/bin/cp asa_save_%d asa_save_%d.old",+                 OPTIONS->Asa_Recursive_Level, OPTIONS->Asa_Recursive_Level);+      else+        sprintf (asa_save_comm, "/bin/cp asa_save asa_save.old");+      ptr_comm = popen (asa_save_comm, "r");+      pclose (ptr_comm);+#endif /* ASA_SAVE_BACKUP */+#endif /* SYSTEM_CALL */+    }+#endif /* ASA_SAVE */++    if (OPTIONS->Immediate_Exit == TRUE) {+      *exit_status = IMMEDIATE_EXIT;+      goto EXIT_ASA;+    }++    /* PERIODIC TESTING/REANNEALING/PRINTING SECTION */++    if (OPTIONS->Acceptance_Frequency_Modulus == 0)+      tmp_var_int1 = FALSE;+    else if ((int) (*number_accepted %+                    ((LONG_INT) OPTIONS->Acceptance_Frequency_Modulus)) == 0+             && *number_acceptances_saved == *number_accepted)+      tmp_var_int1 = TRUE;+    else+      tmp_var_int1 = FALSE;++    if (OPTIONS->Generated_Frequency_Modulus == 0)+      tmp_var_int2 = FALSE;+    else if ((int) (*number_generated %+                    ((LONG_INT) OPTIONS->Generated_Frequency_Modulus)) == 0)+      tmp_var_int2 = TRUE;+    else+      tmp_var_int2 = FALSE;++    if (tmp_var_int1 == TRUE || tmp_var_int2 == TRUE+        || (*accepted_to_generated_ratio+            < OPTIONS->Accepted_To_Generated_Ratio)) {+      if (*accepted_to_generated_ratio+          < (OPTIONS->Accepted_To_Generated_Ratio))+        *recent_number_acceptances = *recent_number_generated = 0;++      /* if best.cost repeats OPTIONS->Maximum_Cost_Repeat then exit */+      if (OPTIONS->Maximum_Cost_Repeat != 0) {+        if (fabs (last_saved_state->cost - best_generated_state->cost)+            < OPTIONS->Cost_Precision) {+          ++index_cost_repeat;+          if (index_cost_repeat == (OPTIONS->Maximum_Cost_Repeat)) {+            *exit_status = COST_REPEATING;+            goto EXIT_ASA;+          }+        } else {+          index_cost_repeat = 0;+        }+      }++      if (OPTIONS->Reanneal_Parameters == TRUE) {+        OPTIONS->Locate_Cost = 3;       /* reanneal parameters */++        /* calculate tangents, not curvatures, to reanneal */+        *curvature_flag = FALSE;+        cost_derivatives (user_cost_function,+                          parameter_minimum,+                          parameter_maximum,+                          tangents,+                          curvature,+                          maximum_tangent,+                          number_parameters,+                          parameter_type,+                          exit_status,+                          curvature_flag,+                          valid_state_generated_flag,+                          number_invalid_generated_states,+                          current_generated_state,+                          best_generated_state, ptr_asa_out, OPTIONS);+        if (*exit_status == INVALID_COST_FUNCTION_DERIV) {+          goto EXIT_ASA;+        }+      }+#if USER_REANNEAL_COST+#else+      if (OPTIONS->Reanneal_Cost == 0 || OPTIONS->Reanneal_Cost == 1) {+        ;+      } else {+        immediate_flag = OPTIONS->Immediate_Exit;++        if (OPTIONS->Reanneal_Cost < -1) {+          tmp_var_int = -OPTIONS->Reanneal_Cost;+        } else {+          tmp_var_int = OPTIONS->Reanneal_Cost;+        }+        tmp_var_db1 = ZERO;+        tmp_var_db2 = ZERO;++        for (index_cost_constraint = 0;+             index_cost_constraint < tmp_var_int; ++index_cost_constraint) {+          OPTIONS->Locate_Cost = 4;     /* reanneal cost */++          *number_invalid_generated_states = 0;+          repeated_invalid_states = 0;+          OPTIONS->Sequential_Parameters = *start_sequence - 1;+          do {+            ++(*number_invalid_generated_states);+            generate_new_state (user_random_generator,+                                seed,+                                parameter_minimum,+                                parameter_maximum,+                                current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                                initial_user_parameter_temp,+                                temperature_scale_parameters,+#endif+                                number_parameters,+                                parameter_type,+                                current_generated_state,+                                last_saved_state, OPTIONS);+            *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+            OPTIONS->User_Acceptance_Flag = TRUE;+            OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif++#if ASA_QUEUE+            if (OPTIONS->Queue_Size == 0) {+              queue_new = 1;+            } else {+              queue_new = 1;+              for (queue = 0; queue < save_queue; ++queue) {+                save_queue_test = 0;+                VFOR (index_v) {+                  if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+                    ++save_queue_test;+                  } else {+                    queue_v = index_v + queue+                      * (LONG_INT) (*number_parameters);+                    if (fabs+                        (current_generated_state->+                         parameter[index_v] -+                         save_queue_param[queue_v]) <+                        (OPTIONS->Queue_Resolution[index_v] + EPS_DOUBLE)) {+                      ++save_queue_test;+                    }+                  }+                }+                if (save_queue_test == *number_parameters) {+                  tmp_var_db = save_queue_cost[queue];+                  *valid_state_generated_flag = save_queue_flag[queue];+                  queue_new = 0;+#if ASA_PRINT_MORE+#if INT_LONG+                  fprintf (ptr_asa_out,+                           "ASA_QUEUE: %ld \t %*.*g\n",+                           OPTIONS->N_Generated, G_FIELD,+                           G_PRECISION, tmp_var_db);+#else+                  fprintf (ptr_asa_out,+                           "ASA_QUEUE: %d \t %*.*g\n",+                           OPTIONS->N_Generated, G_FIELD,+                           G_PRECISION, tmp_var_db);+#endif+#endif+                  break;+                }+              }+            }+            if (queue_new == 1) {+              tmp_var_db =+                user_cost_function (current_generated_state->+                                    parameter, parameter_minimum,+                                    parameter_maximum, tangents,+                                    curvature, number_parameters,+                                    parameter_type,+                                    valid_state_generated_flag,+                                    exit_status, OPTIONS);+              if (cost_function_test+                  (tmp_var_db, current_generated_state->parameter,+                   parameter_minimum, parameter_maximum,+                   number_parameters, xnumber_parameters) == 0) {+                *exit_status = INVALID_COST_FUNCTION;+                goto EXIT_ASA;+              }+              if (OPTIONS->Queue_Size > 0) {+                VFOR (index_v) {+                  if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+                    continue;+                  }+                  queue_v = index_v + save_queue+                    * (LONG_INT) (*number_parameters);+                  save_queue_param[queue_v] =+                    current_generated_state->parameter[index_v];+                }+                save_queue_cost[save_queue] = tmp_var_db;+                save_queue_flag[save_queue]+                  = *valid_state_generated_flag;++                ++save_queue;+                if (save_queue == (LONG_INT) OPTIONS->Queue_Size)+                  --save_queue;++                ++save_queue_indx;+                if (save_queue_indx == (LONG_INT) OPTIONS->Queue_Size)+                  save_queue_indx = 0;+              }+            }+#else /* ASA_QUEUE */+            tmp_var_db =+              user_cost_function (current_generated_state->+                                  parameter, parameter_minimum,+                                  parameter_maximum, tangents,+                                  curvature, number_parameters,+                                  parameter_type,+                                  valid_state_generated_flag,+                                  exit_status, OPTIONS);+            if (cost_function_test+                (tmp_var_db, current_generated_state->parameter,+                 parameter_minimum, parameter_maximum,+                 number_parameters, xnumber_parameters) == 0) {+              *exit_status = INVALID_COST_FUNCTION;+              goto EXIT_ASA;+            }+#endif /* ASA_QUEUE */+            ++repeated_invalid_states;+            if (repeated_invalid_states >+                OPTIONS->Limit_Invalid_Generated_States) {+              *exit_status = TOO_MANY_INVALID_STATES;+              goto EXIT_ASA;+            }+          }+          while (*valid_state_generated_flag == FALSE);+          --(*number_invalid_generated_states);++          tmp_var_db1 += tmp_var_db;+          tmp_var_db2 += (tmp_var_db * tmp_var_db);+        }+        tmp_var_db1 /= (double) tmp_var_int;+        tmp_var_db2 /= (double) tmp_var_int;+        tmp_var_db =+          sqrt (fabs+                ((tmp_var_db2 -+                  tmp_var_db1 * tmp_var_db1) * ((double) tmp_var_int /+                                                ((double) tmp_var_int -+                                                 ONE))));+        if (OPTIONS->Reanneal_Cost < -1) {+          *current_cost_temperature = *initial_cost_temperature =+            tmp_var_db + (double) EPS_DOUBLE;+        } else {+          *initial_cost_temperature = tmp_var_db + (double) EPS_DOUBLE;+        }+        OPTIONS->Immediate_Exit = immediate_flag;+      }+#endif /* USER_REANNEAL_COST */++      reanneal (parameter_minimum,+                parameter_maximum,+                tangents,+                maximum_tangent,+                current_cost_temperature,+                initial_cost_temperature,+                temperature_scale_cost,+                current_user_parameter_temp,+                initial_user_parameter_temp,+                temperature_scale_parameters,+                number_parameters,+                parameter_type,+                index_cost_acceptances,+                index_parameter_generations,+                last_saved_state, best_generated_state, OPTIONS);+#if ASA_PRINT_INTERMED+#if ASA_PRINT+      print_state (parameter_minimum,+                   parameter_maximum,+                   tangents,+                   curvature,+                   current_cost_temperature,+                   current_user_parameter_temp,+                   accepted_to_generated_ratio,+                   number_parameters,+                   curvature_flag,+                   number_accepted,+                   index_cost_acceptances,+                   number_generated,+                   number_invalid_generated_states,+                   last_saved_state,+                   best_generated_state, ptr_asa_out, OPTIONS);++      fprintf (ptr_asa_out, "\n");+      fflush (ptr_asa_out);+#endif+#endif+    }+  }++  /* FINISHED ANNEALING and MINIMIZATION */++  *exit_status = NORMAL_EXIT;+EXIT_ASA:++  asa_exit_value = asa_exit (user_cost_function,+                             &final_cost,+                             parameter_initial_final,+                             parameter_minimum,+                             parameter_maximum,+                             tangents,+                             curvature,+                             maximum_tangent,+                             current_cost_temperature,+                             initial_user_parameter_temp,+                             current_user_parameter_temp,+                             accepted_to_generated_ratio,+                             number_parameters,+                             parameter_type,+                             valid_state_generated_flag,+                             exit_status,+                             index_exit_v,+                             start_sequence,+                             number_accepted,+                             best_number_accepted_saved,+                             index_cost_acceptances,+                             number_generated,+                             number_invalid_generated_states,+                             index_parameter_generations,+                             best_number_generated_saved,+                             current_generated_state,+                             last_saved_state,+                             best_generated_state, ptr_asa_out, OPTIONS);+  if (asa_exit_value == 9) {+    *exit_status = CALLOC_FAILED;+    return (-1);+  }++  free (curvature_flag);+  free (maximum_tangent);+  free (accepted_to_generated_ratio);+  free (temperature_scale_cost);+  free (current_cost_temperature);+  free (initial_cost_temperature);+  free (number_generated);+  free (best_number_generated_saved);+  free (recent_number_generated);+  free (number_accepted);+  free (recent_number_acceptances);+  free (index_cost_acceptances);+  free (number_acceptances_saved);+  free (best_number_accepted_saved);+  free (number_invalid_generated_states);+  free (current_generated_state->parameter);+  free (last_saved_state->parameter);+  free (best_generated_state->parameter);+  free (current_generated_state);+  free (last_saved_state);+  free (best_generated_state);+#if ASA_QUEUE+  free (save_queue_flag);+  free (save_queue_cost);+  free (save_queue_param);+#endif+#if MULTI_MIN+  for (multi_index = 0; multi_index <= OPTIONS->Multi_Number; ++multi_index)+    free (multi_params[multi_index]);+  free (multi_params);+  free (multi_sort);+  free (multi_cost);+#endif+#if ASA_PARALLEL+  for (index_parallel = 0; index_parallel < parallel_block_max;+       ++index_parallel) {+    free (gener_block_state[index_parallel].parameter);+  }+  free (gener_block_state);+  free (parallel_sort);+#endif+#if ASA_PIPE_FILE+  fclose (ptr_asa_pipe);+#endif+  free (initial_user_parameter_temp);+  free (index_exit_v);+  free (start_sequence);+  free (index_parameter_generations);+  free (current_user_parameter_temp);+  free (temperature_scale_parameters);+  if (recursive_asa_open == 0)+    asa_open = FALSE;+  return (final_cost);+}++/***********************************************************************+* asa_exit+*	This procedures copies the best parameters and cost into+*       final_cost and parameter_initial_final+***********************************************************************/+#if HAVE_ANSI+int+asa_exit (double (*user_cost_function)++           +          (double *, double *, double *, double *, double *, ALLOC_INT *,+           int *, int *, int *, USER_DEFINES *), double *final_cost,+          double *parameter_initial_final, double *parameter_minimum,+          double *parameter_maximum, double *tangents, double *curvature,+          double *maximum_tangent, double *current_cost_temperature,+          double *initial_user_parameter_temp,+          double *current_user_parameter_temp,+          double *accepted_to_generated_ratio,+          ALLOC_INT * number_parameters, int *parameter_type,+          int *valid_state_generated_flag, int *exit_status,+          ALLOC_INT * index_exit_v, ALLOC_INT * start_sequence,+          LONG_INT * number_accepted,+          LONG_INT * best_number_accepted_saved,+          LONG_INT * index_cost_acceptances, LONG_INT * number_generated,+          LONG_INT * number_invalid_generated_states,+          LONG_INT * index_parameter_generations,+          LONG_INT * best_number_generated_saved,+          STATE * current_generated_state, STATE * last_saved_state,+          STATE * best_generated_state, FILE * ptr_asa_out,+          USER_DEFINES * OPTIONS)+#else+int++asa_exit (user_cost_function,+          final_cost,+          parameter_initial_final,+          parameter_minimum,+          parameter_maximum,+          tangents,+          curvature,+          maximum_tangent,+          current_cost_temperature,+          initial_user_parameter_temp,+          current_user_parameter_temp,+          accepted_to_generated_ratio,+          number_parameters,+          parameter_type,+          valid_state_generated_flag,+          exit_status,+          index_exit_v,+          start_sequence,+          number_accepted,+          best_number_accepted_saved,+          index_cost_acceptances,+          number_generated,+          number_invalid_generated_states,+          index_parameter_generations,+          best_number_generated_saved,+          current_generated_state,+          last_saved_state, best_generated_state, ptr_asa_out, OPTIONS)+     double (*user_cost_function) ();+     double *final_cost;+     double *parameter_initial_final;+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *curvature;+     double *maximum_tangent;+     double *current_cost_temperature;+     double *initial_user_parameter_temp;+     double *current_user_parameter_temp;+     double *accepted_to_generated_ratio;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     int *valid_state_generated_flag;+     int *exit_status;+     ALLOC_INT *index_exit_v;+     ALLOC_INT *start_sequence;+     LONG_INT *number_accepted;+     LONG_INT *best_number_accepted_saved;+     LONG_INT *index_cost_acceptances;+     LONG_INT *number_generated;+     LONG_INT *number_invalid_generated_states;+     LONG_INT *index_parameter_generations;+     LONG_INT *best_number_generated_saved;+     STATE *current_generated_state;+     STATE *last_saved_state;+     STATE *best_generated_state;+     FILE *ptr_asa_out;+     USER_DEFINES *OPTIONS;+#endif+{+  ALLOC_INT index_v;            /* iteration index */+  int curvatureFlag;+  int exit_exit_status, tmp_locate;+#if MULTI_MIN+  int multi_index;+#endif++  tmp_locate = OPTIONS->Locate_Cost;++  /* return final function minimum and associated parameters */+  *final_cost = best_generated_state->cost;+  VFOR (index_v) {+    parameter_initial_final[index_v] =+      best_generated_state->parameter[index_v];+  }++  OPTIONS->N_Accepted = *best_number_accepted_saved;+  OPTIONS->N_Generated = *best_number_generated_saved;++#if MULTI_MIN+  for (multi_index = 0; multi_index < OPTIONS->Multi_Number; ++multi_index) {+    best_generated_state->cost = OPTIONS->Multi_Cost[multi_index];+    VFOR (index_v) {+      best_generated_state->parameter[index_v] =+        OPTIONS->Multi_Params[multi_index][index_v];+    }+#if ASA_PRINT+    fprintf (ptr_asa_out, "\n\t\t multi_index = %d\n", multi_index);+#endif /* ASA_PRINT */+#endif /* MULTI_MIN */+    if (*exit_status != TOO_MANY_INVALID_STATES+        && *exit_status != IMMEDIATE_EXIT+        && *exit_status != INVALID_USER_INPUT+        && *exit_status != INVALID_COST_FUNCTION+        && *exit_status != INVALID_COST_FUNCTION_DERIV) {+      if (OPTIONS->Curvature_0 != TRUE)+        OPTIONS->Locate_Cost = 5;       /* calc curvatures while exiting asa */++      /* calculate curvatures and tangents at best point */+      curvatureFlag = TRUE;+      cost_derivatives (user_cost_function,+                        parameter_minimum,+                        parameter_maximum,+                        tangents,+                        curvature,+                        maximum_tangent,+                        number_parameters,+                        parameter_type,+                        &exit_exit_status,+                        &curvatureFlag,+                        valid_state_generated_flag,+                        number_invalid_generated_states,+                        current_generated_state,+                        best_generated_state, ptr_asa_out, OPTIONS);+    }+#if ASA_PRINT+    if (exit_exit_status == INVALID_COST_FUNCTION_DERIV)+      fprintf (ptr_asa_out, "\n\n  in asa_exit: INVALID_COST_FUNCTION_DERIV");++    if (*exit_status != INVALID_USER_INPUT+        && *exit_status != INVALID_COST_FUNCTION+        && *exit_status != INVALID_COST_FUNCTION_DERIV)+      print_state (parameter_minimum,+                   parameter_maximum,+                   tangents,+                   curvature,+                   current_cost_temperature,+                   current_user_parameter_temp,+                   accepted_to_generated_ratio,+                   number_parameters,+                   &curvatureFlag,+                   number_accepted,+                   index_cost_acceptances,+                   number_generated,+                   number_invalid_generated_states,+                   last_saved_state,+                   best_generated_state, ptr_asa_out, OPTIONS);+#endif /* ASA_PRINT */++#if MULTI_MIN+  }+  best_generated_state->cost = OPTIONS->Multi_Cost[0];+  VFOR (index_v) {+    best_generated_state->parameter[index_v] =+      OPTIONS->Multi_Params[0][index_v];+  }+#endif /* MULTI_MIN */++#if ASA_PRINT+  switch (*exit_status) {+  case NORMAL_EXIT:+    fprintf (ptr_asa_out,+             "\n\n NORMAL_EXIT exit_status = %d\n", *exit_status);+    break;+  case P_TEMP_TOO_SMALL:+    fprintf (ptr_asa_out,+             "\n\n P_TEMP_TOO_SMALL exit_status = %d\n", *exit_status);+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "current_user_parameter_temp[%d] too small = %*.*g\n",+#else+#if INT_LONG+             "current_user_parameter_temp[%ld] too small = %*.*g\n",+#else+             "current_user_parameter_temp[%d] too small = %*.*g\n",+#endif+#endif+             *index_exit_v,+             G_FIELD, G_PRECISION,+             current_user_parameter_temp[*index_exit_v]);+    break;+  case C_TEMP_TOO_SMALL:+    fprintf (ptr_asa_out,+             "\n\n C_TEMP_TOO_SMALL exit_status = %d\n", *exit_status);+    fprintf (ptr_asa_out,+             "*current_cost_temperature too small = %*.*g\n",+             G_FIELD, G_PRECISION, *current_cost_temperature);+    break;+  case COST_REPEATING:+    fprintf (ptr_asa_out,+             "\n\n COST_REPEATING exit_status = %d\n", *exit_status);+    break;+  case TOO_MANY_INVALID_STATES:+    fprintf (ptr_asa_out,+             "\n\n  TOO_MANY_INVALID_STATES exit_status = %d\n",+             *exit_status);+    break;+  case IMMEDIATE_EXIT:+    fprintf (ptr_asa_out,+             "\n\n  IMMEDIATE_EXIT exit_status = %d\n", *exit_status);+    break;+  case INVALID_USER_INPUT:+    fprintf (ptr_asa_out,+             "\n\n  INVALID_USER_INPUT exit_status = %d\n", *exit_status);+    break;+  case INVALID_COST_FUNCTION:+    fprintf (ptr_asa_out,+             "\n\n  INVALID_COST_FUNCTION exit_status = %d\n", *exit_status);+    break;+  case INVALID_COST_FUNCTION_DERIV:+    fprintf (ptr_asa_out,+             "\n\n  INVALID_COST_FUNCTION_DERIV exit_status = %d\n",+             *exit_status);+    break;+  default:+    fprintf (ptr_asa_out, "\n\n ERR: no exit code available = %d\n",+             *exit_status);+  }++  switch (OPTIONS->Locate_Cost) {+  case 0:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, initial cost temperature\n",+             OPTIONS->Locate_Cost);+    break;+  case 1:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, initial cost value\n", OPTIONS->Locate_Cost);+    break;+  case 2:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, new generated state\n",+             OPTIONS->Locate_Cost);+    break;+  case 12:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, new generated state just after a new best state\n",+             OPTIONS->Locate_Cost);+    break;+  case 3:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, cost derivatives, reannealing parameters\n",+             OPTIONS->Locate_Cost);+    break;+  case 4:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, reannealing cost temperature\n",+             OPTIONS->Locate_Cost);+    break;+  case 5:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, calculating curvatures while exiting asa ()\n",+             OPTIONS->Locate_Cost);+    break;+  case -1:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, exited main asa () loop by user-defined OPTIONS\n",+             OPTIONS->Locate_Cost);+    break;+  default:+    fprintf (ptr_asa_out,+             " Locate_Cost = %d, no index available for Locate_Cost\n",+             OPTIONS->Locate_Cost);+  }++  if (*exit_status != INVALID_USER_INPUT+      && *exit_status != INVALID_COST_FUNCTION+      && *exit_status != INVALID_COST_FUNCTION_DERIV) {+    fprintf (ptr_asa_out,+             "final_cost = best_generated_state->cost = %-*.*g\n",+             G_FIELD, G_PRECISION, *final_cost);+#if INT_LONG+    fprintf (ptr_asa_out,+             "*number_accepted at best_generated_state->cost = %ld\n",+             *best_number_accepted_saved);+    fprintf (ptr_asa_out,+             "*number_generated at best_generated_state->cost = %ld\n",+             *best_number_generated_saved);+#else+    fprintf (ptr_asa_out,+             "*number_accepted at best_generated_state->cost = %d\n",+             *best_number_accepted_saved);+    fprintf (ptr_asa_out,+             "*number_generated at best_generated_state->cost = %d\n",+             *best_number_generated_saved);+#endif+  }+#endif++#if ASA_TEMPLATE_SELFOPT+  if (OPTIONS->Asa_Data_Dbl[0] > (double) MIN_DOUBLE)+    OPTIONS->Asa_Data_Dbl[1] = (double) (*best_number_generated_saved);+#endif++  /* reset OPTIONS->Sequential_Parameters */+  OPTIONS->Sequential_Parameters = *start_sequence;++#if ASA_PRINT+#if TIME_CALC+  /* print ending time */+  print_time ("asa_end", ptr_asa_out);+#endif+  fprintf (ptr_asa_out, "\n\n\n");+  fflush (ptr_asa_out);+  ptr_asa_out != stdout && fclose (ptr_asa_out);+#endif++  return (0);+}++/***********************************************************************+* generate_new_state+*       Generates a valid new state from the old state+***********************************************************************/+#if HAVE_ANSI+void++generate_new_state (double (*user_random_generator) (LONG_INT *),+                    LONG_INT * seed,+                    double *parameter_minimum,+                    double *parameter_maximum,+                    double *current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                    double *initial_user_parameter_temp,+                    double *temperature_scale_parameters,+#endif+                    ALLOC_INT * number_parameters,+                    int *parameter_type,+                    STATE * current_generated_state,+                    STATE * last_saved_state, USER_DEFINES * OPTIONS)+#else+void++generate_new_state (user_random_generator,+                    seed,+                    parameter_minimum,+                    parameter_maximum, current_user_parameter_temp,+#if USER_GENERATING_FUNCTION+                    initial_user_parameter_temp, temperature_scale_parameters,+#endif+                    number_parameters,+                    parameter_type,+                    current_generated_state, last_saved_state, OPTIONS)+     double (*user_random_generator) ();+     LONG_INT *seed;+     double *parameter_minimum;+     double *parameter_maximum;+     double *current_user_parameter_temp;+#if USER_GENERATING_FUNCTION+     double *initial_user_parameter_temp;+     double *temperature_scale_parameters;+#endif+     ALLOC_INT *number_parameters;+     int *parameter_type;+     STATE *current_generated_state;+     STATE *last_saved_state;+     USER_DEFINES *OPTIONS;+#endif+{+  ALLOC_INT index_v;+  double x;+  double parameter_v, min_parameter_v, max_parameter_v, temperature_v,+    parameter_range_v;+#if USER_GENERATING_FUNCTION+  double init_param_temp_v;+  double temp_scale_params_v;+#endif+#if ASA_RESOLUTION+  double xres, xint, xminus, xplus, dx, dxminus, dxplus;+#endif++  /* generate a new value for each parameter */+  VFOR (index_v) {+    if (OPTIONS->Sequential_Parameters >= -1) {+      ++OPTIONS->Sequential_Parameters;+      if (OPTIONS->Sequential_Parameters == *number_parameters)+        OPTIONS->Sequential_Parameters = 0;+      index_v = OPTIONS->Sequential_Parameters;+    }+    min_parameter_v = parameter_minimum[index_v];+    max_parameter_v = parameter_maximum[index_v];+    parameter_range_v = max_parameter_v - min_parameter_v;++    /* ignore parameters that have too small a range */+    if (fabs (parameter_range_v) < (double) EPS_DOUBLE)+      continue;++    temperature_v = current_user_parameter_temp[index_v];+#if USER_GENERATING_FUNCTION+    init_param_temp_v = initial_user_parameter_temp[index_v];+    temp_scale_params_v = temperature_scale_parameters[index_v];+#endif+    parameter_v = last_saved_state->parameter[index_v];++    /* Handle discrete parameters. */+#if ASA_RESOLUTION+    xres = OPTIONS->Coarse_Resolution[index_v];+    if (xres > EPS_DOUBLE) {+      min_parameter_v -= (xres / TWO);+      max_parameter_v += (xres / TWO);+      parameter_range_v = max_parameter_v - min_parameter_v;+    }+#endif /* ASA_RESOLUTION */+    if (INTEGER_PARAMETER (index_v)) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        min_parameter_v -= HALF;+        max_parameter_v += HALF;+        parameter_range_v = max_parameter_v - min_parameter_v;+      }+#if ASA_RESOLUTION+    }+#endif++    /* generate a new state x within the parameter bounds */+    for (;;) {+#if USER_GENERATING_FUNCTION+      x = OPTIONS->Generating_Distrib (seed,+                                       number_parameters,+                                       index_v,+                                       temperature_v,+                                       init_param_temp_v,+                                       temp_scale_params_v,+                                       parameter_v,+                                       parameter_range_v,+                                       last_saved_state->parameter, OPTIONS);+#else+      x = parameter_v+        + generate_asa_state (user_random_generator, seed, &temperature_v)+        * parameter_range_v;+#endif /* USER_GENERATING_FUNCTION */+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        xint = xres * (double) ((LONG_INT) (x / xres));+        xplus = xint + xres;+        xminus = xint - xres;+        dx = fabs (xint - x);+        dxminus = fabs (xminus - x);+        dxplus = fabs (xplus - x);++        if (dx < dxminus && dx < dxplus)+          x = xint;+        else if (dxminus < dxplus)+          x = xminus;+        else+          x = xplus;+      }+#endif /* ASA_RESOLUTION */++      /* exit the loop if within its valid parameter range */+      if (x <= max_parameter_v - (double) EPS_DOUBLE+          && x >= min_parameter_v + (double) EPS_DOUBLE)+        break;+    }++    /* Handle discrete parameters.+       You might have to check rounding on your machine. */+    if (INTEGER_PARAMETER (index_v)) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        if (x < min_parameter_v + HALF)+          x = min_parameter_v + HALF + (double) EPS_DOUBLE;+        if (x > max_parameter_v - HALF)+          x = max_parameter_v - HALF + (double) EPS_DOUBLE;++        if (x + HALF > ZERO) {+          x = (double) ((LONG_INT) (x + HALF));+        } else {+          x = (double) ((LONG_INT) (x - HALF));+        }+        if (x > parameter_maximum[index_v])+          x = parameter_maximum[index_v];+        if (x < parameter_minimum[index_v])+          x = parameter_minimum[index_v];+      }+#if ASA_RESOLUTION+    }+    if (xres > EPS_DOUBLE) {+      if (x < min_parameter_v + xres / TWO)+        x = min_parameter_v + xres / TWO + (double) EPS_DOUBLE;+      if (x > max_parameter_v - xres / TWO)+        x = max_parameter_v - xres / TWO + (double) EPS_DOUBLE;++      if (x > parameter_maximum[index_v])+        x = parameter_maximum[index_v];+      if (x < parameter_minimum[index_v])+        x = parameter_minimum[index_v];+    }+#endif /* ASA_RESOLUTION */++    /* save the newly generated value */+    current_generated_state->parameter[index_v] = x;++    if (OPTIONS->Sequential_Parameters >= 0)+      break;+  }++}++/***********************************************************************+* generate_asa_state+*       This function generates a single value according to the+*       ASA generating function and the passed temperature+***********************************************************************/+#if HAVE_ANSI+double++generate_asa_state (double (*user_random_generator) (LONG_INT *),+                    LONG_INT * seed, double *temp)+#else+double+generate_asa_state (user_random_generator, seed, temp)+     double (*user_random_generator) ();+     LONG_INT *seed;+     double *temp;+#endif+{+  double x, y, z;++  x = (*user_random_generator) (seed);+  y = x < HALF ? -ONE : ONE;+  z = y * *temp * (F_POW ((ONE + ONE / *temp), fabs (TWO * x - ONE)) - ONE);++  return (z);++}++/***********************************************************************+* accept_new_state+*	This procedure accepts or rejects a newly generated state,+*	depending on whether the difference between new and old+*	cost functions passes a statistical test. If accepted,+*	the current state is updated.+***********************************************************************/+#if HAVE_ANSI+void++accept_new_state (double (*user_random_generator) (LONG_INT *),+                  LONG_INT * seed,+                  double *parameter_minimum,+                  double *parameter_maximum, double *current_cost_temperature,+#if ASA_SAMPLE+                  double *current_user_parameter_temp,+#endif+                  ALLOC_INT * number_parameters,+                  LONG_INT * recent_number_acceptances,+                  LONG_INT * number_accepted,+                  LONG_INT * index_cost_acceptances,+                  LONG_INT * number_acceptances_saved,+                  LONG_INT * recent_number_generated,+                  LONG_INT * number_generated,+                  LONG_INT * index_parameter_generations,+                  STATE * current_generated_state, STATE * last_saved_state,+#if ASA_SAMPLE+                  FILE * ptr_asa_out,+#endif+                  USER_DEFINES * OPTIONS)+#else+void++accept_new_state (user_random_generator,+                  seed,+                  parameter_minimum,+                  parameter_maximum, current_cost_temperature,+#if ASA_SAMPLE+                  current_user_parameter_temp,+#endif+                  number_parameters,+                  recent_number_acceptances,+                  number_accepted,+                  index_cost_acceptances,+                  number_acceptances_saved,+                  recent_number_generated,+                  number_generated,+                  index_parameter_generations,+                  current_generated_state, last_saved_state,+#if ASA_SAMPLE+                  ptr_asa_out,+#endif+                  OPTIONS)+     double (*user_random_generator) ();+     LONG_INT *seed;+     double *parameter_minimum;+     double *parameter_maximum;+     double *current_cost_temperature;+#if ASA_SAMPLE+     double *current_user_parameter_temp;+#endif+     ALLOC_INT *number_parameters;+     LONG_INT *recent_number_acceptances;+     LONG_INT *number_accepted;+     LONG_INT *index_cost_acceptances;+     LONG_INT *number_acceptances_saved;+     LONG_INT *recent_number_generated;+     LONG_INT *number_generated;+     LONG_INT *index_parameter_generations;+     STATE *current_generated_state;+     STATE *last_saved_state;+#if ASA_SAMPLE+     FILE *ptr_asa_out;+#endif+     USER_DEFINES *OPTIONS;++#endif+{+#if USER_ACCEPTANCE_TEST+#else+  double delta_cost;+#if USER_ACCEPT_ASYMP_EXP+  double q;+#endif+#endif+  double prob_test, unif_test;+  double curr_cost_temp;+  ALLOC_INT index_v;+#if ASA_SAMPLE+  LONG_INT active_params;+  double weight_param_ind, weight_aver, range;+#endif++  /* update accepted and generated count */+  ++*number_acceptances_saved;+  ++*recent_number_generated;+  ++*number_generated;+  OPTIONS->N_Generated = *number_generated;++  /* increment the parameter index generation for each parameter */+  if (OPTIONS->Sequential_Parameters >= 0) {+    /* ignore parameters with too small a range */+    if (!PARAMETER_RANGE_TOO_SMALL (OPTIONS->Sequential_Parameters))+      ++index_parameter_generations[OPTIONS->Sequential_Parameters];+  } else {+    VFOR (index_v) {+      if (!PARAMETER_RANGE_TOO_SMALL (index_v))+        ++index_parameter_generations[index_v];+    }+  }++  /* effective cost function for testing acceptance criteria,+     calculate the cost difference and divide by the temperature */+  curr_cost_temp = *current_cost_temperature;+#if USER_ACCEPTANCE_TEST+  if (OPTIONS->Cost_Acceptance_Flag == TRUE) {+    if (OPTIONS->User_Acceptance_Flag == TRUE) {+      unif_test = ZERO;+      OPTIONS->User_Acceptance_Flag = FALSE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+    } else {+      unif_test = ONE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+    }+  } else {+    OPTIONS->Acceptance_Test (current_generated_state->cost,+                              parameter_minimum,+                              parameter_maximum, *number_parameters, OPTIONS);+    if (OPTIONS->User_Acceptance_Flag == TRUE) {+      unif_test = ZERO;+      OPTIONS->User_Acceptance_Flag = FALSE;+    } else {+      unif_test = ONE;+    }+  }+  prob_test = OPTIONS->Prob_Bias;+#else /* USER_ACCEPTANCE_TEST */++#if USER_COST_SCHEDULE+  curr_cost_temp =+    (OPTIONS->Cost_Schedule (*current_cost_temperature, OPTIONS)+     + (double) EPS_DOUBLE);+#endif+  delta_cost = (current_generated_state->cost - last_saved_state->cost)+    / (curr_cost_temp + (double) EPS_DOUBLE);++#if USER_ACCEPT_ASYMP_EXP+  q = OPTIONS->Asymp_Exp_Param;+  if (fabs (ONE - q) < (double) EPS_DOUBLE)+    prob_test = MIN (ONE, (F_EXP (EXPONENT_CHECK (-delta_cost))));+  else if ((ONE - (ONE - q) * delta_cost) < (double) EPS_DOUBLE)+    prob_test = MIN (ONE, (F_EXP (EXPONENT_CHECK (-delta_cost))));+  else+    prob_test = MIN (ONE, F_POW ((ONE - (ONE - q) * delta_cost),+                                 (ONE / (ONE - q))));+#else /* USER_ACCEPT_ASYMP_EXP */++#if USER_ACCEPT_THRESHOLD       /* USER_ACCEPT_THRESHOLD */+  prob_test = delta_cost <= 1.0 ? 1.0 : 0.0;+#else /* Metropolis */+  prob_test = MIN (ONE, (F_EXP (EXPONENT_CHECK (-delta_cost))));+#endif /* USER_ACCEPT_THRESHOLD */++#endif /* USER_ACCEPT_ASYMP_EXP */++  unif_test = (*user_random_generator) (seed);+#endif /* USER_ACCEPTANCE_TEST */++#if ASA_SAMPLE+  active_params = 0;+  weight_aver = ZERO;+  VFOR (index_v) {+    /* ignore parameters with too small a range */+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    ++active_params;+    range = parameter_maximum[index_v] - parameter_minimum[index_v];+    weight_param_ind = TWO * (fabs ((last_saved_state->parameter[index_v]+                                     -+                                     current_generated_state->+                                     parameter[index_v]) / range)+                              + current_user_parameter_temp[index_v])+      * F_LOG (ONE + ONE / current_user_parameter_temp[index_v]);+    weight_aver += weight_param_ind;+    OPTIONS->Bias_Generated[index_v] = ONE / weight_param_ind;+  }+  weight_aver /= (double) active_params;+  OPTIONS->Average_Weights = weight_aver;+  if (prob_test >= unif_test) {+    OPTIONS->Bias_Acceptance = prob_test;+  } else {+    OPTIONS->Bias_Acceptance = ONE - prob_test;+  }++#if ASA_PRINT+  if (OPTIONS->Limit_Weights < OPTIONS->Average_Weights) {+    fprintf (ptr_asa_out, ":SAMPLE#\n");+    if (prob_test >= unif_test) {+      fprintf (ptr_asa_out,+#if INT_LONG+               ":SAMPLE+ %10ld %*.*g %*.*g %*.*g %*.*g\n",+#else+               ":SAMPLE+ %10d %*.*g %*.*g %*.*g\n",+#endif+               OPTIONS->N_Accepted,+               G_FIELD, G_PRECISION, current_generated_state->cost,+               G_FIELD, G_PRECISION, *current_cost_temperature,+               G_FIELD, G_PRECISION, OPTIONS->Bias_Acceptance,+               G_FIELD, G_PRECISION, OPTIONS->Average_Weights);+      VFOR (index_v) {+        /* ignore parameters with too small a range */+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+        range = parameter_maximum[index_v] - parameter_minimum[index_v];+        fprintf (ptr_asa_out,+#if INT_ALLOC+                 ":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",+#else+#if INT_LONG+                 ":SAMPLE %11ld %*.*g %*.*g %*.*g %*.*g\n",+#else+                 ":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",+#endif+#endif+                 index_v,+                 G_FIELD, G_PRECISION,+                 current_generated_state->parameter[index_v], G_FIELD,+                 G_PRECISION, current_user_parameter_temp[index_v],+                 G_FIELD, G_PRECISION, OPTIONS->Bias_Generated[index_v],+                 G_FIELD, G_PRECISION, range);+      }+    } else {+      fprintf (ptr_asa_out,+#if INT_LONG+               ":SAMPLE %11ld %*.*g %*.*g %*.*g %*.*g\n",+#else+               ":SAMPLE %11d %*.*g %*.*g %*.*g\n",+#endif+               OPTIONS->N_Accepted,+               G_FIELD, G_PRECISION, last_saved_state->cost,+               G_FIELD, G_PRECISION, *current_cost_temperature,+               G_FIELD, G_PRECISION, OPTIONS->Bias_Acceptance,+               G_FIELD, G_PRECISION, OPTIONS->Average_Weights);+      VFOR (index_v) {+        /* ignore parameters with too small a range */+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+        range = parameter_maximum[index_v] - parameter_minimum[index_v];+        fprintf (ptr_asa_out,+#if INT_ALLOC+                 ":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",+#else+#if INT_LONG+                 ":SAMPLE %11ld %*.*g %*.*g %*.*g %*.*g\n",+#else+                 ":SAMPLE %11d %*.*g %*.*g %*.*g %*.*g\n",+#endif+#endif+                 index_v,+                 G_FIELD, G_PRECISION,+                 last_saved_state->parameter[index_v], G_FIELD,+                 G_PRECISION, current_user_parameter_temp[index_v],+                 G_FIELD, G_PRECISION, OPTIONS->Bias_Generated[index_v],+                 G_FIELD, G_PRECISION, range);+      }+    }+  }+#endif+#endif /* ASA_SAMPLE */++  /* accept/reject the new state */+  if (prob_test >= unif_test) {+    /* copy current state to the last saved state */++    last_saved_state->cost = current_generated_state->cost;+    VFOR (index_v) {+      /* ignore parameters with too small a range */+      if (PARAMETER_RANGE_TOO_SMALL (index_v))+        continue;+      last_saved_state->parameter[index_v] =+        current_generated_state->parameter[index_v];+    }++    /* update acceptance counts */+    ++*recent_number_acceptances;+    ++*number_accepted;+    ++*index_cost_acceptances;+    *number_acceptances_saved = *number_accepted;+    OPTIONS->N_Accepted = *number_accepted;+  }+}++/***********************************************************************+* reanneal+*	Readjust temperatures of generating and acceptance functions+***********************************************************************/+#if HAVE_ANSI+void++reanneal (double *parameter_minimum,+          double *parameter_maximum,+          double *tangents,+          double *maximum_tangent,+          double *current_cost_temperature,+          double *initial_cost_temperature,+          double *temperature_scale_cost,+          double *current_user_parameter_temp,+          double *initial_user_parameter_temp,+          double *temperature_scale_parameters,+          ALLOC_INT * number_parameters,+          int *parameter_type,+          LONG_INT * index_cost_acceptances,+          LONG_INT * index_parameter_generations,+          STATE * last_saved_state,+          STATE * best_generated_state, USER_DEFINES * OPTIONS)+#else+void++reanneal (parameter_minimum,+          parameter_maximum,+          tangents,+          maximum_tangent,+          current_cost_temperature,+          initial_cost_temperature,+          temperature_scale_cost,+          current_user_parameter_temp,+          initial_user_parameter_temp,+          temperature_scale_parameters,+          number_parameters,+          parameter_type,+          index_cost_acceptances,+          index_parameter_generations,+          last_saved_state, best_generated_state, OPTIONS)+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *maximum_tangent;+     double *current_cost_temperature;+     double *initial_cost_temperature;+     double *temperature_scale_cost;+     double *current_user_parameter_temp;+     double *initial_user_parameter_temp;+     double *temperature_scale_parameters;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     LONG_INT *index_cost_acceptances;+     LONG_INT *index_parameter_generations;+     STATE *last_saved_state;+     STATE *best_generated_state;+     USER_DEFINES *OPTIONS;+#endif+{+  ALLOC_INT index_v;+  int cost_test;+  double tmp_var_db3;+  double new_temperature;+  double log_new_temperature_ratio;+  double log_init_cur_temp_ratio;+  double temperature_rescale_power;+  double cost_best, cost_last;+  double tmp_dbl, tmp_dbl1;++  double xnumber_parameters[1];++  cost_test = cost_function_test (last_saved_state->cost,+                                  last_saved_state->parameter,+                                  parameter_minimum,+                                  parameter_maximum, number_parameters,+                                  xnumber_parameters);++  if (OPTIONS->Reanneal_Parameters == TRUE) {+    VFOR (index_v) {+      if (NO_REANNEAL (index_v))+        continue;++      /* use the temp double to prevent overflow */+      tmp_dbl = (double) index_parameter_generations[index_v];++      /* skip parameters with too small range or integer parameters */+      if (OPTIONS->Include_Integer_Parameters == TRUE) {+        if (PARAMETER_RANGE_TOO_SMALL (index_v))+          continue;+      } else {+        if (PARAMETER_RANGE_TOO_SMALL (index_v) ||+            INTEGER_PARAMETER (index_v))+          continue;+      }++      /* ignore parameters with too small tangents */+      if (fabs (tangents[index_v]) < (double) EPS_DOUBLE)+        continue;++      /* reset the index of parameter generations appropriately */+#if USER_REANNEAL_PARAMETERS+      new_temperature =+        fabs (OPTIONS->+              Reanneal_Params_Function (current_user_parameter_temp+                                        [index_v], tangents[index_v],+                                        *maximum_tangent, OPTIONS));+#else+      new_temperature =+        fabs (FUNCTION_REANNEAL_PARAMS+              (current_user_parameter_temp[index_v], tangents[index_v],+               *maximum_tangent));+#endif+      if (new_temperature < initial_user_parameter_temp[index_v]) {+        log_init_cur_temp_ratio =+          fabs (F_LOG (((double) EPS_DOUBLE+                        + initial_user_parameter_temp[index_v])+                       / ((double) EPS_DOUBLE + new_temperature)));+        tmp_dbl = (double) EPS_DOUBLE+          + F_POW (log_init_cur_temp_ratio+                   / temperature_scale_parameters[index_v],+                   *xnumber_parameters+#if QUENCH_PARAMETERS+                   / OPTIONS->User_Quench_Param_Scale[index_v]);+#else+          );+#endif+      } else {+        tmp_dbl = ONE;+      }++      /* Reset index_parameter_generations if index reset too large,+         and also reset the initial_user_parameter_temp, to achieve+         the same new temperature. */+      while (tmp_dbl > ((double) MAXIMUM_REANNEAL_INDEX)) {+        log_new_temperature_ratio =+          -temperature_scale_parameters[index_v] * F_POW (tmp_dbl,+#if QUENCH_PARAMETERS+                                                          OPTIONS->+                                                          User_Quench_Param_Scale+                                                          [index_v]+#else+                                                          ONE+#endif+                                                          /+                                                          *xnumber_parameters);+        log_new_temperature_ratio =+          EXPONENT_CHECK (log_new_temperature_ratio);+        new_temperature =+          initial_user_parameter_temp[index_v] *+          F_EXP (log_new_temperature_ratio);+        tmp_dbl /= (double) REANNEAL_SCALE;+        temperature_rescale_power = ONE / F_POW ((double) REANNEAL_SCALE,+#if QUENCH_PARAMETERS+                                                 OPTIONS->+                                                 User_Quench_Param_Scale+                                                 [index_v]+#else+                                                 ONE+#endif+                                                 / *xnumber_parameters);+        initial_user_parameter_temp[index_v] =+          new_temperature * F_POW (initial_user_parameter_temp[index_v] /+                                   new_temperature,+                                   temperature_rescale_power);+      }+      /* restore from temporary double */+      index_parameter_generations[index_v] = (LONG_INT) tmp_dbl;+    }+  }++  if (OPTIONS->Reanneal_Cost == 0) {+    ;+  } else if (OPTIONS->Reanneal_Cost < -1) {+    *index_cost_acceptances = 1;+  } else {+    /* reanneal : Reset the current cost temp and rescale the+       index of cost acceptances. */++    cost_best = best_generated_state->cost;+    cost_last = last_saved_state->cost;+#if USER_REANNEAL_COST+    cost_test = OPTIONS->Reanneal_Cost_Function (&cost_best,+                                                 &cost_last,+                                                 initial_cost_temperature,+                                                 current_cost_temperature,+                                                 OPTIONS);+    tmp_dbl1 = *current_cost_temperature;+#else+    cost_test = TRUE;+    if (OPTIONS->Reanneal_Cost == 1) {+      /* (re)set the initial cost_temperature */+      tmp_dbl = MAX (fabs (cost_last), fabs (cost_best));+      tmp_dbl = MAX (tmp_dbl, fabs (cost_best - cost_last));+      tmp_dbl = MAX ((double) EPS_DOUBLE, tmp_dbl);+      *initial_cost_temperature = MIN (*initial_cost_temperature, tmp_dbl);+    }++    tmp_dbl = (double) *index_cost_acceptances;++    tmp_dbl1 = MAX (fabs (cost_last - cost_best), *current_cost_temperature);+    tmp_dbl1 = MAX ((double) EPS_DOUBLE, tmp_dbl1);+    tmp_dbl1 = MIN (tmp_dbl1, *initial_cost_temperature);+#endif /* USER_REANNEAL_COST */+    if (cost_test == TRUE && (*current_cost_temperature > tmp_dbl1)) {+      tmp_var_db3 =+        fabs (F_LOG (((double) EPS_DOUBLE + *initial_cost_temperature) /+                     (tmp_dbl1)));+      tmp_dbl = (double) EPS_DOUBLE + F_POW (tmp_var_db3+                                             / *temperature_scale_cost,+                                             *xnumber_parameters+#if QUENCH_COST+                                             /+                                             OPTIONS->+                                             User_Quench_Cost_Scale[0]);+#else+        );+#endif+    } else {+      log_init_cur_temp_ratio =+        fabs (F_LOG (((double) EPS_DOUBLE + *initial_cost_temperature) /+                     ((double) EPS_DOUBLE + *current_cost_temperature)));+      tmp_dbl = (double) EPS_DOUBLE+        + F_POW (log_init_cur_temp_ratio+                 / *temperature_scale_cost, *xnumber_parameters+#if QUENCH_COST+                 / OPTIONS->User_Quench_Cost_Scale[0]+#else+#endif+        );+    }++    /* reset index_cost_temperature if index reset too large */+    while (tmp_dbl > ((double) MAXIMUM_REANNEAL_INDEX)) {+      log_new_temperature_ratio = -*temperature_scale_cost * F_POW (tmp_dbl,+#if QUENCH_COST+                                                                    OPTIONS->+                                                                    User_Quench_Cost_Scale+                                                                    [0]+#else+                                                                    ONE+#endif+                                                                    /+                                                                    *xnumber_parameters);+      log_new_temperature_ratio = EXPONENT_CHECK (log_new_temperature_ratio);+      new_temperature =+        *initial_cost_temperature * F_EXP (log_new_temperature_ratio);+      tmp_dbl /= (double) REANNEAL_SCALE;+      temperature_rescale_power = ONE / F_POW ((double) REANNEAL_SCALE,+#if QUENCH_COST+                                               OPTIONS->+                                               User_Quench_Cost_Scale[0]+#else+                                               ONE+#endif+                                               / *xnumber_parameters);+      *initial_cost_temperature =+        new_temperature * F_POW (*initial_cost_temperature /+                                 new_temperature, temperature_rescale_power);+    }+    *index_cost_acceptances = (LONG_INT) tmp_dbl;+#if USER_ACCEPTANCE_TEST+    OPTIONS->Cost_Temp_Init = *initial_cost_temperature;+#endif+  }+}++/***********************************************************************+* cost_derivatives+*	This procedure calculates the derivatives of the cost function+*	with respect to its parameters.  The first derivatives are+*	used as a sensitivity measure for reannealing.  The second+*	derivatives are calculated only if *curvature_flag=TRUE;+*	these are a measure of the covariance of the fit when a+*	minimum is found.+***********************************************************************/+  /* Calculate the numerical derivatives of the best+     generated state found so far */++  /* In this implementation of ASA, no checks are made for+   *valid_state_generated_flag=FALSE for differential neighbors+   to the current best state. */++  /* Assuming no information is given about the metric of the parameter+     space, use simple Cartesian space to calculate curvatures. */++#if HAVE_ANSI+void+cost_derivatives (double (*user_cost_function)++                   +                  (double *, double *, double *, double *, double *,+                   ALLOC_INT *, int *, int *, int *, USER_DEFINES *),+                  double *parameter_minimum, double *parameter_maximum,+                  double *tangents, double *curvature,+                  double *maximum_tangent, ALLOC_INT * number_parameters,+                  int *parameter_type, int *exit_status,+                  int *curvature_flag, int *valid_state_generated_flag,+                  LONG_INT * number_invalid_generated_states,+                  STATE * current_generated_state,+                  STATE * best_generated_state, FILE * ptr_asa_out,+                  USER_DEFINES * OPTIONS)+#else+void++cost_derivatives (user_cost_function,+                  parameter_minimum,+                  parameter_maximum,+                  tangents,+                  curvature,+                  maximum_tangent,+                  number_parameters,+                  parameter_type,+                  exit_status,+                  curvature_flag,+                  valid_state_generated_flag,+                  number_invalid_generated_states,+                  current_generated_state,+                  best_generated_state, ptr_asa_out, OPTIONS)+     double (*user_cost_function) ();+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *curvature;+     double *maximum_tangent;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     int *exit_status;+     int *curvature_flag;+     int *valid_state_generated_flag;+     LONG_INT *number_invalid_generated_states;+     STATE *current_generated_state;+     STATE *best_generated_state;+     FILE *ptr_asa_out;+     USER_DEFINES *OPTIONS;+#endif+{+  ALLOC_INT index_v, index_vv, index_v_vv, index_vv_v;+  LONG_INT saved_num_invalid_gen_states;+#if ASA_PRINT+  LONG_INT tmp_saved;+#endif+  double parameter_v, parameter_vv, parameter_v_offset, parameter_vv_offset;+  double recent_best_cost;+  double new_cost_state_1, new_cost_state_2, new_cost_state_3;+  double delta_parameter_v, delta_parameter_vv;+  int immediate_flag;+  double xnumber_parameters[1];++  if (OPTIONS->Curvature_0 == TRUE)+    *curvature_flag = FALSE;+  if (OPTIONS->Curvature_0 == -1)+    *curvature_flag = TRUE;++  /* save Immediate_Exit flag */+  immediate_flag = OPTIONS->Immediate_Exit;++  /* save the best cost */+  recent_best_cost = best_generated_state->cost;++  /* copy the best state into the current state */+  VFOR (index_v) {+    /* ignore parameters with too small ranges */+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    current_generated_state->parameter[index_v] =+      best_generated_state->parameter[index_v];+  }++  saved_num_invalid_gen_states = (*number_invalid_generated_states);++  /* set parameters (& possibly constraints) to best state */+  *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+  OPTIONS->User_Acceptance_Flag = TRUE;+  OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+  current_generated_state->cost =+    user_cost_function (current_generated_state->parameter,+                        parameter_minimum,+                        parameter_maximum,+                        tangents,+                        curvature,+                        number_parameters,+                        parameter_type,+                        valid_state_generated_flag, exit_status, OPTIONS);+  if (cost_function_test (current_generated_state->cost,+                          current_generated_state->parameter,+                          parameter_minimum,+                          parameter_maximum, number_parameters,+                          xnumber_parameters) == 0) {+    *exit_status = INVALID_COST_FUNCTION_DERIV;+    return;+  }+  if (*valid_state_generated_flag == FALSE)+    ++(*number_invalid_generated_states);++  if (OPTIONS->User_Tangents == TRUE) {+    *valid_state_generated_flag = FALSE;+#if USER_ACCEPTANCE_TEST+    OPTIONS->User_Acceptance_Flag = TRUE;+    OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+    current_generated_state->cost =+      user_cost_function (current_generated_state->parameter,+                          parameter_minimum,+                          parameter_maximum,+                          tangents,+                          curvature,+                          number_parameters,+                          parameter_type,+                          valid_state_generated_flag, exit_status, OPTIONS);+    if (cost_function_test (current_generated_state->cost,+                            current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum, number_parameters,+                            xnumber_parameters) == 0) {+      *exit_status = INVALID_COST_FUNCTION_DERIV;+      return;+    }+    if (*valid_state_generated_flag == FALSE)+      ++(*number_invalid_generated_states);+  } else {+    /* calculate tangents */+    VFOR (index_v) {+      if (NO_REANNEAL (index_v)) {+        tangents[index_v] = ZERO;+        continue;+      }+      /* skip parameters with too small range or integer parameters */+      if (OPTIONS->Include_Integer_Parameters == TRUE) {+        if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+          tangents[index_v] = ZERO;+          continue;+        }+      } else {+        if (PARAMETER_RANGE_TOO_SMALL (index_v) ||+            INTEGER_PARAMETER (index_v)) {+          tangents[index_v] = ZERO;+          continue;+        }+      }++      /* save the v_th parameter and delta_parameter */+      parameter_v = best_generated_state->parameter[index_v];+#if DELTA_PARAMETERS+      delta_parameter_v = OPTIONS->User_Delta_Parameter[index_v];+#else+      delta_parameter_v = OPTIONS->Delta_X;+#endif++      parameter_v_offset = (ONE + delta_parameter_v) * parameter_v;+      if (parameter_v_offset > parameter_maximum[index_v] ||+          parameter_v_offset < parameter_minimum[index_v]) {+        delta_parameter_v = -delta_parameter_v;+        parameter_v_offset = (ONE + delta_parameter_v) * parameter_v;+      }++      /* generate the first sample point */+      current_generated_state->parameter[index_v] = parameter_v_offset;+      *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+      OPTIONS->User_Acceptance_Flag = TRUE;+      OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+      current_generated_state->cost =+        user_cost_function (current_generated_state->parameter,+                            parameter_minimum,+                            parameter_maximum,+                            tangents,+                            curvature,+                            number_parameters,+                            parameter_type,+                            valid_state_generated_flag, exit_status, OPTIONS);+      if (cost_function_test+          (current_generated_state->cost,+           current_generated_state->parameter, parameter_minimum,+           parameter_maximum, number_parameters, xnumber_parameters) == 0) {+        *exit_status = INVALID_COST_FUNCTION_DERIV;+        return;+      }+      if (*valid_state_generated_flag == FALSE)+        ++(*number_invalid_generated_states);+      new_cost_state_1 = current_generated_state->cost;++      /* restore the parameter state */+      current_generated_state->parameter[index_v] = parameter_v;++      /* calculate the numerical derivative */+      tangents[index_v] = (new_cost_state_1 - recent_best_cost)+        / (delta_parameter_v * parameter_v + (double) EPS_DOUBLE);++    }+  }++  /* find the maximum |tangent| from all tangents */+  *maximum_tangent = 0;+  VFOR (index_v) {+    if (NO_REANNEAL (index_v))+      continue;++    /* ignore too small ranges and integer parameters types */+    if (OPTIONS->Include_Integer_Parameters == TRUE) {+      if (PARAMETER_RANGE_TOO_SMALL (index_v))+        continue;+    } else {+      if (PARAMETER_RANGE_TOO_SMALL (index_v)+          || INTEGER_PARAMETER (index_v))+        continue;+    }++    /* find the maximum |tangent| (from all tangents) */+    if (fabs (tangents[index_v]) > *maximum_tangent) {+      *maximum_tangent = fabs (tangents[index_v]);+    }+  }++  if (*curvature_flag == TRUE || *curvature_flag == -1) {+    /* calculate diagonal curvatures */+    VFOR (index_v) {+      if (NO_REANNEAL (index_v)) {+        index_v_vv = ROW_COL_INDEX (index_v, index_v);+        curvature[index_v_vv] = ZERO;+        continue;+      }+      /* skip parameters with too small range or integer parameters */+      if (OPTIONS->Include_Integer_Parameters == TRUE) {+        if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+          index_v_vv = ROW_COL_INDEX (index_v, index_v);+          curvature[index_v_vv] = ZERO;+          continue;+        }+      } else {+        if (PARAMETER_RANGE_TOO_SMALL (index_v) ||+            INTEGER_PARAMETER (index_v)) {+          index_v_vv = ROW_COL_INDEX (index_v, index_v);+          curvature[index_v_vv] = ZERO;+          continue;+        }+      }++      /* save the v_th parameter and delta_parameter */+      parameter_v = best_generated_state->parameter[index_v];+#if DELTA_PARAMETERS+      delta_parameter_v = OPTIONS->User_Delta_Parameter[index_v];+#else+      delta_parameter_v = OPTIONS->Delta_X;+#endif++      if (parameter_v + delta_parameter_v * fabs (parameter_v)+          > parameter_maximum[index_v]) {+        /* generate the first sample point */+        current_generated_state->parameter[index_v] =+          parameter_v - TWO * delta_parameter_v * fabs (parameter_v);+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_1 = current_generated_state->cost;++        /* generate the second sample point */+        current_generated_state->parameter[index_v] =+          parameter_v - delta_parameter_v * fabs (parameter_v);++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_2 = current_generated_state->cost;++        /* restore the parameter state */+        current_generated_state->parameter[index_v] = parameter_v;++        /* index_v_vv: row index_v, column index_v */+        index_v_vv = ROW_COL_INDEX (index_v, index_v);++        /* calculate and store the curvature */+        curvature[index_v_vv] =+          (recent_best_cost - TWO * new_cost_state_2+           + new_cost_state_1) / (delta_parameter_v * delta_parameter_v+                                  * parameter_v * parameter_v ++                                  (double) EPS_DOUBLE);+      } else if (parameter_v - delta_parameter_v * fabs (parameter_v)+                 < parameter_minimum[index_v]) {+        /* generate the first sample point */+        current_generated_state->parameter[index_v] =+          parameter_v + TWO * delta_parameter_v * fabs (parameter_v);+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_1 = current_generated_state->cost;++        /* generate the second sample point */+        current_generated_state->parameter[index_v] =+          parameter_v + delta_parameter_v * fabs (parameter_v);++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_2 = current_generated_state->cost;++        /* restore the parameter state */+        current_generated_state->parameter[index_v] = parameter_v;++        /* index_v_vv: row index_v, column index_v */+        index_v_vv = ROW_COL_INDEX (index_v, index_v);++        /* calculate and store the curvature */+        curvature[index_v_vv] =+          (recent_best_cost - TWO * new_cost_state_2+           + new_cost_state_1) / (delta_parameter_v * delta_parameter_v+                                  * parameter_v * parameter_v ++                                  (double) EPS_DOUBLE);+      } else {+        /* generate the first sample point */+        parameter_v_offset = (ONE + delta_parameter_v) * parameter_v;+        current_generated_state->parameter[index_v] = parameter_v_offset;+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_1 = current_generated_state->cost;++        /* generate the second sample point */+        current_generated_state->parameter[index_v] =+          (ONE - delta_parameter_v) * parameter_v;++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_2 = current_generated_state->cost;++        /* restore the parameter state */+        current_generated_state->parameter[index_v] = parameter_v;++        /* index_v_vv: row index_v, column index_v */+        index_v_vv = ROW_COL_INDEX (index_v, index_v);++        /* calculate and store the curvature */+        curvature[index_v_vv] =+          (new_cost_state_2 - TWO * recent_best_cost+           + new_cost_state_1) / (delta_parameter_v * delta_parameter_v+                                  * parameter_v * parameter_v ++                                  (double) EPS_DOUBLE);+      }+    }++    /* calculate off-diagonal curvatures */+    VFOR (index_v) {+      /* save the v_th parameter and delta_x */+      parameter_v = current_generated_state->parameter[index_v];+#if DELTA_PARAMETERS+      delta_parameter_v = OPTIONS->User_Delta_Parameter[index_v];+#else+      delta_parameter_v = OPTIONS->Delta_X;+#endif++      VFOR (index_vv) {+        /* index_v_vv: row index_v, column index_vv */+        index_v_vv = ROW_COL_INDEX (index_v, index_vv);+        index_vv_v = ROW_COL_INDEX (index_vv, index_v);++        if (NO_REANNEAL (index_vv) || NO_REANNEAL (index_v)) {+          curvature[index_vv_v] = curvature[index_v_vv] = ZERO;+          continue;+        }++        /* calculate only the upper diagonal */+        if (index_v <= index_vv)+          continue;++        /* skip parms with too small range or integer parameters */+        if (OPTIONS->Include_Integer_Parameters == TRUE) {+          if (PARAMETER_RANGE_TOO_SMALL (index_v) ||+              PARAMETER_RANGE_TOO_SMALL (index_vv)) {+            curvature[index_vv_v] = curvature[index_v_vv] = ZERO;+            continue;+          }+        } else {+          if (INTEGER_PARAMETER (index_v) ||+              INTEGER_PARAMETER (index_vv) ||+              PARAMETER_RANGE_TOO_SMALL (index_v) ||+              PARAMETER_RANGE_TOO_SMALL (index_vv)) {+            curvature[index_vv_v] = curvature[index_v_vv] = ZERO;+            continue;+          }+        }+        /* save the vv_th parameter and delta_parameter */+        parameter_vv = current_generated_state->parameter[index_vv];+#if DELTA_PARAMETERS+        delta_parameter_vv = OPTIONS->User_Delta_Parameter[index_vv];+#else+        delta_parameter_vv = OPTIONS->Delta_X;+#endif++        /* generate first sample point */+        parameter_v_offset = current_generated_state->parameter[index_v] =+          (ONE + delta_parameter_v) * parameter_v;+        parameter_vv_offset = current_generated_state->parameter[index_vv] =+          (ONE + delta_parameter_vv) * parameter_vv;+        if (parameter_v_offset > parameter_maximum[index_v] ||+            parameter_v_offset < parameter_minimum[index_v]) {+          delta_parameter_v = -delta_parameter_v;+          current_generated_state->parameter[index_v] =+            (ONE + delta_parameter_v) * parameter_v;+        }+        if (parameter_vv_offset > parameter_maximum[index_vv] ||+            parameter_vv_offset < parameter_minimum[index_vv]) {+          delta_parameter_vv = -delta_parameter_vv;+          current_generated_state->parameter[index_vv] =+            (ONE + delta_parameter_vv) * parameter_vv;+        }++        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_1 = current_generated_state->cost;++        /* restore the v_th parameter */+        current_generated_state->parameter[index_v] = parameter_v;++        /* generate second sample point */+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_2 = current_generated_state->cost;++        /* restore the vv_th parameter */+        current_generated_state->parameter[index_vv] = parameter_vv;++        /* generate third sample point */+        current_generated_state->parameter[index_v] =+          (ONE + delta_parameter_v) * parameter_v;+        *valid_state_generated_flag = TRUE;+#if USER_ACCEPTANCE_TEST+        OPTIONS->User_Acceptance_Flag = TRUE;+        OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+        current_generated_state->cost =+          user_cost_function (current_generated_state->parameter,+                              parameter_minimum,+                              parameter_maximum,+                              tangents,+                              curvature,+                              number_parameters,+                              parameter_type,+                              valid_state_generated_flag,+                              exit_status, OPTIONS);+        if (cost_function_test (current_generated_state->cost,+                                current_generated_state->parameter,+                                parameter_minimum,+                                parameter_maximum, number_parameters,+                                xnumber_parameters) == 0) {+          *exit_status = INVALID_COST_FUNCTION_DERIV;+          return;+        }+        if (*valid_state_generated_flag == FALSE)+          ++(*number_invalid_generated_states);+        new_cost_state_3 = current_generated_state->cost;++        /* restore the v_th parameter */+        current_generated_state->parameter[index_v] = parameter_v;++        /* calculate and store the curvature */+        curvature[index_vv_v] = curvature[index_v_vv] =+          (new_cost_state_1 - new_cost_state_2+           - new_cost_state_3 + recent_best_cost)+          / (delta_parameter_v * delta_parameter_vv+             * parameter_v * parameter_vv + (double) EPS_DOUBLE);+      }+    }+  }++  /* restore Immediate_Exit flag */+  OPTIONS->Immediate_Exit = immediate_flag;++  /* restore the best cost function value */+  current_generated_state->cost = recent_best_cost;+#if ASA_PRINT+  tmp_saved = *number_invalid_generated_states - saved_num_invalid_gen_states;+  if (tmp_saved > 0)+#if INT_LONG+    fprintf (ptr_asa_out,+             "Generated %ld invalid states when calculating the derivatives\n",+             tmp_saved);+#else+    fprintf (ptr_asa_out,+             "Generated %d invalid states when calculating the derivatives\n",+             tmp_saved);+#endif+#endif /* ASA_PRINT */+  *number_invalid_generated_states = saved_num_invalid_gen_states;+#if USER_ACCEPTANCE_TEST+  OPTIONS->User_Acceptance_Flag = TRUE;+  OPTIONS->Cost_Acceptance_Flag = FALSE;+#endif+}++/***********************************************************************+* asa_test_asa_options+*       Tests user's selected options+***********************************************************************/+#if HAVE_ANSI+int++asa_test_asa_options (LONG_INT * seed,+                      double *parameter_initial_final,+                      double *parameter_minimum,+                      double *parameter_maximum,+                      double *tangents,+                      double *curvature,+                      ALLOC_INT * number_parameters,+                      int *parameter_type,+                      int *valid_state_generated_flag,+                      int *exit_status,+                      FILE * ptr_asa_out, USER_DEFINES * OPTIONS)+#else+int++asa_test_asa_options (seed,+                      parameter_initial_final,+                      parameter_minimum,+                      parameter_maximum,+                      tangents,+                      curvature,+                      number_parameters,+                      parameter_type,+                      valid_state_generated_flag,+                      exit_status, ptr_asa_out, OPTIONS)+     LONG_INT *seed;+     double *parameter_initial_final;+     double *parameter_minimum;+     double *parameter_maximum;+     double *tangents;+     double *curvature;+     ALLOC_INT *number_parameters;+     int *parameter_type;+     int *valid_state_generated_flag;+     int *exit_status;+     FILE *ptr_asa_out;+     USER_DEFINES *OPTIONS;+#endif /* HAVE_ANSI */+{+  int invalid, index_v;++  invalid = 0;++  if (seed == NULL) {+    strcpy (exit_msg, "*** seed == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (parameter_initial_final == NULL) {+    strcpy (exit_msg, "*** parameter_initial_final == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (parameter_minimum == NULL) {+    strcpy (exit_msg, "*** parameter_minimum == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (parameter_maximum == NULL) {+    strcpy (exit_msg, "*** parameter_maximum == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (tangents == NULL) {+    strcpy (exit_msg, "*** tangents == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Curvature_0 == FALSE || OPTIONS->Curvature_0 == -1) {+    if (curvature == NULL) {+      strcpy (exit_msg, "*** curvature == NULL ***");+      print_string (ptr_asa_out, exit_msg);+      ++invalid;+    }+  }+  if (number_parameters == NULL) {+    strcpy (exit_msg, "*** number_parameters == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (parameter_type == NULL) {+    strcpy (exit_msg, "*** parameter_type == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (valid_state_generated_flag == NULL) {+    strcpy (exit_msg, "*** valid_state_generated_flag == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (exit_status == NULL) {+    strcpy (exit_msg, "*** exit_status == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS == NULL) {+    strcpy (exit_msg, "*** OPTIONS == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }++  VFOR (index_v) if (parameter_minimum[index_v] > parameter_maximum[index_v]) {+    strcpy (exit_msg, "*** parameter_minimum[] > parameter_maximum[] ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+  VFOR (index_v)+    if (parameter_initial_final[index_v] < parameter_minimum[index_v]) {+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    strcpy (exit_msg, "*** parameter_initial[] < parameter_minimum[] ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+  VFOR (index_v)+    if (parameter_initial_final[index_v] > parameter_maximum[index_v]) {+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+    strcpy (exit_msg, "*** parameter_initial[] > parameter_maximum[] ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+  if (*number_parameters < 1) {+    strcpy (exit_msg, "*** *number_parameters < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  VFOR (index_v)+    if (parameter_type[index_v] != -2 && parameter_type[index_v] != 2+        && parameter_type[index_v] != -1 && parameter_type[index_v] != 1) {+    strcpy (exit_msg,+            "*** parameter_type[] != -2 && parameter_type[] != 2 && parameter_type[] != -1 && parameter_type[] != 1 ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }++  if (OPTIONS_FILE != FALSE && OPTIONS_FILE != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONS_FILE != FALSE && OPTIONS_FILE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS_FILE_DATA != FALSE && OPTIONS_FILE_DATA != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONS_FILE_DATA != FALSE && OPTIONS_FILE_DATA != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (RECUR_OPTIONS_FILE != FALSE && RECUR_OPTIONS_FILE != TRUE) {+    strcpy (exit_msg,+            "*** RECUR_OPTIONS_FILE != FALSE && RECUR_OPTIONS_FILE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (RECUR_OPTIONS_FILE_DATA != FALSE && RECUR_OPTIONS_FILE_DATA != TRUE) {+    strcpy (exit_msg,+            "*** RECUR_OPTIONS_FILE_DATA != FALSE && RECUR_OPTIONS_FILE_DATA != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (COST_FILE != FALSE && COST_FILE != TRUE) {+    strcpy (exit_msg, "*** COST_FILE != FALSE && COST_FILE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_LIB != FALSE && ASA_LIB != TRUE) {+    strcpy (exit_msg, "*** ASA_LIB != FALSE && ASA_LIB != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MY_TEMPLATE != FALSE && MY_TEMPLATE != TRUE) {+    strcpy (exit_msg, "*** MY_TEMPLATE != FALSE && MY_TEMPLATE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_LIB != FALSE && ASA_TEMPLATE_LIB != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_LIB != FALSE && ASA_TEMPLATE_LIB != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (HAVE_ANSI != FALSE && HAVE_ANSI != TRUE) {+    strcpy (exit_msg, "*** HAVE_ANSI != FALSE && HAVE_ANSI != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (IO_PROTOTYPES != FALSE && IO_PROTOTYPES != TRUE) {+    strcpy (exit_msg,+            "*** IO_PROTOTYPES != FALSE && IO_PROTOTYPES != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (TIME_CALC != FALSE && TIME_CALC != TRUE) {+    strcpy (exit_msg, "*** TIME_CALC != FALSE && TIME_CALC != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (TIME_STD != FALSE && TIME_STD != TRUE) {+    strcpy (exit_msg, "*** TIME_STD != FALSE && TIME_STD != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (TIME_GETRUSAGE != FALSE && TIME_GETRUSAGE != TRUE) {+    strcpy (exit_msg,+            "*** TIME_GETRUSAGE != FALSE && TIME_GETRUSAGE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (INT_LONG != FALSE && INT_LONG != TRUE) {+    strcpy (exit_msg, "*** INT_LONG != FALSE && INT_LONG != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (INT_ALLOC != FALSE && INT_ALLOC != TRUE) {+    strcpy (exit_msg, "*** INT_ALLOC != FALSE && INT_ALLOC != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (SMALL_FLOAT < ZERO) {+    strcpy (exit_msg, "*** SMALL_FLOAT < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MIN_DOUBLE < ZERO) {+    strcpy (exit_msg, "*** MIN_DOUBLE < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MAX_DOUBLE < ZERO) {+    strcpy (exit_msg, "*** MAX_DOUBLE < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (EPS_DOUBLE < ZERO) {+    strcpy (exit_msg, "*** EPS_DOUBLE < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (CHECK_EXPONENT != FALSE && CHECK_EXPONENT != TRUE) {+    strcpy (exit_msg,+            "*** CHECK_EXPONENT != FALSE && CHECK_EXPONENT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (NO_PARAM_TEMP_TEST != FALSE && NO_PARAM_TEMP_TEST != TRUE) {+    strcpy (exit_msg,+            "*** NO_PARAM_TEMP_TEST != FALSE && NO_PARAM_TEMP_TEST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (NO_COST_TEMP_TEST != FALSE && NO_COST_TEMP_TEST != TRUE) {+    strcpy (exit_msg,+            "*** NO_COST_TEMP_TEST != FALSE && NO_COST_TEMP_TEST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (SELF_OPTIMIZE != FALSE && SELF_OPTIMIZE != TRUE) {+    strcpy (exit_msg,+            "*** SELF_OPTIMIZE != FALSE && SELF_OPTIMIZE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEST != FALSE && ASA_TEST != TRUE) {+    strcpy (exit_msg, "*** ASA_TEST != FALSE && ASA_TEST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEST_POINT != FALSE && ASA_TEST_POINT != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEST_POINT != FALSE && ASA_TEST_POINT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE != FALSE) {+    strcpy (exit_msg, "*** ASA_TEMPLATE != FALSE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_ASA_OUT_PID != FALSE && ASA_TEMPLATE_ASA_OUT_PID != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_ASA_OUT_PID != FALSE && ASA_TEMPLATE_ASA_OUT_PID != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_MULTIPLE != FALSE && ASA_TEMPLATE_MULTIPLE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_MULTIPLE != FALSE && ASA_TEMPLATE_MULTIPLE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_SELFOPT != FALSE && ASA_TEMPLATE_SELFOPT != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_SELFOPT != FALSE && ASA_TEMPLATE_SELFOPT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_SAMPLE != FALSE && ASA_TEMPLATE_SAMPLE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_SAMPLE != FALSE && ASA_TEMPLATE_SAMPLE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_QUEUE != FALSE && ASA_TEMPLATE_QUEUE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_QUEUE != FALSE && ASA_TEMPLATE_QUEUE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_PARALLEL != FALSE && ASA_TEMPLATE_PARALLEL != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_PARALLEL != FALSE && ASA_TEMPLATE_PARALLEL != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_TEMPLATE_SAVE != FALSE && ASA_TEMPLATE_SAVE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_TEMPLATE_SAVE != FALSE && ASA_TEMPLATE_SAVE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_INITIAL_COST_TEMP != FALSE && USER_INITIAL_COST_TEMP != TRUE) {+    strcpy (exit_msg,+            "*** USER_INITIAL_COST_TEMP != FALSE && USER_INITIAL_COST_TEMP != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (RATIO_TEMPERATURE_SCALES != FALSE && RATIO_TEMPERATURE_SCALES != TRUE) {+    strcpy (exit_msg,+            "*** RATIO_TEMPERATURE_SCALES != FALSE && RATIO_TEMPERATURE_SCALES != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_INITIAL_PARAMETERS_TEMPS != FALSE+      && USER_INITIAL_PARAMETERS_TEMPS != TRUE) {+    strcpy (exit_msg,+            "*** USER_INITIAL_PARAMETERS_TEMPS != FALSE && USER_INITIAL_PARAMETERS_TEMPS != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (DELTA_PARAMETERS != FALSE && DELTA_PARAMETERS != TRUE) {+    strcpy (exit_msg,+            "*** DELTA_PARAMETERS != FALSE && DELTA_PARAMETERS != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (QUENCH_PARAMETERS != FALSE && QUENCH_PARAMETERS != TRUE) {+    strcpy (exit_msg,+            "*** QUENCH_PARAMETERS != FALSE && QUENCH_PARAMETERS != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (QUENCH_COST != FALSE && QUENCH_COST != TRUE) {+    strcpy (exit_msg, "*** QUENCH_COST != FALSE && QUENCH_COST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (QUENCH_PARAMETERS_SCALE != FALSE && QUENCH_PARAMETERS_SCALE != TRUE) {+    strcpy (exit_msg,+            "*** QUENCH_PARAMETERS_SCALE != FALSE && QUENCH_PARAMETERS_SCALE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (QUENCH_COST_SCALE != FALSE && QUENCH_COST_SCALE != TRUE) {+    strcpy (exit_msg,+            "*** QUENCH_COST_SCALE != FALSE && QUENCH_COST_SCALE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONAL_DATA_DBL != FALSE && OPTIONAL_DATA_DBL != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONAL_DATA_DBL != FALSE && OPTIONAL_DATA_DBL != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONAL_DATA_INT != FALSE && OPTIONAL_DATA_INT != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONAL_DATA_INT != FALSE && OPTIONAL_DATA_INT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONAL_DATA_PTR != FALSE && OPTIONAL_DATA_PTR != TRUE) {+    strcpy (exit_msg,+            "*** OPTIONAL_DATA_PTR != FALSE && OPTIONAL_DATA_PTR != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_COST_SCHEDULE != FALSE && USER_COST_SCHEDULE != TRUE) {+    strcpy (exit_msg,+            "*** USER_COST_SCHEDULE != FALSE && USER_COST_SCHEDULE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_ACCEPT_ASYMP_EXP != FALSE && USER_ACCEPT_ASYMP_EXP != TRUE) {+    strcpy (exit_msg,+            "*** USER_ACCEPT_ASYMP_EXP != FALSE && USER_ACCEPT_ASYMP_EXP != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_ACCEPT_THRESHOLD != FALSE && USER_ACCEPT_THRESHOLD != TRUE) {+    strcpy (exit_msg,+            "*** USER_ACCEPT_THRESHOLD != FALSE && USER_ACCEPT_THRESHOLD != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_ACCEPTANCE_TEST != FALSE && USER_ACCEPTANCE_TEST != TRUE) {+    strcpy (exit_msg,+            "*** USER_ACCEPTANCE_TEST != FALSE && USER_ACCEPTANCE_TEST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_GENERATING_FUNCTION != FALSE && USER_GENERATING_FUNCTION != TRUE) {+    strcpy (exit_msg,+            "*** USER_GENERATING_FUNCTION != FALSE && USER_GENERATING_FUNCTION != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_REANNEAL_COST != FALSE && USER_REANNEAL_COST != TRUE) {+    strcpy (exit_msg,+            "*** USER_REANNEAL_COST != FALSE && USER_REANNEAL_COST != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_REANNEAL_PARAMETERS != FALSE && USER_REANNEAL_PARAMETERS != TRUE) {+    strcpy (exit_msg,+            "*** USER_REANNEAL_PARAMETERS != FALSE && USER_REANNEAL_PARAMETERS != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MAXIMUM_REANNEAL_INDEX < 1) {+    strcpy (exit_msg, "*** MAXIMUM_REANNEAL_INDEX < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (REANNEAL_SCALE < ZERO) {+    strcpy (exit_msg, "*** REANNEAL_SCALE < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_SAMPLE != FALSE && ASA_SAMPLE != TRUE) {+    strcpy (exit_msg, "*** ASA_SAMPLE != FALSE && ASA_SAMPLE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_QUEUE != FALSE && ASA_QUEUE != TRUE) {+    strcpy (exit_msg, "*** ASA_QUEUE != FALSE && ASA_QUEUE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_RESOLUTION != FALSE && ASA_RESOLUTION != TRUE) {+    strcpy (exit_msg,+            "*** ASA_RESOLUTION != FALSE && ASA_RESOLUTION != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FITLOC != FALSE && FITLOC != TRUE) {+    strcpy (exit_msg, "*** FITLOC != FALSE && FITLOC != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FITLOC_ROUND != FALSE && FITLOC_ROUND != TRUE) {+    strcpy (exit_msg,+            "*** FITLOC_ROUND != FALSE && FITLOC_ROUND != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FITLOC_PRINT != FALSE && FITLOC_PRINT != TRUE) {+    strcpy (exit_msg,+            "*** FITLOC_PRINT != FALSE && FITLOC_PRINT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (MULTI_MIN != FALSE && MULTI_MIN != TRUE) {+    strcpy (exit_msg, "*** MULTI_MIN != FALSE && MULTI_MIN != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if MULTI_MIN+  if (OPTIONS->Multi_Number <= 0) {+    strcpy (exit_msg, "*** OPTIONS->Multi_Number <= 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  VFOR (index_v) {+    if (((OPTIONS->Multi_Grid[index_v]) != (OPTIONS->Multi_Grid[index_v]))+        || OPTIONS->Multi_Grid[index_v] < 0) {+      strcpy (exit_msg,+              "*** (OPTIONS->Multi_Grid[]) != (OPTIONS->Multi_Grid[]) || OPTIONS->Multi_Grid[] < 0 ***");+      print_string_index (ptr_asa_out, exit_msg, index_v);+      ++invalid;+    }+  }+  if (OPTIONS->Multi_Specify != 0 && OPTIONS->Multi_Specify != 1) {+    strcpy (exit_msg,+            "*** OPTIONS->Multi_Specify != 0 && OPTIONS->Multi_Specify != 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+  if (ASA_PARALLEL != FALSE && ASA_PARALLEL != TRUE) {+    strcpy (exit_msg,+            "*** ASA_PARALLEL != FALSE && ASA_PARALLEL != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_SAVE != FALSE && ASA_SAVE != TRUE) {+    strcpy (exit_msg, "*** ASA_SAVE != FALSE && ASA_SAVE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_SAVE_OPT != FALSE && ASA_SAVE_OPT != TRUE) {+    strcpy (exit_msg,+            "*** ASA_SAVE_OPT != FALSE && ASA_SAVE_OPT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_SAVE_BACKUP != FALSE && ASA_SAVE_BACKUP != TRUE) {+    strcpy (exit_msg,+            "*** ASA_SAVE_BACKUP != FALSE && ASA_SAVE_BACKUP != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PIPE != FALSE && ASA_PIPE != TRUE) {+    strcpy (exit_msg, "*** ASA_PIPE != FALSE && ASA_PIPE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PIPE_FILE != FALSE && ASA_PIPE_FILE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_PIPE_FILE != FALSE && ASA_PIPE_FILE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (SYSTEM_CALL != FALSE && SYSTEM_CALL != TRUE) {+    strcpy (exit_msg, "*** SYSTEM_CALL != FALSE && SYSTEM_CALL != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FDLIBM_POW != FALSE && FDLIBM_POW != TRUE) {+    strcpy (exit_msg, "*** FDLIBM_POW != FALSE && FDLIBM_POW != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FDLIBM_LOG != FALSE && FDLIBM_LOG != TRUE) {+    strcpy (exit_msg, "*** FDLIBM_LOG != FALSE && FDLIBM_LOG != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (FDLIBM_EXP != FALSE && FDLIBM_EXP != TRUE) {+    strcpy (exit_msg, "*** FDLIBM_EXP != FALSE && FDLIBM_EXP != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PRINT != FALSE && ASA_PRINT != TRUE) {+    strcpy (exit_msg, "*** ASA_PRINT != FALSE && ASA_PRINT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (USER_ASA_OUT != FALSE && USER_ASA_OUT != TRUE) {+    strcpy (exit_msg,+            "*** USER_ASA_OUT != FALSE && USER_ASA_OUT != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PRINT_INTERMED != FALSE && ASA_PRINT_INTERMED != TRUE) {+    strcpy (exit_msg,+            "*** ASA_PRINT_INTERMED != FALSE && ASA_PRINT_INTERMED != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (ASA_PRINT_MORE != FALSE && ASA_PRINT_MORE != TRUE) {+    strcpy (exit_msg,+            "*** ASA_PRINT_MORE != FALSE && ASA_PRINT_MORE != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (G_FIELD < 0) {+    strcpy (exit_msg, "*** G_FIELD < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (G_PRECISION < 0) {+    strcpy (exit_msg, "*** G_PRECISION < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }++  if (OPTIONS->Limit_Acceptances < 0) {+    strcpy (exit_msg, "*** Limit_Acceptances < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Limit_Generated < 0) {+    strcpy (exit_msg, "*** Limit_Generated < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Limit_Invalid_Generated_States < 0) {+    strcpy (exit_msg, "*** Limit_Invalid_Generated_States < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Accepted_To_Generated_Ratio <= ZERO) {+    strcpy (exit_msg, "*** Accepted_To_Generated_Ratio <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Cost_Precision <= ZERO) {+    strcpy (exit_msg, "*** Cost_Precision <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Maximum_Cost_Repeat < 0) {+    strcpy (exit_msg, "*** Maximum_Cost_Repeat < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Number_Cost_Samples == 0 || OPTIONS->Number_Cost_Samples == -1) {+    strcpy (exit_msg,+            "*** Number_Cost_Samples == 0 || Number_Cost_Samples == -1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Temperature_Ratio_Scale <= ZERO) {+    strcpy (exit_msg, "*** Temperature_Ratio_Scale <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Cost_Parameter_Scale_Ratio <= ZERO) {+    strcpy (exit_msg, "*** Cost_Parameter_Scale_Ratio <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Temperature_Anneal_Scale <= ZERO) {+    strcpy (exit_msg, "*** Temperature_Anneal_Scale <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if USER_INITIAL_COST_TEMP+  if (OPTIONS->User_Cost_Temperature[0] <= ZERO) {+    strcpy (exit_msg, "*** User_Cost_Temperature[0] <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+  if (OPTIONS->Include_Integer_Parameters != FALSE+      && OPTIONS->Include_Integer_Parameters != TRUE) {+    strcpy (exit_msg, "");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->User_Initial_Parameters != FALSE+      && OPTIONS->User_Initial_Parameters != TRUE) {+    strcpy (exit_msg,+            "*** User_Initial_Parameters != FALSE && User_Initial_Parameters != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Sequential_Parameters >= *number_parameters) {+    strcpy (exit_msg, "*** Sequential_Parameters >= *number_parameters ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Initial_Parameter_Temperature <= ZERO) {+    strcpy (exit_msg, "*** Initial_Parameter_Temperature <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if RATIO_TEMPERATURE_SCALES+  VFOR (index_v) if (OPTIONS->User_Temperature_Ratio[index_v] <= ZERO) {+    strcpy (exit_msg, "*** User_Temperature_Ratio[] <= ZERO ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+#endif+#if USER_INITIAL_PARAMETERS_TEMPS+  VFOR (index_v) if (OPTIONS->User_Parameter_Temperature[index_v] <= ZERO) {+    strcpy (exit_msg, "*** User_Parameter_Temperature[] <= ZERO ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+#endif+  if (OPTIONS->Acceptance_Frequency_Modulus < 0) {+    strcpy (exit_msg, "*** Acceptance_Frequency_Modulus < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Generated_Frequency_Modulus < 0) {+    strcpy (exit_msg, "*** Generated_Frequency_Modulus < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Reanneal_Cost == -1) {+    strcpy (exit_msg, "*** Reanneal_Cost == -1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Reanneal_Parameters != FALSE+      && OPTIONS->Reanneal_Parameters != TRUE) {+    strcpy (exit_msg,+            "*** Reanneal_Parameters != FALSE && Reanneal_Parameters != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Delta_X <= ZERO) {+    strcpy (exit_msg, "*** Delta_X <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if DELTA_PARAMETERS+  VFOR (index_v) if (OPTIONS->User_Delta_Parameter[index_v] <= ZERO) {+    strcpy (exit_msg, "*** User_Delta_Parameter[] <= ZERO ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+#endif+  if (OPTIONS->User_Tangents != FALSE && OPTIONS->User_Tangents != TRUE) {+    strcpy (exit_msg,+            "*** User_Tangents != FALSE && User_Tangents != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Curvature_0 != -1 && OPTIONS->Curvature_0 != FALSE+      && OPTIONS->Curvature_0 != TRUE) {+    strcpy (exit_msg,+            "*** Curvature_0 -1 && Curvature_0 != FALSE && Curvature_0 != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#if QUENCH_PARAMETERS+  VFOR (index_v) if (OPTIONS->User_Quench_Param_Scale[index_v] <= ZERO) {+    strcpy (exit_msg, "*** User_Quench_Param_Scale[] <= ZERO ***");+    print_string_index (ptr_asa_out, exit_msg, index_v);+    ++invalid;+  }+#endif+#if QUENCH_COST+  if (OPTIONS->User_Quench_Cost_Scale[0] <= ZERO) {+    strcpy (exit_msg, "*** User_Quench_Cost_Scale[0] <= ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if OPTIONAL_DATA_DBL+  if (OPTIONS->Asa_Data_Dim_Dbl < 1) {+    strcpy (exit_msg, "*** Asa_Data_Dim_Dbl < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Asa_Data_Dbl == NULL) {+    strcpy (exit_msg, "*** Asa_Data_Dbl == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if ASA_SAVE+  if (OPTIONS->Random_Array_Dim < 1) {+    strcpy (exit_msg, "*** Random_Array_Dim < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Random_Array == NULL) {+    strcpy (exit_msg, "*** Random_Array == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if OPTIONAL_DATA_INT+  if (OPTIONS->Asa_Data_Dim_Int < 1) {+    strcpy (exit_msg, "*** Asa_Data_Dim_Int < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Asa_Data_Int == NULL) {+    strcpy (exit_msg, "*** Asa_Data_Int == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if OPTIONAL_DATA_PTR+  if (OPTIONS->Asa_Data_Dim_Ptr < 1) {+    strcpy (exit_msg, "*** Asa_Data_Dim_Ptr < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Asa_Data_Ptr == NULL) {+    strcpy (exit_msg, "*** Asa_Data_Ptr == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_ASA_OUT+  if (OPTIONS->Asa_Out_File == NULL) {+    strcpy (exit_msg, "*** Asa_Out_File == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_COST_SCHEDULE+  if (OPTIONS->Cost_Schedule == NULL) {+    strcpy (exit_msg, "*** Cost_Schedule == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_ACCEPTANCE_TEST+  if (OPTIONS->Acceptance_Test == NULL) {+    strcpy (exit_msg, "*** Acceptance_Test == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->User_Acceptance_Flag != FALSE+      && OPTIONS->User_Acceptance_Flag != TRUE) {+    strcpy (exit_msg,+            "*** User_Acceptance_Flag != FALSE && User_Acceptance_Flag != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Cost_Acceptance_Flag != FALSE+      && OPTIONS->Cost_Acceptance_Flag != TRUE) {+    strcpy (exit_msg,+            "*** Cost_Acceptance_Flag != FALSE && Cost_Acceptance_Flag != TRUE ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_GENERATING_FUNCTION+  if (OPTIONS->Generating_Distrib == NULL) {+    strcpy (exit_msg, "*** Generating_Distrib == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_REANNEAL_COST+  if (OPTIONS->Reanneal_Cost_Function == NULL) {+    strcpy (exit_msg, "*** Reanneal_Cost_Function == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if USER_REANNEAL_PARAMETERS+  if (OPTIONS->Reanneal_Params_Function == NULL) {+    strcpy (exit_msg, "*** Reanneal_Params_Function == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if ASA_SAMPLE+  if (OPTIONS->Bias_Generated == NULL) {+    strcpy (exit_msg, "*** Bias_Generated == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Limit_Weights < ZERO) {+    strcpy (exit_msg, "*** Limit_Weights < ZERO ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if ASA_QUEUE+  if (OPTIONS->Queue_Size < 0) {+    strcpy (exit_msg, "*** Queue_Size < 0 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Queue_Size > 0) {+    if (OPTIONS->Queue_Resolution == NULL) {+      strcpy (exit_msg, "*** Queue_Resolution == NULL ***");+      print_string (ptr_asa_out, exit_msg);+      ++invalid;+    }+  }+#endif+#if ASA_RESOLUTION+  if (OPTIONS->Coarse_Resolution == NULL) {+    strcpy (exit_msg, "*** Coarse_Resolution == NULL ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif+#if ASA_PARALLEL+  if (OPTIONS->Gener_Block < 1) {+    strcpy (exit_msg, "*** Gener_Block < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Gener_Block_Max < 1) {+    strcpy (exit_msg, "*** Gener_Block_Max < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+  if (OPTIONS->Gener_Mov_Avr < 1) {+    strcpy (exit_msg, "*** Gener_Mov_Avr < 1 ***");+    print_string (ptr_asa_out, exit_msg);+    ++invalid;+  }+#endif++  return (invalid);+}++/***********************************************************************+* cost_function_test+*       Tests user's returned cost function values and parameters+***********************************************************************/+#if HAVE_ANSI+int++cost_function_test (double cost,+                    double *parameter,+                    double *parameter_minimum,+                    double *parameter_maximum,+                    ALLOC_INT * number_parameters, double *xnumber_parameters)+#else+int++cost_function_test (cost,+                    parameter,+                    parameter_minimum, parameter_maximum,+                    number_parameters, xnumber_parameters)+     double cost;+     double *parameter;+     double *parameter_minimum;+     double *parameter_maximum;+     ALLOC_INT *number_parameters;+     double *xnumber_parameters;+#endif /* HAVE_ANSI */+{+  ALLOC_INT index_v;+  int test_flag;++  test_flag = 1;++  if (((cost) != (cost)) || (cost < -MAX_DOUBLE || cost > MAX_DOUBLE))+    test_flag = 0;++  *xnumber_parameters = (double) *number_parameters;+  VFOR (index_v) {+    if (PARAMETER_RANGE_TOO_SMALL (index_v)) {+      *xnumber_parameters -= 1.0;+      continue;+    }+    if (parameter[index_v] < parameter_minimum[index_v] ||+        parameter[index_v] > parameter_maximum[index_v]) {+      test_flag = 0;+    }+  }++  return (test_flag);+}++/***********************************************************************+* print_string+*	This prints the designated string+***********************************************************************/+#if HAVE_ANSI+void+print_string (FILE * ptr_asa_out, char *string)+#else+void+print_string (ptr_asa_out, string)+     FILE *ptr_asa_out;+     char *string;+#endif /* HAVE_ANSI */+{+#if INCL_STDOUT+  printf ("\n\n%s\n\n", string);+#endif /* INCL_STDOUT */+#if ASA_PRINT+  fprintf (ptr_asa_out, "\n\n%s\n\n", string);+#else+#endif+}++/***********************************************************************+* print_string_index+*	This prints the designated string and index+***********************************************************************/+#if HAVE_ANSI+void+print_string_index (FILE * ptr_asa_out, char *string, ALLOC_INT index)+#else+void+print_string_index (ptr_asa_out, string, index)+     FILE *ptr_asa_out;+     char *string;+     ALLOC_INT index;+#endif /* HAVE_ANSI */+{+#if INCL_STDOUT+#if INT_ALLOC+  printf ("\n\n%s index = %d\n\n", string, index);+#else /* INT_ALLOC */+#if INT_LONG+  printf ("\n\n%s index = %ld\n\n", string, index);+#else /* INT_LONG */+  printf ("\n\n%s index = %ld\n\n", string, index);+#endif /* INT_LONG */+#endif /* INT_ALLOC */+#endif /* INCL_STDOUT */++#if ASA_PRINT+#if INT_ALLOC+  fprintf (ptr_asa_out, "\n\n%s index = %d\n\n", string, index);+#else /* INT_ALLOC */+#if INT_LONG+  fprintf (ptr_asa_out, "\n\n%s index = %ld\n\n", string, index);+#else /* INT_LONG */+  fprintf (ptr_asa_out, "\n\n%s index = %d\n\n", string, index);+#endif /* INT_LONG */+#endif /* INT_ALLOC */+#else /* ASA_PRINT */+  ;+#endif /* ASA_PRINT */+}++#if ASA_PRINT+/***********************************************************************+* print_state+*	Prints a description of the current state of the system+***********************************************************************/+void+print_state (double *parameter_minimum,+             double *parameter_maximum,+             double *tangents,+             double *curvature,+             double *current_cost_temperature,+             double *current_user_parameter_temp,+             double *accepted_to_generated_ratio,+             ALLOC_INT * number_parameters,+             int *curvature_flag,+             LONG_INT * number_accepted,+             LONG_INT * index_cost_acceptances,+             LONG_INT * number_generated,+             LONG_INT * number_invalid_generated_states,+             STATE * last_saved_state,+             STATE * best_generated_state,+             FILE * ptr_asa_out, USER_DEFINES * OPTIONS)+{+  ALLOC_INT index_v;+  ALLOC_INT index_vv, index_v_vv;++  fprintf (ptr_asa_out, "\n");+#if TIME_CALC+  print_time ("", ptr_asa_out);+#endif++  if (OPTIONS->Curvature_0 == TRUE)+    *curvature_flag = FALSE;+  if (OPTIONS->Curvature_0 == -1)+    *curvature_flag = TRUE;++#if INT_LONG+  fprintf (ptr_asa_out,+           "*index_cost_acceptances = %ld, *current_cost_temperature = %*.*g\n",+           *index_cost_acceptances,+           G_FIELD, G_PRECISION, *current_cost_temperature);+  fprintf (ptr_asa_out, "*accepted_to_generated_ratio = %*.*g,\+ *number_invalid... = %ld\n", G_FIELD, G_PRECISION, *accepted_to_generated_ratio, (*number_invalid_generated_states));+  fprintf (ptr_asa_out,+           "*number_generated = %ld, *number_accepted = %ld\n",+           *number_generated, *number_accepted);+#else+  fprintf (ptr_asa_out,+           "*index_cost_acceptances = %d, *current_cost_temperature = %*.*g\n",+           *index_cost_acceptances,+           G_FIELD, G_PRECISION, *current_cost_temperature);+  fprintf (ptr_asa_out, "*accepted_to_generated_ratio = %*.*g,\+ *number_invalid... = %d\n", G_FIELD, G_PRECISION, *accepted_to_generated_ratio, *number_invalid_generated_states);+  fprintf (ptr_asa_out,+           "*number_generated = %d, *number_accepted = %d\n",+           *number_generated, *number_accepted);+#endif++  fprintf (ptr_asa_out, "best...->cost = %*.*g,\+ last...->cost = %*.*g\n", G_FIELD, G_PRECISION, best_generated_state->cost, G_FIELD, G_PRECISION, last_saved_state->cost);++  /* Note that tangents will not be calculated until reanneal+     is called, and therefore their listing in the printout only+     is relevant then */++  fprintf (ptr_asa_out,+           "index_v  best...->parameter current_parameter_temp\ttangent\n");+  VFOR (index_v) {+    /* ignore too small ranges */+#if DROPPED_PARAMETERS+    if (PARAMETER_RANGE_TOO_SMALL (index_v))+      continue;+#endif+    fprintf (ptr_asa_out,+#if INT_ALLOC+             "%d\t%*.*g\t\t%*.*g\t%*.*g\n",+#else+#if INT_LONG+             "%ld\t%*.*g\t\t%*.*g\t%*.*g\n",+#else+             "%d\t%*.*g\t\t%*.*g\t%*.*g\n",+#endif+#endif+             index_v,+             G_FIELD, G_PRECISION, best_generated_state->parameter[index_v],+             G_FIELD, G_PRECISION, current_user_parameter_temp[index_v],+             G_FIELD, G_PRECISION, tangents[index_v]);+  }++  if (*curvature_flag == TRUE) {+    /* print curvatures */+    VFOR (index_v) {+      /* ignore too small ranges */+      if (PARAMETER_RANGE_TOO_SMALL (index_v))+        continue;+      fprintf (ptr_asa_out, "\n");+      VFOR (index_vv) {+        /* only print upper diagonal of matrix */+        if (index_v < index_vv)+          continue;+        /* ignore too small ranges (index_vv) */+        if (PARAMETER_RANGE_TOO_SMALL (index_vv))+          continue;++        /* index_v_vv: row index_v, column index_vv */+        index_v_vv = ROW_COL_INDEX (index_v, index_vv);++        if (index_v == index_vv) {+          fprintf (ptr_asa_out,+#if INT_ALLOC+                   "curvature[%d][%d] = %*.*g\n",+#else+#if INT_LONG+                   "curvature[%ld][%ld] = %*.*g\n",+#else+                   "curvature[%d][%d] = %*.*g\n",+#endif+#endif+                   index_v, index_vv,+                   G_FIELD, G_PRECISION, curvature[index_v_vv]);+        } else {+          fprintf (ptr_asa_out,+#if INT_ALLOC+                   "curvature[%d][%d] = %*.*g \t = curvature[%d][%d]\n",+#else+#if INT_LONG+                   "curvature[%ld][%ld] = %*.*g \t = curvature[%ld][%ld]\n",+#else+                   "curvature[%d][%d] = %*.*g \t = curvature[%d][%d]\n",+#endif+#endif+                   index_v, index_vv,+                   G_FIELD, G_PRECISION, curvature[index_v_vv],+                   index_vv, index_v);+        }+      }+    }+  }+  fprintf (ptr_asa_out, "\n");+  fflush (ptr_asa_out);++}++/***********************************************************************+* print_asa_options+*	Prints user's selected options+***********************************************************************/+void+print_asa_options (FILE * ptr_asa_out, USER_DEFINES * OPTIONS)+{+  fprintf (ptr_asa_out, "\t\tADAPTIVE SIMULATED ANNEALING\n\n");++  fprintf (ptr_asa_out, "%s\n\n", ASA_ID);++  fprintf (ptr_asa_out, "OPTIONS_FILE = %d\n", (int) OPTIONS_FILE);+  fprintf (ptr_asa_out, "OPTIONS_FILE_DATA = %d\n", (int) OPTIONS_FILE_DATA);+  fprintf (ptr_asa_out, "RECUR_OPTIONS_FILE = %d\n",+           (int) RECUR_OPTIONS_FILE);+  fprintf (ptr_asa_out, "RECUR_OPTIONS_FILE_DATA = %d\n",+           (int) RECUR_OPTIONS_FILE_DATA);+  fprintf (ptr_asa_out, "COST_FILE = %d\n", (int) COST_FILE);+  fprintf (ptr_asa_out, "ASA_LIB = %d\n", (int) ASA_LIB);+  fprintf (ptr_asa_out, "HAVE_ANSI = %d\n", (int) HAVE_ANSI);+  fprintf (ptr_asa_out, "IO_PROTOTYPES = %d\n", (int) IO_PROTOTYPES);+  fprintf (ptr_asa_out, "TIME_CALC = %d\n", (int) TIME_CALC);+  fprintf (ptr_asa_out, "TIME_STD = %d\n", (int) TIME_STD);+  fprintf (ptr_asa_out, "TIME_GETRUSAGE = %d\n", (int) TIME_GETRUSAGE);+  fprintf (ptr_asa_out, "INT_LONG = %d\n", (int) INT_LONG);+  fprintf (ptr_asa_out, "INT_ALLOC = %d\n", (int) INT_ALLOC);+  fprintf (ptr_asa_out, "SMALL_FLOAT = %*.*g\n",+           G_FIELD, G_PRECISION, (double) SMALL_FLOAT);+  fprintf (ptr_asa_out, "MIN_DOUBLE = %*.*g\n",+           G_FIELD, G_PRECISION, (double) MIN_DOUBLE);+  fprintf (ptr_asa_out, "MAX_DOUBLE = %*.*g\n",+           G_FIELD, G_PRECISION, (double) MAX_DOUBLE);+  fprintf (ptr_asa_out, "EPS_DOUBLE = %*.*g\n",+           G_FIELD, G_PRECISION, (double) EPS_DOUBLE);+  fprintf (ptr_asa_out, "CHECK_EXPONENT = %d\n", (int) CHECK_EXPONENT);+  fprintf (ptr_asa_out, "NO_PARAM_TEMP_TEST = %d\n",+           (int) NO_PARAM_TEMP_TEST);+  fprintf (ptr_asa_out, "NO_COST_TEMP_TEST = %d\n", (int) NO_COST_TEMP_TEST);+  fprintf (ptr_asa_out, "SELF_OPTIMIZE = %d\n", (int) SELF_OPTIMIZE);+  fprintf (ptr_asa_out, "ASA_TEST = %d\n", (int) ASA_TEST);+  fprintf (ptr_asa_out, "ASA_TEST_POINT = %d\n", (int) ASA_TEST_POINT);+  fprintf (ptr_asa_out, "ASA_TEMPLATE = %d\n", (int) ASA_TEMPLATE);+  fprintf (ptr_asa_out, "MY_TEMPLATE = %d\n", (int) MY_TEMPLATE);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_LIB = %d\n", (int) ASA_TEMPLATE_LIB);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_ASA_OUT_PID = %d\n",+           (int) ASA_TEMPLATE_ASA_OUT_PID);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_MULTIPLE = %d\n",+           (int) ASA_TEMPLATE_MULTIPLE);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_SELFOPT = %d\n",+           (int) ASA_TEMPLATE_SELFOPT);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_SAMPLE = %d\n",+           (int) ASA_TEMPLATE_SAMPLE);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_QUEUE = %d\n",+           (int) ASA_TEMPLATE_QUEUE);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_PARALLEL = %d\n",+           (int) ASA_TEMPLATE_PARALLEL);+  fprintf (ptr_asa_out, "ASA_TEMPLATE_SAVE = %d\n", (int) ASA_TEMPLATE_SAVE);+  fprintf (ptr_asa_out, "USER_INITIAL_COST_TEMP = %d\n",+           (int) USER_INITIAL_COST_TEMP);+  fprintf (ptr_asa_out, "RATIO_TEMPERATURE_SCALES = %d\n",+           (int) RATIO_TEMPERATURE_SCALES);+  fprintf (ptr_asa_out, "USER_INITIAL_PARAMETERS_TEMPS = %d\n",+           (int) USER_INITIAL_PARAMETERS_TEMPS);+  fprintf (ptr_asa_out, "DELTA_PARAMETERS = %d\n", (int) DELTA_PARAMETERS);+  fprintf (ptr_asa_out, "QUENCH_PARAMETERS = %d\n", (int) QUENCH_PARAMETERS);+  fprintf (ptr_asa_out, "QUENCH_COST = %d\n", (int) QUENCH_COST);+  fprintf (ptr_asa_out, "QUENCH_PARAMETERS_SCALE = %d\n",+           (int) QUENCH_PARAMETERS_SCALE);+  fprintf (ptr_asa_out, "QUENCH_COST_SCALE = %d\n", (int) QUENCH_COST_SCALE);+  fprintf (ptr_asa_out, "OPTIONAL_DATA_DBL = %d\n", (int) OPTIONAL_DATA_DBL);+  fprintf (ptr_asa_out, "OPTIONAL_DATA_INT = %d\n", (int) OPTIONAL_DATA_INT);+  fprintf (ptr_asa_out, "OPTIONAL_DATA_PTR = %d\n", (int) OPTIONAL_DATA_PTR);+  fprintf (ptr_asa_out, "USER_COST_SCHEDULE = %d\n",+           (int) USER_COST_SCHEDULE);+  fprintf (ptr_asa_out, "USER_ACCEPT_ASYMP_EXP = %d\n",+           (int) USER_ACCEPT_ASYMP_EXP);+  fprintf (ptr_asa_out, "USER_ACCEPT_THRESHOLD = %d\n",+           (int) USER_ACCEPT_THRESHOLD);+  fprintf (ptr_asa_out, "USER_ACCEPTANCE_TEST = %d\n",+           (int) USER_ACCEPTANCE_TEST);+  fprintf (ptr_asa_out, "USER_GENERATING_FUNCTION = %d\n",+           (int) USER_GENERATING_FUNCTION);+  fprintf (ptr_asa_out, "USER_REANNEAL_COST = %d\n",+           (int) USER_REANNEAL_COST);+  fprintf (ptr_asa_out, "USER_REANNEAL_PARAMETERS = %d\n",+           (int) USER_REANNEAL_PARAMETERS);+#if INT_LONG+  fprintf (ptr_asa_out, "MAXIMUM_REANNEAL_INDEX = %ld\n",+           (LONG_INT) MAXIMUM_REANNEAL_INDEX);+#else+  fprintf (ptr_asa_out, "MAXIMUM_REANNEAL_INDEX = %d\n",+           (LONG_INT) MAXIMUM_REANNEAL_INDEX);+#endif+  fprintf (ptr_asa_out, "REANNEAL_SCALE = %*.*g\n",+           G_FIELD, G_PRECISION, (double) REANNEAL_SCALE);+  fprintf (ptr_asa_out, "ASA_SAMPLE = %d\n", (int) ASA_SAMPLE);+  fprintf (ptr_asa_out, "ASA_QUEUE = %d\n", (int) ASA_QUEUE);+  fprintf (ptr_asa_out, "ASA_RESOLUTION = %d\n", (int) ASA_RESOLUTION);+  fprintf (ptr_asa_out, "FITLOC = %d\n", (int) FITLOC);+  fprintf (ptr_asa_out, "FITLOC_ROUND = %d\n", (int) FITLOC_ROUND);+  fprintf (ptr_asa_out, "FITLOC_PRINT = %d\n", (int) FITLOC_PRINT);+  fprintf (ptr_asa_out, "MULTI_MIN = %d\n", (int) MULTI_MIN);+  fprintf (ptr_asa_out, "ASA_PARALLEL = %d\n", (int) ASA_PARALLEL);+  fprintf (ptr_asa_out, "FDLIBM_POW = %d\n", (int) FDLIBM_POW);+  fprintf (ptr_asa_out, "FDLIBM_LOG = %d\n", (int) FDLIBM_LOG);+  fprintf (ptr_asa_out, "FDLIBM_EXP = %d\n\n", (int) FDLIBM_EXP);++  fprintf (ptr_asa_out, "ASA_PRINT = %d\n", (int) ASA_PRINT);+  fprintf (ptr_asa_out, "USER_OUT = %s\n", USER_OUT);+#if USER_ASA_OUT+  fprintf (ptr_asa_out, "ASA_OUT = %s\n", OPTIONS->Asa_Out_File);+#else+  fprintf (ptr_asa_out, "ASA_OUT = %s\n", ASA_OUT);+#endif+  fprintf (ptr_asa_out, "USER_ASA_OUT = %d\n", (int) USER_ASA_OUT);+  fprintf (ptr_asa_out, "ASA_PRINT_INTERMED = %d\n",+           (int) ASA_PRINT_INTERMED);+  fprintf (ptr_asa_out, "ASA_PRINT_MORE = %d\n", (int) ASA_PRINT_MORE);+  fprintf (ptr_asa_out, "INCL_STDOUT = %d\n", (int) INCL_STDOUT);+  fprintf (ptr_asa_out, "G_FIELD = %d\n", (int) G_FIELD);+  fprintf (ptr_asa_out, "G_PRECISION = %d\n", (int) G_PRECISION);+  fprintf (ptr_asa_out, "ASA_SAVE = %d\n", (int) ASA_SAVE);+  fprintf (ptr_asa_out, "ASA_SAVE_OPT = %d\n", (int) ASA_SAVE_OPT);+  fprintf (ptr_asa_out, "ASA_SAVE_BACKUP = %d\n", (int) ASA_SAVE_BACKUP);+  fprintf (ptr_asa_out, "ASA_PIPE = %d\n", (int) ASA_PIPE);+  fprintf (ptr_asa_out, "ASA_PIPE_FILE = %d\n", (int) ASA_PIPE_FILE);+  fprintf (ptr_asa_out, "SYSTEM_CALL = %d\n\n", (int) SYSTEM_CALL);++#if INT_LONG+  fprintf (ptr_asa_out, "OPTIONS->Limit_Acceptances = %ld\n",+           (LONG_INT) OPTIONS->Limit_Acceptances);+  fprintf (ptr_asa_out, "OPTIONS->Limit_Generated = %ld\n",+           (LONG_INT) OPTIONS->Limit_Generated);+#else+  fprintf (ptr_asa_out, "OPTIONS->Limit_Acceptances = %d\n",+           (LONG_INT) OPTIONS->Limit_Acceptances);+  fprintf (ptr_asa_out, "OPTIONS->Limit_Generated = %d\n",+           (LONG_INT) OPTIONS->Limit_Generated);+#endif+  fprintf (ptr_asa_out, "OPTIONS->Limit_Invalid_Generated_States = %d\n",+           OPTIONS->Limit_Invalid_Generated_States);+  fprintf (ptr_asa_out, "OPTIONS->Accepted_To_Generated_Ratio = %*.*g\n\n",+           G_FIELD, G_PRECISION, OPTIONS->Accepted_To_Generated_Ratio);++  fprintf (ptr_asa_out, "OPTIONS->Cost_Precision = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Cost_Precision);+  fprintf (ptr_asa_out, "OPTIONS->Maximum_Cost_Repeat = %d\n",+           OPTIONS->Maximum_Cost_Repeat);+  fprintf (ptr_asa_out, "OPTIONS->Number_Cost_Samples = %d\n",+           OPTIONS->Number_Cost_Samples);+  fprintf (ptr_asa_out, "OPTIONS->Temperature_Ratio_Scale = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Temperature_Ratio_Scale);+  fprintf (ptr_asa_out, "OPTIONS->Cost_Parameter_Scale_Ratio = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Cost_Parameter_Scale_Ratio);+  fprintf (ptr_asa_out, "OPTIONS->Temperature_Anneal_Scale = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Temperature_Anneal_Scale);++  fprintf (ptr_asa_out, "OPTIONS->Include_Integer_Parameters = %d\n",+           OPTIONS->Include_Integer_Parameters);+  fprintf (ptr_asa_out, "OPTIONS->User_Initial_Parameters = %d\n",+           OPTIONS->User_Initial_Parameters);+#if INT_ALLOC+  fprintf (ptr_asa_out, "OPTIONS->Sequential_Parameters = %d\n",+           (int) OPTIONS->Sequential_Parameters);+#else+#if INT_LONG+  fprintf (ptr_asa_out, "OPTIONS->Sequential_Parameters = %ld\n",+           (LONG_INT) OPTIONS->Sequential_Parameters);+#else+  fprintf (ptr_asa_out, "OPTIONS->Sequential_Parameters = %d\n",+           (LONG_INT) OPTIONS->Sequential_Parameters);+#endif+#endif+  fprintf (ptr_asa_out, "OPTIONS->Initial_Parameter_Temperature = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Initial_Parameter_Temperature);++  fprintf (ptr_asa_out, "OPTIONS->Acceptance_Frequency_Modulus = %d\n",+           OPTIONS->Acceptance_Frequency_Modulus);+  fprintf (ptr_asa_out, "OPTIONS->Generated_Frequency_Modulus = %d\n",+           OPTIONS->Generated_Frequency_Modulus);+  fprintf (ptr_asa_out, "OPTIONS->Reanneal_Cost = %d\n",+           OPTIONS->Reanneal_Cost);+  fprintf (ptr_asa_out, "OPTIONS->Reanneal_Parameters = %d\n\n",+           OPTIONS->Reanneal_Parameters);++  fprintf (ptr_asa_out, "OPTIONS->Delta_X = %*.*g\n",+           G_FIELD, G_PRECISION, OPTIONS->Delta_X);+  fprintf (ptr_asa_out, "OPTIONS->User_Tangents = %d\n",+           OPTIONS->User_Tangents);+  fprintf (ptr_asa_out, "OPTIONS->Curvature_0 = %d\n", OPTIONS->Curvature_0);+  fprintf (ptr_asa_out, "OPTIONS->Asa_Recursive_Level = %d\n\n",+           OPTIONS->Asa_Recursive_Level);++  fprintf (ptr_asa_out, "\n");+}+#endif /* ASA_PRINT */++#if TIME_CALC+#if TIME_GETRUSAGE+/***********************************************************************+* print_time+*	This calculates the time and runtime and prints it.+***********************************************************************/+#if HAVE_ANSI+void+print_time (char *message, FILE * ptr_asa_out)+#else+void+print_time (message, ptr_asa_out)+     char *message;+     FILE *ptr_asa_out;+#endif /* HAVE_ANSI */+{+  int who = RUSAGE_SELF;        /* Check our own time */+  struct rusage usage;++  /* get the resource usage information */+#if TIME_STD+  syscall (SYS_GETRUSAGE, who, &usage);+#else+  getrusage (who, &usage);+#endif++  /* print the usage time in reasonable form */+  aux_print_time (&usage.ru_utime, message, ptr_asa_out);+}++/***********************************************************************+* aux_print_time+*      auxiliary print the time routine+***********************************************************************/+#if HAVE_ANSI+void+aux_print_time (struct timeval *time, char *message, FILE * ptr_asa_out)+#else+void+aux_print_time (time, message, ptr_asa_out)+     struct timeval *time;+     char *message;+     FILE *ptr_asa_out;+#endif /* HAVE_ANSI */+{+  static double sx;+  double us, s, m, h;+  double ds, dm, dh;++  /* calculate the new microseconds, seconds, minutes, hours+     and the differences since the last call */+  us = (double) ((int) ((double) EPS_DOUBLE + time->tv_usec)) / 1.E6;+  s = (double) ((int) ((double) EPS_DOUBLE + time->tv_sec)) + us;+  ds = s - sx;+  sx = s;++  h = (int) ((double) EPS_DOUBLE + s / 3600.);+  m = (int) ((double) EPS_DOUBLE + s / 60.) - 60. * h;+  s -= (3600. * h + 60. * m);+  dh = (int) ((double) EPS_DOUBLE + ds / 3600.);+  dm = (int) ((double) EPS_DOUBLE + ds / 60.) - 60. * dh;+  ds -= (3600. * dh + 60. * dm);++  /* print the statistics */+  fprintf (ptr_asa_out,+           "%s:time: %gh %gm %gs; incr: %gh %gm %gs\n",+           message, h, m, s, dh, dm, ds);+}+#else /* TIME_GETRUSAGE */+  /* Note that on many machines the time resolution of this algorithm+   * may be less than the other alternatives, e.g., rounding off the+   * number of ticks to the nearest tens of thousands.  Also, because+   * time here is typically indexed by a long integer, there typically+   * is a cycle of time in periods of fractions of an hour.  For+   * example, under Solaris 2.5.1:  The value returned by clock() is+   * defined in microseconds, since the first call to clock(), for+   *  compatibility with  systems that have * CPU clocks with much higher+   * resolution.  Because of this, the value returned will wrap around+   * after accumulating only 2147 seconds of CPU time (about 36 minutes).+   *+   * See asa.h for two places where some additional modifications should+   * be made under SunOS 4.1.x. */++#if HAVE_ANSI+void+print_time (char *message, FILE * ptr_asa_out)+#else+void+print_time (message, ptr_asa_out)+     char *message;+     FILE *ptr_asa_out;+#endif /* HAVE_ANSI */+{+  aux_print_time (clock (), message, ptr_asa_out);++}                               /*print_time */++/***********************************************************************+* aux_print_time+*      auxiliary print the time routine+***********************************************************************/+#if HAVE_ANSI+void+aux_print_time (clock_t time, char *message, FILE * ptr_asa_out)+#else+void+aux_print_time (time, message, ptr_asa_out)+     clock_t time;+     char *message;+     FILE *ptr_asa_out;+#endif /* HAVE_ANSI */+{+  static clock_t previousTime = -1;+  clock_t diffTime;+  double clocksPerSecF = CLOCKS_PER_SEC;+  double timeF, diffF;+  double s, m, h;+  double ds, dm, dh;++  if (previousTime != -1) {+    diffTime = time - previousTime;+    timeF = time;+    diffF = diffTime;+    previousTime = time;++    s = timeF / clocksPerSecF;+    ds = diffF / clocksPerSecF;++    h = (int) ((double) EPS_DOUBLE + s / 3600.);+    m = (int) ((double) EPS_DOUBLE + s / 60.) - 60. * h;+    s -= (3600. * h + 60. * m);+    dh = (int) ((double) EPS_DOUBLE + ds / 3600.);+    dm = (int) ((double) EPS_DOUBLE + ds / 60.) - 60. * dh;+    ds -= (3600. * dh + 60. * dm);++    fprintf (ptr_asa_out,+             "%s:time: %gh %gm %gs; incr: %gh %gm %gs\n",+             message, h, m, s, dh, dm, ds);+  } else {+    /* The first call will be invalid - don't output anything. */+    fprintf (ptr_asa_out, "TIMING PARAMETERS: ticks/sec: %lu\n",+             CLOCKS_PER_SEC);+    previousTime = time;+  }+}                               /* aux_print_time */++#endif /* TIME_GETRUSAGE */++#endif /* TIME_CALC */++#if MULTI_MIN+#if HAVE_ANSI+static int+multi_compare (const void *ii, const void *jj)+#else /* HAVE_ANSI */+static int+multi_compare (ii, jj)+     char *ii;+     char *jj;+#endif /* HAVE_ANSI */+{+  int i;+  int j;++  i = *(int *) ii;+  j = *(int *) jj;++  if (multi_cost_qsort[i] > multi_cost_qsort[j] + (double) EPS_DOUBLE)+    return (1);+  else if (multi_cost_qsort[i] < multi_cost_qsort[j] - (double) EPS_DOUBLE)+    return (-1);+  else+    return (0);+}+#endif /* MULTI_MIN */++#if ASA_PARALLEL+#if HAVE_ANSI+static int+sort_parallel (const void *ii, const void *jj)+#else /* HAVE_ANSI */+static int+sort_parallel (ii, jj)+     void *ii;+     void *jj;+#endif /* HAVE_ANSI */+{+  LONG_INT i;+  LONG_INT j;++  i = *(LONG_INT *) ii;+  j = *(LONG_INT *) jj;++  if (gener_block_state_qsort[i].cost > gener_block_state_qsort[j].cost)+    return (1);+  else if (gener_block_state_qsort[i].cost < gener_block_state_qsort[j].cost)+    return (-1);+  else+    return (0);+}+#endif /* ASA_PARALLEL */+#if HAVE_ANSI+void+Exit_ASA (char *statement)+#else /* HAVE_ANSI */+void+Exit_ASA (statement)+     char *statement;+#endif /* HAVE_ANSI */+{+#if INCL_STDOUT+  printf ("\n\n*** EXIT calloc failed in ASA *** %s\n\n", statement);+#else+  ;+#endif /* INCL_STDOUT */+}
+ cbits/hs_asa.c view
@@ -0,0 +1,4369 @@+/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+* Modified by John Meacham for Haskell interface+***********************************************************************/++#include "asa_usr.h"+++++char user_exit_msg[160];        /* temp storage for exit messages */+FILE *ptr_out;++static double resettable_randflt (LONG_INT * rand_seed, int reset);+static double randflt (LONG_INT * rand_seed);+/***********************************************************************+* main+*	This is a sample calling program to optimize using ASA+***********************************************************************/+int+asa_main (+           hs_cost_func *func, +           int number_parameters,+           double *upper_bounds,+           double *lower_bounds,+           int *type,+           double *main_cost_value,+           double *main_cost_parameters, +           int *main_exit_code,+           long int initial_rand_seed+  )+{+  int i;+  int *exit_code;+  ALLOC_INT n_param;+#if ASA_TEMPLATE_SAMPLE+  FILE *ptr_asa;+#endif+#if MULTI_MIN+  int multi_index;+#endif++  /* pointer to array storage for asa arguments */+  double *parameter_lower_bound, *parameter_upper_bound, *cost_parameters,+    *cost_tangents, *cost_curvature;+  double cost_value;++  int initialize_parameters_value;++  /* the number of parameters to optimize */+  ALLOC_INT *parameter_dimension;++  /* pointer to array storage for parameter type flags */+  int *parameter_int_real;++  /* valid flag for cost function */+  int *cost_flag;++  /* seed for random number generator */+  LONG_INT *rand_seed;++  USER_DEFINES *USER_OPTIONS;++#if MY_TEMPLATE                 /* MY_TEMPLATE_main_decl */+  /* add some declarations if required */+#endif++#if ASA_TEMPLATE_MULTIPLE+  int n_asa, n_trajectory;+  ALLOC_INT index;+#if HAVE_ANSI+  char asa_file[8] = "asa_x_y";+#else+  char asa_file[8];+#endif /* HAVE_ANSI */+#endif /* ASA_TEMPLATE_MULTIPLE */+++  if ((USER_OPTIONS =+       (USER_DEFINES *) calloc (1, sizeof (USER_DEFINES))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): USER_DEFINES");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if OPTIONAL_DATA_PTR+#if ASA_TEMPLATE+  USER_OPTIONS->Asa_Data_Dim_Ptr = 256;+  if ((USER_OPTIONS->Asa_Data_Ptr =+       (OPTIONAL_PTR_TYPE *) calloc (USER_OPTIONS->Asa_Data_Dim_Ptr,+                                     sizeof (OPTIONAL_PTR_TYPE))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): USER_OPTIONS->Asa_Data_Ptr");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* ASA_TEMPLATE */+#endif /* OPTIONAL_DATA_PTR */+++  if (!strcmp (USER_OUT, "STDOUT")) {+#if INCL_STDOUT+    ptr_out = stdout;+#endif /* INCL_STDOUT */+  } else {+    ptr_out = fopen (USER_OUT, "w");+  }+++  fflush (ptr_out);++  if ((rand_seed = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): rand_seed");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  *rand_seed = initial_rand_seed;++  /* initialize random number generator with first call */+  resettable_randflt (rand_seed, 1);++  /* Initialize the users parameters, allocating space, etc.+     Note that the default is to have asa generate the initial+     cost_parameters that satisfy the user's constraints. */++  if ((parameter_dimension =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): parameter_dimension");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((exit_code = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): exit_code");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((cost_flag = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): cost_flag");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  //USER_OPTIONS->Limit_Acceptances = 10000; +  USER_OPTIONS->Limit_Acceptances = 1000;+  USER_OPTIONS->Limit_Generated = 99999;+  USER_OPTIONS->Limit_Invalid_Generated_States = 1000;+  /* USER_OPTIONS->Accepted_To_Generated_Ratio = 1.0E-6; */+  USER_OPTIONS->Accepted_To_Generated_Ratio = 1.0E-4;++  USER_OPTIONS->Cost_Precision = 1.0E-18;+  USER_OPTIONS->Maximum_Cost_Repeat = 5;+  USER_OPTIONS->Number_Cost_Samples = 5;+  USER_OPTIONS->Temperature_Ratio_Scale = 1.0E-5;+  USER_OPTIONS->Cost_Parameter_Scale_Ratio = 1.0;+  USER_OPTIONS->Temperature_Anneal_Scale = 100.0;++  USER_OPTIONS->Include_Integer_Parameters = FALSE;+  USER_OPTIONS->User_Initial_Parameters = FALSE;+  USER_OPTIONS->Sequential_Parameters = -1;+  USER_OPTIONS->Initial_Parameter_Temperature = 1.0;++  USER_OPTIONS->Acceptance_Frequency_Modulus = 100;+  USER_OPTIONS->Generated_Frequency_Modulus = 10000;+  USER_OPTIONS->Reanneal_Cost = 1;+  USER_OPTIONS->Reanneal_Parameters = TRUE;++  USER_OPTIONS->Delta_X = 0.001;+  USER_OPTIONS->User_Tangents = FALSE;+  USER_OPTIONS->Curvature_0 = FALSE;+++  /* ALLOCATE STORAGE */+++#if USER_ASA_OUT+  if ((USER_OPTIONS->Asa_Out_File =+       (char *) calloc (80, sizeof (char))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): USER_OPTIONS->Asa_Out_File");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif++  /* the number of parameters for the cost function */+#if OPTIONS_FILE_DATA+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%s", read_option);++#if INT_ALLOC+  fscanf (ptr_options, "%d", &read_int);+  *parameter_dimension = read_int;+#else+#if INT_LONG+  fscanf (ptr_options, "%ld", &read_long);+  *parameter_dimension = read_long;+#else+  fscanf (ptr_options, "%d", &read_int);+  *parameter_dimension = read_int;+#endif+#endif++#else /* OPTIONS_FILE_DATA */+#endif /* OPTIONS_FILE_DATA */+#if MY_TEMPLATE                 /* MY_TEMPLATE_dim */+  *parameter_dimension = number_parameters;+  /* If not using OPTIONS_FILE_DATA or data read from asa_opt,+     insert the number of parameters for the cost_function */+#endif /* MY_TEMPLATE dim */++#if ASA_TEMPLATE_SAMPLE+  *parameter_dimension = 2;+  USER_OPTIONS->Limit_Acceptances = 2000;+  USER_OPTIONS->User_Tangents = TRUE;+  USER_OPTIONS->Limit_Weights = 1.0E-7;+#endif+#if ASA_TEMPLATE_PARALLEL+  USER_OPTIONS->Gener_Block = 100;+  USER_OPTIONS->Gener_Block_Max = 512;+  USER_OPTIONS->Gener_Mov_Avr = 3;+#endif++  /* allocate parameter minimum space */+  if ((parameter_lower_bound =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): parameter_lower_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* allocate parameter maximum space */+  if ((parameter_upper_bound =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): parameter_upper_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* allocate parameter initial values; the parameter final values+     will be stored here later */+  if ((cost_parameters =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): cost_parameters");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* allocate the parameter types, real or integer */+  if ((parameter_int_real =+       (int *) calloc (*parameter_dimension, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): parameter_int_real");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* allocate space for parameter cost_tangents -+     used for reannealing */+  if ((cost_tangents =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): cost_tangents");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if (USER_OPTIONS->Curvature_0 == FALSE || USER_OPTIONS->Curvature_0 == -1) {+    /* allocate space for parameter cost_curvatures/covariance */+    if ((cost_curvature =+         (double *) calloc ((*parameter_dimension) *+                            (*parameter_dimension),+                            sizeof (double))) == NULL) {+      strcpy (user_exit_msg, "main()/asa_main(): cost_curvature");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  } else {+    cost_curvature = (double *) NULL;+  }++#if USER_COST_SCHEDULE+  USER_OPTIONS->Cost_Schedule = user_cost_schedule;+#endif+#if USER_ACCEPTANCE_TEST+  USER_OPTIONS->Acceptance_Test = user_acceptance_test;+#endif+#if USER_ACCEPT_ASYMP_EXP+  USER_OPTIONS->Asymp_Exp_Param = 1.0;+#endif+#if USER_GENERATING_FUNCTION+  USER_OPTIONS->Generating_Distrib = user_generating_distrib;+#endif+#if USER_REANNEAL_COST+  USER_OPTIONS->Reanneal_Cost_Function = user_reanneal_cost;+#endif+#if USER_REANNEAL_PARAMETERS+  USER_OPTIONS->Reanneal_Params_Function = user_reanneal_params;+#endif++#if MY_TEMPLATE                 /* MY_TEMPLATE_pre_initialize */+  /* last changes before entering initialize_parameters() */+  USER_OPTIONS->Asa_Data_Ptr = func;+  USER_OPTIONS->Asa_Data_Dim_Ptr = 1;+  memcpy(parameter_lower_bound,lower_bounds,sizeof(double)*number_parameters);+  memcpy(cost_parameters,lower_bounds,sizeof(double)*number_parameters);+  memcpy(parameter_upper_bound,upper_bounds,sizeof(double)*number_parameters);+  memcpy(parameter_int_real, type, sizeof(int)*number_parameters);+#endif++  initialize_parameters_value = initialize_parameters (cost_parameters,+                                                       parameter_lower_bound,+                                                       parameter_upper_bound,+                                                       cost_tangents,+                                                       cost_curvature,+                                                       parameter_dimension,+                                                       parameter_int_real,+#if OPTIONS_FILE_DATA+                                                       ptr_options,+#endif+                                                       USER_OPTIONS);++  if (initialize_parameters_value == -2)+    return (initialize_parameters_value);++  for(i = 0; i < number_parameters; i++) {+          USER_OPTIONS->User_Quench_Param_Scale[i] = 1.0;+  }+        USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;++  /* optimize the cost_function, returning the results in+     cost_value and cost_parameters */+#if ASA_TEMPLATE_MULTIPLE+  /* multiple asa() quenched calls + multiple asa_out files+     (To get longer quenched runs, decrease SMALL_FLOAT.) */+  for (n_asa = 1; n_asa <= *parameter_dimension; n_asa++) {+    asa_file[4] = 'A' + n_asa - 1;+    USER_OPTIONS->User_Quench_Cost_Scale[0] = (double) n_asa;+    for (index = 0; index < *parameter_dimension; ++index)+      USER_OPTIONS->User_Quench_Param_Scale[index] = (double) n_asa;+    for (n_trajectory = 0; n_trajectory < 3; ++n_trajectory) {+      asa_file[6] = 'a' + n_trajectory;+      strcpy (USER_OPTIONS->Asa_Out_File, asa_file);+#endif++#if ASA_TEMPLATE_ASA_OUT_PID+      pid_file[0] = 'a';+      pid_file[1] = 's';+      pid_file[2] = 'a';+      pid_file[3] = '_';+      pid_file[4] = 'o';+      pid_file[5] = 'u';+      pid_file[6] = 't';+      pid_file[7] = '_';++      pid_int = getpid ();+      if (pid_int < 0) {+        pid_file[7] = '0';+        pid_int = -pid_int;+      }++      strcpy (USER_OPTIONS->Asa_Out_File, pid_file);+#endif+      cost_value =+        asa (USER_COST_FUNCTION,+             randflt,+             rand_seed,+             cost_parameters,+             parameter_lower_bound,+             parameter_upper_bound,+             cost_tangents,+             cost_curvature,+             parameter_dimension,+             parameter_int_real, cost_flag, exit_code, USER_OPTIONS);+      if (*exit_code == -1) {+#if INCL_STDOUT+        printf ("\n\n*** error in calloc in ASA ***\n\n");+#endif /* INCL_STDOUT */+        fprintf (ptr_out, "\n\n*** error in calloc in ASA ***\n\n");+        fflush (ptr_out);+        return (-1);+      }+#if MULTI_MIN+      fprintf (ptr_out, "Multi_Specify = %d\n", USER_OPTIONS->Multi_Specify);+#if INT_LONG+      fprintf (ptr_out, "N_Accepted = %ld\n", USER_OPTIONS->N_Accepted);+#else+      fprintf (ptr_out, "N_Accepted = %d\n", USER_OPTIONS->N_Accepted);+#endif+#if ASA_RESOLUTION+      for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+        fprintf (ptr_out,+#if INT_ALLOC+                 "Coarse_Resolution[%d] = %12.7g\n",+#else+#if INT_LONG+                 "Coarse_Resolution[%ld] = %12.7g\n",+#else+                 "Coarse_Resolution[%d] = %12.7g\n",+#endif+#endif+                 n_param, USER_OPTIONS->Coarse_Resolution[n_param]);+      }+#else /* ASA_RESOLUTION */+      for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+        fprintf (ptr_out,+#if INT_ALLOC+                 "Multi_Grid[%d] = %12.7g\n",+#else+#if INT_LONG+                 "Multi_Grid[%ld] = %12.7g\n",+#else+                 "Multi_Grid[%d] = %12.7g\n",+#endif+#endif+                 n_param, USER_OPTIONS->Multi_Grid[n_param]);+      }+#endif /* ASA_RESOLUTION */+      fprintf (ptr_out, "\n");+      for (multi_index = 0; multi_index < USER_OPTIONS->Multi_Number;+           ++multi_index) {+        fprintf (ptr_out, "\n");+        fprintf (ptr_out, "Multi_Cost[%d] = %12.7g\n",+                 multi_index, USER_OPTIONS->Multi_Cost[multi_index]);+        for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+          fprintf (ptr_out,+#if INT_ALLOC+                   "Multi_Params[%d][%d] = %12.7g\n",+#else+#if INT_LONG+                   "Multi_Params[%d][%ld] = %12.7g\n",+#else+                   "Multi_Params[%d][%d] = %12.7g\n",+#endif+#endif+                   multi_index, n_param,+                   USER_OPTIONS->Multi_Params[multi_index][n_param]);+        }+      }+      fprintf (ptr_out, "\n");+      fflush (ptr_out);+#endif /* MULTI_MIN */++#if FITLOC+      /* Fit_Local, Iter_Max and Penalty may be set adaptively */+      USER_OPTIONS->Penalty = 1000;+      USER_OPTIONS->Fit_Local = 0;+      USER_OPTIONS->Iter_Max = 500;+      if (USER_OPTIONS->Fit_Local >= 1) {+        cost_value = fitloc (USER_COST_FUNCTION,+                             cost_parameters,+                             parameter_lower_bound,+                             parameter_upper_bound,+                             cost_tangents,+                             cost_curvature,+                             parameter_dimension,+                             parameter_int_real,+                             cost_flag, exit_code, USER_OPTIONS, ptr_out);+      }+#endif /* FITLOC */+#if MY_TEMPLATE                 /* MY_TEMPLATE_post_asa */+#endif+      *main_cost_value = cost_value;+      for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+        main_cost_parameters[n_param] = cost_parameters[n_param];+      }+      *main_exit_code = *exit_code;++      fprintf (ptr_out, "exit code = %d\n", *exit_code);+      fprintf (ptr_out, "final cost value = %-12.7g\n", cost_value);+      fprintf (ptr_out, "%12s %12s\n","parameter","value");+      for (n_param = 0; n_param < *parameter_dimension; ++n_param) {+        fprintf (ptr_out,+#if INT_ALLOC+                 "%12d %12.7g\n",+#else+#if INT_LONG+                 "%12ld %12.7g\n",+#else+                 "%12d %12.7g\n",+#endif+#endif+                 n_param, cost_parameters[n_param]);+      }+++#if ASA_TEMPLATE_MULTIPLE+    }+  }+#endif++#if ASA_TEMPLATE_SAMPLE+  ptr_asa = fopen ("asa_out", "r");+  sample (ptr_out, ptr_asa);+#endif++  /* close all files */+  ptr_out != stdout && fclose (ptr_out);+#if OPTIONAL_DATA_DBL+  free (USER_OPTIONS->Asa_Data_Dbl);+#endif+#if OPTIONAL_DATA_INT+  free (USER_OPTIONS->Asa_Data_Int);+#endif+#if OPTIONAL_DATA_PTR+#if MY_TEMPLATE+  /* Instead of freeing Asa_Data_Ptr, if memory has been allocated+   * outside ASA, e.g., by the use of ASA_LIB, use the following: */+  USER_OPTIONS->Asa_Data_Ptr = NULL; +#endif /* MY_TEMPLATE */+  free (USER_OPTIONS->Asa_Data_Ptr);+#endif+#if USER_ASA_OUT+  free (USER_OPTIONS->Asa_Out_File);+#endif+#if ASA_SAMPLE+  free (USER_OPTIONS->Bias_Generated);+#endif+#if ASA_QUEUE+#if ASA_RESOLUTION+#else+  free (USER_OPTIONS->Queue_Resolution);+#endif+#endif+#if ASA_RESOLUTION+  free (USER_OPTIONS->Coarse_Resolution);+#endif+  if (USER_OPTIONS->Curvature_0 == FALSE || USER_OPTIONS->Curvature_0 == -1)+    free (cost_curvature);+#if USER_INITIAL_PARAMETERS_TEMPS+  free (USER_OPTIONS->User_Parameter_Temperature);+#endif+#if USER_INITIAL_COST_TEMP+  free (USER_OPTIONS->User_Cost_Temperature);+#endif+#if DELTA_PARAMETERS+  free (USER_OPTIONS->User_Delta_Parameter);+#endif+#if QUENCH_PARAMETERS+  free (USER_OPTIONS->User_Quench_Param_Scale);+#endif+#if QUENCH_COST+  free (USER_OPTIONS->User_Quench_Cost_Scale);+#endif+#if RATIO_TEMPERATURE_SCALES+  free (USER_OPTIONS->User_Temperature_Ratio);+#endif+#if MULTI_MIN+  free (USER_OPTIONS->Multi_Cost);+  free (USER_OPTIONS->Multi_Grid);+  for (multi_index = 0; multi_index < USER_OPTIONS->Multi_Number;+       ++multi_index) {+    free (USER_OPTIONS->Multi_Params[multi_index]);+  }+  free (USER_OPTIONS->Multi_Params);+#endif /* MULTI_MIN */+  free (USER_OPTIONS);+  free (parameter_dimension);+  free (exit_code);+  free (cost_flag);+  free (parameter_lower_bound);+  free (parameter_upper_bound);+  free (cost_parameters);+  free (parameter_int_real);+  free (cost_tangents);+  free (rand_seed);+  return (0);+  /* NOTREACHED */+}++/***********************************************************************+* initialize_parameters - sample parameter initialization function+*	This depends on the users cost function to optimize (minimum).+*	The routine allocates storage needed for asa. The user should+*	define the number of parameters and their ranges,+*	and make sure the initial parameters are within+*	the minimum and maximum ranges. The array+*	parameter_int_real should be REAL_TYPE (-1) for real parameters,+*	and INTEGER_TYPE (1) for integer values+***********************************************************************/+#if HAVE_ANSI+int+initialize_parameters (double *cost_parameters,+                       double *parameter_lower_bound,+                       double *parameter_upper_bound,+                       double *cost_tangents,+                       double *cost_curvature,+                       ALLOC_INT * parameter_dimension,+                       int *parameter_int_real,+#if OPTIONS_FILE_DATA+                       FILE * ptr_options,+#endif+                       USER_DEFINES * USER_OPTIONS)+#else+int+initialize_parameters (cost_parameters,+                       parameter_lower_bound,+                       parameter_upper_bound,+                       cost_tangents,+                       cost_curvature,+                       parameter_dimension, parameter_int_real,+#if OPTIONS_FILE_DATA+                       ptr_options,+#endif+                       USER_OPTIONS)+     double *cost_parameters;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+#if OPTIONS_FILE_DATA+     FILE *ptr_options;+#endif+     USER_DEFINES *USER_OPTIONS;+#endif+{+  ALLOC_INT index;+#if OPTIONS_FILE_DATA+  char read_option[80];+  ALLOC_INT read_index;+#endif+#if MULTI_MIN+  int multi_index;+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_init_decl */+  /* add some declarations if required */+#endif++  index = 0;+#if OPTIONS_FILE_DATA+  fscanf (ptr_options, "%s", read_option);++  for (index = 0; index < *parameter_dimension; ++index) {+#if MY_TEMPLATE                 /* MY_TEMPLATE_read_opt */+    /* put in some code as required to alter lines read from asa_opt */+#endif+#if INT_ALLOC+    fscanf (ptr_options, "%d", &read_index);+#else+#if INT_LONG+    fscanf (ptr_options, "%ld", &read_index);+#else+    fscanf (ptr_options, "%d", &read_index);+#endif+#endif+    fscanf (ptr_options, "%lf%lf%lf%d",+            &(parameter_lower_bound[read_index]),+            &(parameter_upper_bound[read_index]),+            &(cost_parameters[read_index]),+            &(parameter_int_real[read_index]));+  }+#else /* OPTIONS_FILE_DATA */+#if ASA_TEST+  /* store the parameter ranges */+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_lower_bound[index] = -10000.0;+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_upper_bound[index] = 10000.0;++  /* store the initial parameter types */+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_int_real[index] = REAL_TYPE;++  /* store the initial parameter values */+  for (index = 0; index < *parameter_dimension / 4.0; ++index) {+    cost_parameters[4 * (index + 1) - 4] = 999.0;+    cost_parameters[4 * (index + 1) - 3] = -1007.0;+    cost_parameters[4 * (index + 1) - 2] = 1001.0;+    cost_parameters[4 * (index + 1) - 1] = -903.0;+  }+#endif /* ASA_TEST */+#endif /* OPTIONS_FILE_DATA */+#if ASA_TEMPLATE_SAMPLE+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_lower_bound[index] = 0;+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_upper_bound[index] = 2.0;+  for (index = 0; index < *parameter_dimension; ++index)+    parameter_int_real[index] = REAL_TYPE;+  for (index = 0; index < *parameter_dimension; ++index)+    cost_parameters[index] = 0.5;+#endif++#if USER_INITIAL_PARAMETERS_TEMPS+  if ((USER_OPTIONS->User_Parameter_Temperature =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Parameter_Temperature");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Parameter_Temperature[index] = 1.0;+#endif+#endif /* USER_INITIAL_PARAMETERS_TEMPS */+#if USER_INITIAL_COST_TEMP+  if ((USER_OPTIONS->User_Cost_Temperature =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Cost_Temperature");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  USER_OPTIONS->User_Cost_Temperature[0] = 5.936648E+09;+#endif+#endif /* USER_INITIAL_COST_TEMP */+#if DELTA_PARAMETERS+  if ((USER_OPTIONS->User_Delta_Parameter =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Delta_Parameter");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Delta_Parameter[index] = 0.001;+#endif+#endif /* DELTA_PARAMETERS */+#if QUENCH_PARAMETERS+  if ((USER_OPTIONS->User_Quench_Param_Scale =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Quench_Param_Scale");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#if ASA_TEMPLATE_MULTIPLE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#if ASA_TEMPLATE_SAVE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#endif /* QUENCH_PARAMETERS */+#if QUENCH_COST+  if ((USER_OPTIONS->User_Quench_Cost_Scale =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Quench_Cost_Scale");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#if ASA_TEMPLATE_MULTIPLE+  USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#if ASA_TEMPLATE_SAVE+  USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#endif /* QUENCH_COST */++  /* use asa_opt to read in QUENCH USER_OPTIONS */+#if OPTIONS_FILE_DATA+#if QUENCH_COST+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &(USER_OPTIONS->User_Quench_Cost_Scale[0]));++#if QUENCH_PARAMETERS+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%s", read_option);+  for (index = 0; index < *parameter_dimension; ++index) {+#if INT_ALLOC+    fscanf (ptr_options, "%d", &read_index);+#else+#if INT_LONG+    fscanf (ptr_options, "%ld", &read_index);+#else+    fscanf (ptr_options, "%d", &read_index);+#endif+#endif+    fscanf (ptr_options, "%lf",+            &(USER_OPTIONS->User_Quench_Param_Scale[read_index]));+  }+#endif /* QUENCH_PARAMETERS */+#endif /* QUENCH_COST */+#endif /* OPTIONS_FILE_DATA */++#if RATIO_TEMPERATURE_SCALES+  if ((USER_OPTIONS->User_Temperature_Ratio =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->User_Temperature_Ratio");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->User_Temperature_Ratio[index] = 1.0;+#endif+#endif /* RATIO_TEMPERATURE_SCALES */+  /* Defines the limit of collection of sampled data by asa */+#if ASA_SAMPLE+  /* create memory for Bias_Generated[] */+  if ((USER_OPTIONS->Bias_Generated =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Bias_Generated");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif++#if ASA_RESOLUTION+  if ((USER_OPTIONS->Coarse_Resolution =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Coarse_Resolution");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->Coarse_Resolution[index] = 1.0;+#endif+#endif /* ASA_RESOLUTION */+#if ASA_QUEUE+#if ASA_RESOLUTION+  USER_OPTIONS->Queue_Resolution = USER_OPTIONS->Coarse_Resolution;+#else /* ASA_RESOLUTION */+  if ((USER_OPTIONS->Queue_Resolution =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Queue_Resolution");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* ASA_RESOLUTION */+#if ASA_TEMPLATE_QUEUE+  USER_OPTIONS->Queue_Size = 100;+  for (index = 0; index < *parameter_dimension; ++index)+    USER_OPTIONS->Queue_Resolution[index] = 0.001;+#endif+#endif /* ASA_QUEUE */+#if MULTI_MIN+#if ASA_TEMPLATE+  USER_OPTIONS->Multi_Number = 2;+#endif+  if ((USER_OPTIONS->Multi_Cost =+       (double *) calloc (USER_OPTIONS->Multi_Number,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Multi_Cost");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((USER_OPTIONS->Multi_Grid =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Multi_Grid");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((USER_OPTIONS->Multi_Params =+       (double **) calloc (USER_OPTIONS->Multi_Number,+                           sizeof (double *))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): USER_OPTIONS->Multi_Params");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  for (multi_index = 0; multi_index < USER_OPTIONS->Multi_Number;+       ++multi_index) {+    if ((USER_OPTIONS->Multi_Params[multi_index] =+         (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+      strcpy (user_exit_msg,+              "initialize_parameters(): USER_OPTIONS->Multi_Params[multi_index]");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  }+#if ASA_TEST+  for (index = 0; index < *parameter_dimension; ++index) {+    USER_OPTIONS->Multi_Grid[index] = 0.05;+  }+  USER_OPTIONS->Multi_Specify = 0;+#endif+#if ASA_TEMPLATE+  for (index = 0; index < *parameter_dimension; ++index) {+    USER_OPTIONS->Multi_Grid[index] =+      (parameter_upper_bound[index] - parameter_lower_bound[index]) / 100.0;+  }+  USER_OPTIONS->Multi_Specify = 0;+#endif /* ASA_TEMPLATE */+#endif /* MULTI_MIN */+  USER_OPTIONS->Asa_Recursive_Level = 0;++#if MY_TEMPLATE                 /* MY_TEMPLATE_params */+  /* If not using RECUR_OPTIONS_FILE_DATA or data read from asa_opt,+     store the parameter ranges+     store the parameter types+     store the initial parameter values+     other changes needed for initialization */+#endif /* MY_TEMPLATE params */++  return (0);+}++#if COST_FILE+#else+/***********************************************************************+* double cost_function+*	This is the users cost function to optimize+*	(find the minimum).+*	cost_flag is set to TRUE if the parameter set+*	does not violates any constraints+*       parameter_lower_bound and parameter_upper_bound may be+*       adaptively changed during the search.+***********************************************************************/++#if HAVE_ANSI+double+cost_function (double *x,+               double *parameter_lower_bound,+               double *parameter_upper_bound,+               double *cost_tangents,+               double *cost_curvature,+               ALLOC_INT * parameter_dimension,+               int *parameter_int_real,+               int *cost_flag, int *exit_code, USER_DEFINES * USER_OPTIONS)+#else+double+cost_function (x,+               parameter_lower_bound,+               parameter_upper_bound,+               cost_tangents,+               cost_curvature,+               parameter_dimension,+               parameter_int_real, cost_flag, exit_code, USER_OPTIONS)+     double *x;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+     int *cost_flag;+     int *exit_code;+     USER_DEFINES *USER_OPTIONS;+#endif+{++#if ASA_TEST                    /* ASA test problem */+  /* Objective function from+   * %A A. Corana+   * %A M. Marchesi+   * %A C. Martini+   * %A S. Ridella+   * %T Minimizing multimodal functions of continuous variables+   *    with the "simulated annealing" algorithm+   * %J ACM Trans. Mathl. Software+   * %V 13+   * %N 3+   * %P 262-279+   * %D 1987+   *+   * This function, when used with ASA_TEST_POINT set to TRUE, contains+   * 1.0E20 local minima.  When *parameter_dimension is equal to 4, visiting+   * each minimum for a millisecond would take about the present age of the+   * universe to visit all these minima. */++  /* defines for the test problem, which assume *parameter_dimension+     is a multiple of 4.  If this is set to a large number, you+     likely should set Curvature_0 to TRUE. */+  double q_n, d_i, s_i, t_i, z_i, c_r;+  int k_i;+#if ASA_TEST_POINT+  ALLOC_INT k_flag;+#endif+  ALLOC_INT i, j;+#if SELF_OPTIMIZE+#else+  static LONG_INT funevals = 0;+#endif+#if ASA_TEMPLATE_SAVE+  static int read_test = 0;+  FILE *ptr_read_test;+#endif++#if MY_TEMPLATE                 /* MY_TEMPLATE_diminishing_ranges */+  /* insert code to automate changing ranges of parameters */+#endif+#if ASA_TEMPLATE                /* example of diminishing ranges */+  if (USER_OPTIONS->Locate_Cost == 12 && *(USER_OPTIONS->Best_Cost) < 1.0) {+    fprintf (ptr_out, "best_cost = %g\n", *(USER_OPTIONS->Best_Cost));+    for (i = 0; i < *parameter_dimension; ++i) {+      parameter_lower_bound[i] = USER_OPTIONS->Best_Parameters[i]+        - 0.5 * fabs (parameter_lower_bound[i]+                      - USER_OPTIONS->Best_Parameters[i]);+      parameter_upper_bound[i] = USER_OPTIONS->Best_Parameters[i]+        + 0.5 * fabs (parameter_upper_bound[i]+                      - USER_OPTIONS->Best_Parameters[i]);+      parameter_lower_bound[i] = MIN (parameter_lower_bound[i],+                                      USER_OPTIONS->Best_Parameters[i] -+                                      0.01);+      parameter_upper_bound[i] =+        MAX (parameter_upper_bound[i],+             USER_OPTIONS->Best_Parameters[i] + 0.01);+    }+  }+#endif /* ASA_TEMPLATE */++  /* a_i = parameter_upper_bound[i] */+  s_i = 0.2;+  t_i = 0.05;+  c_r = 0.15;++#if ASA_TEST_POINT+  k_flag = 0;+  for (i = 0; i < *parameter_dimension; ++i) {+    if (fabs (parameter_upper_bound[i] - parameter_lower_bound[i]) <+        (double) EPS_DOUBLE)+      continue;++    if (x[i] > 0.0) {+      k_i = (int) (x[i] / s_i + 0.5);+    } else if (x[i] < 0.0) {+      k_i = (int) (x[i] / s_i - 0.5);+    } else {+      k_i = 0;+    }+    if (k_i == 0)+      ++k_flag;+  }+#endif /* ASA_TEST_POINT */++  q_n = 0.0;+  for (i = 0; i < *parameter_dimension; ++i) {+    if (fabs (parameter_upper_bound[i] - parameter_lower_bound[i]) <+        (double) EPS_DOUBLE)+      continue;++    j = i % 4;+    switch (j) {+    case 0:+      d_i = 1.0;+      break;+    case 1:+      d_i = 1000.0;+      break;+    case 2:+      d_i = 10.0;+      break;+    default:+      d_i = 100.0;+    }+    if (x[i] > 0.0) {+      k_i = (int) (x[i] / s_i + 0.5);+    } else if (x[i] < 0.0) {+      k_i = (int) (x[i] / s_i - 0.5);+    } else {+      k_i = 0;+    }++#if ASA_TEST_POINT+    if (fabs (k_i * s_i - x[i]) < t_i && k_flag != *parameter_dimension)+#else+    if (fabs (k_i * s_i - x[i]) < t_i)+#endif+    {+      if (k_i < 0) {+        z_i = k_i * s_i + t_i;+      } else if (k_i > 0) {+        z_i = k_i * s_i - t_i;+      } else {+        z_i = 0.0;+      }+      q_n += c_r * d_i * z_i * z_i;+    } else {+      q_n += d_i * x[i] * x[i];+    }+  }+  funevals = funevals + 1;++#if ASA_TEMPLATE_SAVE+  /* cause a crash */+  if ((ptr_read_test = fopen ("asa_save", "r")) == NULL) {+    read_test = 1;+    fclose (ptr_read_test);+  } else {+    fclose (ptr_read_test);+  }+  /* will need a few hundred if testing ASA_PARALLEL to get an asa_save */+  if (funevals == 50 && read_test == 1) {+    fprintf (ptr_out, "\n\n*** intended crash to test ASA_SAVE *** \n\n");+    fflush (ptr_out);+#if INCL_STDOUT+    printf ("\n\n*** intended crash to test ASA_SAVE *** \n\n");+#endif /* INCL_STDOUT */+    exit (2);+  }+#endif++  *cost_flag = TRUE;++#if SELF_OPTIMIZE+#else+#if TIME_CALC+  /* print the time every PRINT_FREQUENCY evaluations */+  if ((PRINT_FREQUENCY > 0) && ((funevals % PRINT_FREQUENCY) == 0)) {+    fprintf (ptr_out, "funevals = %ld  ", funevals);+#if INCL_STDOUT+    print_time ("", ptr_out);+#endif /* INCL_STDOUT */+  }+#endif+#endif++#if ASA_TEMPLATE_SAMPLE+  USER_OPTIONS->Cost_Acceptance_Flag = TRUE;+  if (USER_OPTIONS->User_Acceptance_Flag == FALSE && *cost_flag == TRUE)+    USER_OPTIONS->Acceptance_Test (q_n,+                                   parameter_lower_bound,+                                   parameter_upper_bound,+                                   *parameter_dimension, USER_OPTIONS);+#endif /* ASA_TEMPLATE_SAMPLE */++  return (q_n);+#endif /* ASA_TEST */+#if ASA_TEMPLATE_SAMPLE++  int n;+  double cost;++  if (*cost_flag == FALSE) {+    for (n = 0; n < *parameter_dimension; ++n)+      if (fabs (parameter_upper_bound[n] - parameter_lower_bound[n]) <+          (double) EPS_DOUBLE)+        continue;++    cost_tangents[n] = 2.0 * x[n];+  }++  cost = 0.0;+  for (n = 0; n < *parameter_dimension; ++n) {+    if (fabs (parameter_upper_bound[n] - parameter_lower_bound[n]) <+        (double) EPS_DOUBLE)+      continue;++    cost += (x[n] * x[n]);+  }++  *cost_flag = TRUE;++  USER_OPTIONS->Cost_Acceptance_Flag = TRUE;+  if (USER_OPTIONS->User_Acceptance_Flag == FALSE && *cost_flag == TRUE)+    USER_OPTIONS->Acceptance_Test (cost,+                                   parameter_lower_bound,+                                   parameter_upper_bound,+                                   *parameter_dimension, USER_OPTIONS);++  return (cost);+#endif /* ASA_TEMPLATE_SAMPLE */+#if MY_TEMPLATE                 /* MY_TEMPLATE_cost */+   return USER_OPTIONS->Asa_Data_Ptr(x,cost_flag); +  /* Use the parameter values x[] and define your cost_function.+     The {} brackets around this function are already in place. */+#endif /* MY_TEMPLATE cost */+}+#endif /* COST_FILE */++  /* Here is a good random number generator */++#define MULT ((LONG_INT) 25173)+#define MOD ((LONG_INT) 65536)+#define INCR ((LONG_INT) 13849)+#define FMOD ((double) 65536.0)+++/***********************************************************************+* double myrand - returns random number between 0 and 1+*	This routine returns the random number generator between 0 and 1+***********************************************************************/++static double+myrand (LONG_INT * rand_seed)+  /* returns random number in {0,1} */+{+#if TRUE                        /* (change to FALSE for alternative RNG) */+  *rand_seed = (LONG_INT) ((MULT * (*rand_seed) + INCR) % MOD);+  return ((double) (*rand_seed) / FMOD);+#else+  /* See "Random Number Generators: Good Ones Are Hard To Find,"+     Park & Miller, CACM 31 (10) (October 1988) pp. 1192-1201.+     ***********************************************************+     THIS IMPLEMENTATION REQUIRES AT LEAST 32 BIT INTEGERS+     *********************************************************** */+#define _A_MULTIPLIER  16807L+#define _M_MODULUS     2147483647L      /* (2**31)-1 */+#define _Q_QUOTIENT    127773L  /* 2147483647 / 16807 */+#define _R_REMAINDER   2836L    /* 2147483647 % 16807 */+  long lo;+  long hi;+  long test;++  hi = *rand_seed / _Q_QUOTIENT;+  lo = *rand_seed % _Q_QUOTIENT;+  test = _A_MULTIPLIER * lo - _R_REMAINDER * hi;+  if (test > 0) {+    *rand_seed = test;+  } else {+    *rand_seed = test + _M_MODULUS;+  }+  return ((double) *rand_seed / _M_MODULUS);+#endif /* alternative RNG */+}++/***********************************************************************+* double randflt+***********************************************************************/++static double+randflt (LONG_INT * rand_seed)+{+  return (resettable_randflt (rand_seed, 0));+}++/***********************************************************************+* double resettable_randflt+***********************************************************************/++static double+resettable_randflt (LONG_INT * rand_seed, int reset)+  /* shuffles random numbers in random_array[SHUFFLE] array */+{++  /* This RNG is a modified algorithm of that presented in+   * %A K. Binder+   * %A D. Stauffer+   * %T A simple introduction to Monte Carlo simulations and some+   *    specialized topics+   * %B Applications of the Monte Carlo Method in statistical physics+   * %E K. Binder+   * %I Springer-Verlag+   * %C Berlin+   * %D 1985+   * %P 1-36+   * where it is stated that such algorithms have been found to be+   * quite satisfactory in many statistical physics applications. */++  double rranf;+  unsigned kranf;+  int n;+  static int initial_flag = 0;+  LONG_INT initial_seed;+  static double random_array[SHUFFLE];  /* random variables */++  if (*rand_seed < 0)+    *rand_seed = -*rand_seed;++  if ((initial_flag == 0) || reset) {+    initial_seed = *rand_seed;++    for (n = 0; n < SHUFFLE; ++n)+      random_array[n] = myrand (&initial_seed);++    initial_flag = 1;++    for (n = 0; n < 1000; ++n)  /* warm up random generator */+      rranf = randflt (&initial_seed);++    rranf = randflt (rand_seed);++    return (rranf);+  }++  kranf = (unsigned) (myrand (rand_seed) * SHUFFLE) % SHUFFLE;+  rranf = *(random_array + kranf);+  *(random_array + kranf) = myrand (rand_seed);++  return (rranf);+}++#if USER_COST_SCHEDULE+#if HAVE_ANSI+double+user_cost_schedule (double test_temperature, USER_DEFINES * USER_OPTIONS)+#else+double+user_cost_schedule (test_temperature, USER_OPTIONS)+     double test_temperature;+     USER_DEFINES *USER_OPTIONS;+#endif /* HAVE_ANSI */+{+  double x;++#if ASA_TEMPLATE_SAMPLE+  x = F_POW (test_temperature, 0.15);+#endif+#if ASA_TEMPLATE+  x = test_temperature;+#endif++  return (x);+}+#endif /* USER_COST_SCHEDULE */++#if USER_ACCEPTANCE_TEST+#if HAVE_ANSI+void+user_acceptance_test (double current_cost,+                      double *parameter_lower_bound,+                      double *parameter_upper_bound,+                      ALLOC_INT * parameter_dimension,+                      USER_DEFINES * USER_OPTIONS)+#else+void+user_acceptance_test (current_cost, parameter_lower_bound,+                      parameter_upper_bound, parameter_dimension,+                      USER_OPTIONS)+     double current_cost;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     ALLOC_INT *parameter_dimension;+     USER_DEFINES *USER_OPTIONS;+#endif /* HAVE_ANSI */+{+  double uniform_test, curr_cost_temp;+#if USER_ACCEPT_ASYMP_EXP+  double x, q, delta_cost;+#endif++#if ASA_TEMPLATE                /* ASA cost index */+  /* Calculate the current ASA cost index.  This could be useful+     to define a new schedule for the cost temperature, beyond+     simple changes that can be made using USER_COST_SCHEDULE. */++  int index;+  double k_temperature, quench, y;+  double xparameter_dimension;++#if QUENCH_COST+  quench = USER_OPTIONS->User_Quench_Cost_Scale[0];+#else+  quench = 1.0;+#endif /* QUENCH_COST */+  xparameter_dimension = (double) *parameter_dimension;+  for (index = 0; index < *parameter_dimension; ++index)+    if (fabs (parameter_upper_bound[index] - parameter_lower_bound[index]) <+        (double) EPS_DOUBLE)+      *xparameter_dimension -= 1.0;++  y = -F_LOG (USER_OPTIONS->Cost_Temp_Curr+              / USER_OPTIONS->Cost_Temp_Init) / USER_OPTIONS->Cost_Temp_Scale;++  k_temperature = F_POW (y, xparameter_dimension / quench);+#endif /* ASA cost index */++  uniform_test = randflt (USER_OPTIONS->Random_Seed);+  curr_cost_temp = USER_OPTIONS->Cost_Temp_Curr;++#if ASA_TEMPLATE+#if USER_COST_SCHEDULE+  curr_cost_temp =+    (USER_OPTIONS->Cost_Schedule (USER_OPTIONS->Cost_Temp_Curr,+                                  USER_OPTIONS) + (double) EPS_DOUBLE);+#else+  curr_cost_temp = USER_OPTIONS->Cost_Temp_Curr;+#endif+#endif /* ASA_TEMPLATE */++  /* You must add in your own test here.  If USER_ACCEPT_ASYMP_EXP+     also is TRUE here, then you can use the default+     Asymp_Exp_Param=1 to replicate the code in asa.c. */++#if USER_ACCEPT_ASYMP_EXP+#if USER_COST_SCHEDULE+  curr_cost_temp =+    (USER_OPTIONS->Cost_Schedule (USER_OPTIONS->Cost_Temp_Curr,+                                  USER_OPTIONS) + (double) EPS_DOUBLE);+#endif++  delta_cost = (current_cost - *(USER_OPTIONS->Last_Cost))+    / (curr_cost_temp + (double) EPS_DOUBLE);++  /* The following asymptotic approximation to the exponential+   * function, "Tsallis statistics," was proposed in+   * %A T.J.P. Penna+   * %T Traveling salesman problem and Tsallis statistics+   * %J Phys. Rev. E+   * %V 50+   * %N 6+   * %P R1-R3+   * %D 1994+   * While the use of the TSP for a test case is of dubious value (since+   * there are many special algorithms for this problem), the use of this+   * function is another example of how to control the rate of annealing+   * of the acceptance criteria.  E.g., if you require a more moderate+   * acceptance test, then negative q may be helpful. */++  q = USER_OPTIONS->Asymp_Exp_Param;+  if (fabs (1.0 - q) < (double) EPS_DOUBLE)+    x = MIN (1.0, (F_EXP (-delta_cost)));       /* Boltzmann test */+  else if ((1.0 - (1.0 - q) * delta_cost) < (double) EPS_DOUBLE)+    x = MIN (1.0, (F_EXP (-delta_cost)));       /* Boltzmann test */+  else+    x = MIN (1.0, F_POW ((1.0 - (1.0 - q) * delta_cost), (1.0 / (1.0 - q))));++  USER_OPTIONS->Prob_Bias = x;+  if (x >= uniform_test)+    USER_OPTIONS->User_Acceptance_Flag = TRUE;+  else+    USER_OPTIONS->User_Acceptance_Flag = FALSE;++#endif /* USER_ACCEPT_ASYMP_EXP */+}+#endif /* USER_ACCEPTANCE_TEST */++#if USER_GENERATING_FUNCTION+#if HAVE_ANSI+double+user_generating_distrib (LONG_INT * seed,+                         ALLOC_INT * parameter_dimension,+                         ALLOC_INT index_v,+                         double temperature_v,+                         double init_param_temp_v,+                         double temp_scale_params_v,+                         double parameter_v,+                         double parameter_range_v,+                         double *last_saved_parameter,+                         USER_DEFINES * USER_OPTIONS)+#else+double+user_generating_distrib (seed,+                         parameter_dimension,+                         index_v,+                         temperature_v,+                         init_param_temp_v,+                         temp_scale_params_v,+                         parameter_v,+                         parameter_range_v,+                         last_saved_parameter, USER_OPTIONS)+     LONG_INT *seed;+     ALLOC_INT *parameter_dimension;+     ALLOC_INT index_v;+     double temperature_v;+     double init_param_temp_v;+     double temp_scale_params_v;+     double parameter_v;+     double parameter_range_v;+     double *last_saved_parameter;+     USER_DEFINES *USER_OPTIONS;+#endif+{+#if ASA_TEMPLATE+  double x, y, z;++  /* This is the ASA distribution.  A slower temperature schedule can be+     obtained here, e.g., temperature_v = pow(temperature_v, 0.5); */++  x = randflt (seed);+  y = x < 0.5 ? -1.0 : 1.0;+  z = y * temperature_v * (F_POW ((1.0 + 1.0 / temperature_v),+                                  fabs (2.0 * x - 1.0)) - 1.0);++  x = parameter_v + z * parameter_range_v;++  return (x);+#endif /* ASA_TEMPLATE */+}+#endif /* USER_GENERATING_FUNCTION */++#if USER_REANNEAL_COST+#if HAVE_ANSI+int+user_reanneal_cost (double *cost_best,+                    double *cost_last,+                    double *initial_cost_temperature,+                    double *current_cost_temperature,+                    USER_DEFINES * USER_OPTIONS)+#else+int+user_reanneal_cost (cost_best,+                    cost_last,+                    initial_cost_temperature,+                    current_cost_temperature, USER_OPTIONS)+     double *cost_best;+     double *cost_last;+     double *initial_cost_temperature;+     double *current_cost_temperature;+     USER_DEFINES *USER_OPTIONS;+#endif /* HAVE_ANSI */+{+  int cost_test;+  double tmp_dbl;++#if ASA_TEMPLATE+  static int first_time = 1;+  static double save_last[3];+  double average_cost_last;++  if (first_time == 1) {+    first_time = 0;+    save_last[0] = save_last[1] = save_last[2] = *cost_last;+  }++  save_last[2] = save_last[1];+  save_last[1] = save_last[0];+  save_last[0] = *cost_last;+  average_cost_last =+    fabs ((save_last[0] + save_last[1] + save_last[2]) / 3.0);++  tmp_dbl = MAX (fabs (*cost_best), average_cost_last);+  tmp_dbl = MAX ((double) EPS_DOUBLE, tmp_dbl);+  *initial_cost_temperature = MIN (*initial_cost_temperature, tmp_dbl);++  /* This test can be useful if your cost function goes from a positive+     to a negative value, and you do not want to get get stuck in a local+     minima around zero due to the default in reanneal().  Pick any+     number instead of 0.0001 */+  tmp_dbl = MIN (fabs (*cost_last), fabs (*cost_best));+  if (tmp_dbl < 0.0001)+    cost_test = FALSE;+  else+    cost_test = TRUE;+#endif /* ASA_TEMPLATE */++  tmp_dbl = MAX (fabs (cost_last), fabs (cost_best));+  tmp_dbl = MAX ((double) EPS_DOUBLE, tmp_dbl);+  *initial_cost_temperature = MIN (*initial_cost_temperature, tmp_dbl);++  *current_cost_temperature =+    MAX (fabs (cost_last - cost_best), *current_cost_temperature);+  *current_cost_temperature =+    MAX ((double) EPS_DOUBLE, *current_cost_temperature);+  *current_cost_temperature =+    MIN (*current_cost_temperature, *initial_cost_temperature);++  cost_test = TRUE;++  return (cost_test);+}+#endif /* USER_REANNEAL_COST */++#if USER_REANNEAL_PARAMETERS+#if HAVE_ANSI+double+user_reanneal_params (double current_temp,+                      double tangent,+                      double max_tangent, USER_DEFINES * USER_OPTIONS)+#else+double+user_reanneal_params (current_temp, tangent, max_tangent, USER_OPTIONS)+     double current_temp;+     double tangent;+     double max_tangent;+     USER_DEFINES *USER_OPTIONS;+#endif /* HAVE_ANSI */+{+#if ASA_TEMPLATE+  double x;++  x = current_temp * (max_tangent / tangent);++  return (x);+#endif+}+#endif /* USER_REANNEAL_PARAMETERS */++#if SELF_OPTIMIZE++/***********************************************************************+* main+*	This is a sample calling program to self-optimize ASA+***********************************************************************/+#if HAVE_ANSI++#if ASA_LIB+int+asa_main (+#if ASA_TEMPLATE_LIB+           double *main_recur_cost_value,+           double *main_recur_cost_parameters, int *main_recur_exit_code+#endif+  )+#else /* ASA_LIB */+int+main (int argc, char **argv)+#endif                          /* ASA_LIB */+#else /* HAVE_ANSI */++#if ASA_LIB+int+asa_main (+#if ASA_TEMPLATE_LIB+           main_recur_cost_value,+           main_recur_cost_parameters, main_recur_exit_code+#endif+  )+#if ASA_TEMPLATE_LIB+     double *main_recur_cost_value;+     double *main_recur_cost_parameters;+     int *main_recur_exit_code;+#endif++#else /* ASA_LIB */+int+main (argc, argv)+     int argc;+     char **argv;+#endif /* ASA_LIB */++#endif /* HAVE_ANSI */+{++  /* seed for random number generator */+  LONG_INT *recur_rand_seed;++#if RECUR_OPTIONS_FILE+  FILE *recur_ptr_options;+  char read_option[80];+  char read_if[4], read_FALSE[6], read_comm1[3], read_ASA_SAVE[9],+    read_comm2[3];+  int read_int;+#if INT_LONG+  LONG_INT read_long;+#endif+  double read_double;+#endif++  int *recur_exit_code;+#if MULTI_MIN+  int multi_index;+  ALLOC_INT n_param;+#endif++  double *recur_parameter_lower_bound, *recur_parameter_upper_bound;+  double *recur_cost_parameters, *recur_cost_tangents, *recur_cost_curvature;+  double recur_cost_value;++  ALLOC_INT *recur_parameter_dimension;+  int *recur_parameter_int_real;+  int *recur_cost_flag;+  int recur_initialize_parameters_value;+  ALLOC_INT recur_v;+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_main_decl */+  /* add some declarations if required */+#endif++  USER_DEFINES *RECUR_USER_OPTIONS;++  if ((recur_parameter_dimension =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_parameter_dimension");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((recur_exit_code = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_exit_code");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((recur_cost_flag = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_cost_flag");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((RECUR_USER_OPTIONS =+       (USER_DEFINES *) calloc (1, sizeof (USER_DEFINES))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): RECUR_USER_OPTIONS");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if RECUR_OPTIONS_FILE+  recur_ptr_options = fopen ("asa_opt_recur", "r");++  fscanf (recur_ptr_options, "%s%s%s%s%s",+          read_if, read_FALSE, read_comm1, read_ASA_SAVE, read_comm2);+  if (strcmp (read_if, "#if") || strcmp (read_FALSE, "FALSE") ||+      strcmp (read_comm1, "/*") || strcmp (read_ASA_SAVE, "ASA_SAVE") ||+      strcmp (read_comm2, "*/")) {+    fprintf (ptr_out, "\n\n*** not asa_opt_recur for this version *** \n\n");+    fflush (ptr_out);+#if INCL_STDOUT+    printf ("\n\n*** EXIT not asa_opt_recur for this version *** \n\n");+#endif /* INCL_STDOUT */+    return (-6);+  }+#if INT_LONG+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%ld", &read_long);+  RECUR_USER_OPTIONS->Limit_Acceptances = read_long;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%ld", &read_long);+  RECUR_USER_OPTIONS->Limit_Generated = read_long;+#else+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Limit_Acceptances = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Limit_Generated = read_int;+#endif+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Limit_Invalid_Generated_States = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Accepted_To_Generated_Ratio = read_double;++  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Cost_Precision = read_double;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Maximum_Cost_Repeat = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Number_Cost_Samples = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Temperature_Ratio_Scale = read_double;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Cost_Parameter_Scale_Ratio = read_double;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Temperature_Anneal_Scale = read_double;++  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Include_Integer_Parameters = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->User_Initial_Parameters = read_int;+#if INT_ALLOC+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Sequential_Parameters = read_int;+#else+#if INT_LONG+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%ld", &read_long);+  RECUR_USER_OPTIONS->Sequential_Parameters = read_long;+#else+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Sequential_Parameters = read_int;+#endif+#endif+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Initial_Parameter_Temperature = read_double;++  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Acceptance_Frequency_Modulus = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Generated_Frequency_Modulus = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Reanneal_Cost = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Reanneal_Parameters = read_int;++  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf", &read_double);+  RECUR_USER_OPTIONS->Delta_X = read_double;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->User_Tangents = read_int;+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%d", &read_int);+  RECUR_USER_OPTIONS->Curvature_0 = read_int;++#else /* RECUR_OPTIONS_FILE */+  RECUR_USER_OPTIONS->Limit_Acceptances = 100;+  RECUR_USER_OPTIONS->Limit_Generated = 1000;+  RECUR_USER_OPTIONS->Limit_Invalid_Generated_States = 1000;+  RECUR_USER_OPTIONS->Accepted_To_Generated_Ratio = 1.0E-4;++  RECUR_USER_OPTIONS->Cost_Precision = 1.0E-18;+  RECUR_USER_OPTIONS->Maximum_Cost_Repeat = 2;+  RECUR_USER_OPTIONS->Number_Cost_Samples = 2;+  RECUR_USER_OPTIONS->Temperature_Ratio_Scale = 1.0E-5;+  RECUR_USER_OPTIONS->Cost_Parameter_Scale_Ratio = 1.0;+  RECUR_USER_OPTIONS->Temperature_Anneal_Scale = 100.0;++  RECUR_USER_OPTIONS->Include_Integer_Parameters = FALSE;+  RECUR_USER_OPTIONS->User_Initial_Parameters = FALSE;+  RECUR_USER_OPTIONS->Sequential_Parameters = -1;+  RECUR_USER_OPTIONS->Initial_Parameter_Temperature = 1.0;++  RECUR_USER_OPTIONS->Acceptance_Frequency_Modulus = 15;+  RECUR_USER_OPTIONS->Generated_Frequency_Modulus = 10000;+  RECUR_USER_OPTIONS->Reanneal_Cost = FALSE;+  RECUR_USER_OPTIONS->Reanneal_Parameters = FALSE;++  RECUR_USER_OPTIONS->Delta_X = 1.0E-6;+  RECUR_USER_OPTIONS->User_Tangents = FALSE;+  RECUR_USER_OPTIONS->Curvature_0 = TRUE;++#endif /* RECUR_OPTIONS_FILE */++  /* the number of parameters for the recur_cost_function */+#if RECUR_OPTIONS_FILE_DATA+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%s", read_option);++#if INT_ALLOC+  fscanf (recur_ptr_options, "%d", &read_int);+  *recur_parameter_dimension = read_int;+#else+#if INT_LONG+  fscanf (recur_ptr_options, "%ld", &read_long);+  *recur_parameter_dimension = read_long;+#else+  fscanf (recur_ptr_options, "%d", &read_int);+  *recur_parameter_dimension = read_int;+#endif+#endif++#else /* RECUR_OPTIONS_FILE_DATA */+#if ASA_TEMPLATE_SELFOPT+  *recur_parameter_dimension = 2;+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_dim */+  /* If not using RECUR_OPTIONS_FILE_DATA or data read from recur_asa_opt,+     insert the number of parameters for the recur_cost_function */+#endif /* MY_TEMPLATE recur_dim */+#endif /* RECUR_OPTIONS_FILE_DATA */+  if ((recur_parameter_lower_bound =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_parameter_lower_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((recur_parameter_upper_bound =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_parameter_upper_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((recur_cost_parameters =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_cost_parameters");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((recur_parameter_int_real =+       (int *) calloc (*recur_parameter_dimension, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_parameter_int_real");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((recur_cost_tangents =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_cost_tangents");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if (RECUR_USER_OPTIONS->Curvature_0 == FALSE+      || RECUR_USER_OPTIONS->Curvature_0 == -1) {++    if ((recur_cost_curvature =+         (double *) calloc ((*recur_parameter_dimension)+                            * (*recur_parameter_dimension),+                            sizeof (double))) == NULL) {+      strcpy (user_exit_msg, "main()/asa_main(): recur_cost_curvature");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  } else {+    recur_cost_curvature = (double *) NULL;+  }++#if ASA_TEMPLATE_SELFOPT+  /* Set memory to that required for use. */+  RECUR_USER_OPTIONS->Asa_Data_Dim_Dbl = 1;+  if ((RECUR_USER_OPTIONS->Asa_Data_Dbl =+       (double *) calloc (RECUR_USER_OPTIONS->Asa_Data_Dim_Dbl,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "main()/asa_main(): RECUR_USER_OPTIONS->Asa_Data_Dbl");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* Use Asa_Data[0] as flag, e.g., if used with SELF_OPTIMIZE. */+  RECUR_USER_OPTIONS->Asa_Data_Dbl[0] = 0;+#endif /* ASA_TEMPLATE_SELFOPT */++#if OPTIONAL_DATA_PTR+#if ASA_TEMPLATE+  RECUR_USER_OPTIONS->Asa_Data_Dim_Ptr = 1;+  if ((RECUR_USER_OPTIONS->Asa_Data_Ptr =+       (OPTIONAL_PTR_TYPE *) calloc (RECUR_USER_OPTIONS->Asa_Data_Dim_Ptr,+                                     sizeof (OPTIONAL_PTR_TYPE))) == NULL) {+    strcpy (user_exit_msg,+            "main()/asa_main(): RECUR_USER_OPTIONS->Asa_Data_Ptr");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* ASA_TEMPLATE */+#endif /* OPTIONAL_DATA_PTR */++#if ASA_SAVE+  /* Such data could be saved in a user_save file, but for+     convenience here everything is saved in asa_save. */+  RECUR_USER_OPTIONS->Random_Array_Dim = SHUFFLE;+  RECUR_USER_OPTIONS->Random_Array = random_array;+#endif /* ASA_SAVE */++  /* open the output file */+#if ASA_SAVE+  if (!strcmp (USER_OUT, "STDOUT")) {+#if INCL_STDOUT+    ptr_out = stdout;+#endif /* INCL_STDOUT */+  } else {+    ptr_out = fopen (USER_OUT, "a");+  }+#else+  if (!strcmp (USER_OUT, "STDOUT")) {+#if INCL_STDOUT+    ptr_out = stdout;+#endif /* INCL_STDOUT */+  } else {+    ptr_out = fopen (USER_OUT, "w");+  }+#endif+//  fprintf (ptr_out, "%s\n\n", USER_ID);++  fflush (ptr_out);++  if ((recur_rand_seed =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "main()/asa_main(): recur_rand_seed");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  /* first value of *recur_rand_seed */+#if ASA_LIB+  *recur_rand_seed = (asa_rand_seed ? *asa_rand_seed : (LONG_INT) 696969);+#else+  *recur_rand_seed = 696969;+#endif++  randflt (recur_rand_seed);++#if USER_COST_SCHEDULE+  RECUR_USER_OPTIONS->Cost_Schedule = recur_user_cost_schedule;+#endif+#if USER_ACCEPTANCE_TEST+  RECUR_USER_OPTIONS->Acceptance_Test = recur_user_acceptance_test;+#endif+#if USER_ACCEPT_ASYMP_EXP+  RECUR_USER_OPTIONS->Asymp_Exp_Param = 1.0;+#endif+#if USER_GENERATING_FUNCTION+  RECUR_USER_OPTIONS->Generating_Distrib = recur_user_generating_distrib;+#endif+#if USER_REANNEAL_COST+  RECUR_USER_OPTIONS->Reanneal_Cost_Function = recur_user_reanneal_cost;+#endif+#if USER_REANNEAL_PARAMETERS+  RECUR_USER_OPTIONS->Reanneal_Params_Function = recur_user_reanneal_params;+#endif++#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_pre_initialize */+  /* last changes before entering recur_initialize_parameters() */+#endif++  /* initialize the users parameters, allocating space, etc.+     Note that the default is to have asa generate the initial+     recur_cost_parameters that satisfy the user's constraints. */++  recur_initialize_parameters_value =+    recur_initialize_parameters (recur_cost_parameters,+                                 recur_parameter_lower_bound,+                                 recur_parameter_upper_bound,+                                 recur_cost_tangents,+                                 recur_cost_curvature,+                                 recur_parameter_dimension,+                                 recur_parameter_int_real,+#if RECUR_OPTIONS_FILE_DATA+                                 recur_ptr_options,+#endif+                                 RECUR_USER_OPTIONS);+#if RECUR_OPTIONS_FILE+  fclose (recur_ptr_options);+#endif+  if (recur_initialize_parameters_value == -2)+    return (recur_initialize_parameters_value);++#if USER_ASA_OUT+  if ((RECUR_USER_OPTIONS->Asa_Out_File =+       (char *) calloc (80, sizeof (char))) == NULL) {+    strcpy (user_exit_msg,+            "main()/asa_main(): RECUR_USER_OPTIONS->Asa_Out_File");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE_SELFOPT+  strcpy (RECUR_USER_OPTIONS->Asa_Out_File, "asa_sfop");+#endif+#endif++  recur_cost_value = asa (RECUR_USER_COST_FUNCTION,+                          randflt,+                          recur_rand_seed,+                          recur_cost_parameters,+                          recur_parameter_lower_bound,+                          recur_parameter_upper_bound,+                          recur_cost_tangents,+                          recur_cost_curvature,+                          recur_parameter_dimension,+                          recur_parameter_int_real,+                          recur_cost_flag,+                          recur_exit_code, RECUR_USER_OPTIONS);+  if (*recur_exit_code == -1) {+#if INCL_STDOUT+    printf ("\n\n*** error in calloc in ASA ***\n\n");+#endif /* INCL_STDOUT */+    fprintf (ptr_out, "\n\n*** error in calloc in ASA ***\n\n");+    fflush (ptr_out);+    return (-1);+  }+#if MULTI_MIN+  fprintf (ptr_out, "Multi_Specify = %d\n",+           RECUR_USER_OPTIONS->Multi_Specify);+  for (n_param = 0; n_param < *recur_parameter_dimension; ++n_param) {+    fprintf (ptr_out,+#if INT_ALLOC+             "Multi_Grid[%d] = %12.7g\n",+#else+#if INT_LONG+             "Multi_Grid[%ld] = %12.7g\n",+#else+             "Multi_Grid[%d] = %12.7g\n",+#endif+#endif+             n_param, RECUR_USER_OPTIONS->Multi_Grid[n_param]);+  }+  fprintf (ptr_out, "\n");+  for (multi_index = 0; multi_index < RECUR_USER_OPTIONS->Multi_Number;+       ++multi_index) {+    fprintf (ptr_out, "\n");+    fprintf (ptr_out, "Multi_Cost[%d] = %12.7g\n",+             multi_index, RECUR_USER_OPTIONS->Multi_Cost[multi_index]);+    for (n_param = 0; n_param < *recur_parameter_dimension; ++n_param) {+      fprintf (ptr_out,+#if INT_ALLOC+               "Multi_Params[%d][%d] = %12.7g\n",+#else+#if INT_LONG+               "Multi_Params[%d][%ld] = %12.7g\n",+#else+               "Multi_Params[%d][%d] = %12.7g\n",+#endif+#endif+               multi_index, n_param,+               RECUR_USER_OPTIONS->Multi_Params[multi_index][n_param]);+    }+  }+  fprintf (ptr_out, "\n");+  fflush (ptr_out);+#endif /* MULTI_MIN */++#if FITLOC+  /* Fit_Local and Penalty may be set adaptively */+  RECUR_USER_OPTIONS->Penalty = 1000;+  RECUR_USER_OPTIONS->Fit_Local = 0;+  RECUR_USER_OPTIONS->Iter_Max = 500;+  if (RECUR_USER_OPTIONS->Fit_Local >= 1) {+    recur_cost_value = fitloc (RECUR_USER_COST_FUNCTION,+                               recur_cost_parameters,+                               recur_parameter_lower_bound,+                               recur_parameter_upper_bound,+                               recur_cost_tangents,+                               recur_cost_curvature,+                               recur_parameter_dimension,+                               recur_parameter_int_real,+                               recur_cost_flag,+                               recur_exit_code, RECUR_USER_OPTIONS, ptr_out);+  }+#endif /* FITLOC */++  fprintf (ptr_out, "\n\n recur_cost_value = %12.7g\n", recur_cost_value);+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_post_recur_asa */+#endif+#if ASA_TEMPLATE_LIB+  *main_recur_cost_value = recur_cost_value;+  for (recur_v = 0; recur_v < *recur_parameter_dimension; ++recur_v) {+    main_recur_cost_parameters[recur_v] = recur_cost_parameters[recur_v];+  }+  *main_recur_exit_code = *recur_exit_code;+#endif++  for (recur_v = 0; recur_v < *recur_parameter_dimension; ++recur_v)+#if INT_ALLOC+    fprintf (ptr_out, "recur_cost_parameters[%d] = %12.7g\n",+#else+#if INT_LONG+    fprintf (ptr_out, "recur_cost_parameters[%ld] = %12.7g\n",+#else+    fprintf (ptr_out, "recur_cost_parameters[%d] = %12.7g\n",+#endif+#endif+             recur_v, recur_cost_parameters[recur_v]);++  fprintf (ptr_out, "\n\n");+++  /* close all files */+  ptr_out != stdout && fclose (ptr_out);++#if OPTIONAL_DATA_DBL+  free (RECUR_USER_OPTIONS->Asa_Data_Dbl);+#endif+#if OPTIONAL_DATA_INT+  free (RECUR_USER_OPTIONS->Asa_Data_Int);+#endif+#if OPTIONAL_DATA_PTR+  free (RECUR_USER_OPTIONS->Asa_Data_Ptr);+#endif+#if USER_ASA_OUT+  free (RECUR_USER_OPTIONS->Asa_Out_File);+#endif+#if ASA_SAMPLE+  free (RECUR_USER_OPTIONS->Bias_Generated);+#endif+#if ASA_QUEUE+#if ASA_RESOLUTION+#else+  free (RECUR_USER_OPTIONS->Queue_Resolution);+#endif+#endif+#if ASA_RESOLUTION+  free (RECUR_USER_OPTIONS->Coarse_Resolution);+#endif+  if (RECUR_USER_OPTIONS->Curvature_0 == FALSE+      || RECUR_USER_OPTIONS->Curvature_0 == -1)+    free (recur_cost_curvature);+#if USER_INITIAL_PARAMETERS_TEMPS+  free (RECUR_USER_OPTIONS->User_Parameter_Temperature);+#endif+#if USER_INITIAL_COST_TEMP+  free (RECUR_USER_OPTIONS->User_Cost_Temperature);+#endif+#if DELTA_PARAMETERS+  free (RECUR_USER_OPTIONS->User_Delta_Parameter);+#endif+#if QUENCH_PARAMETERS+  free (RECUR_USER_OPTIONS->User_Quench_Param_Scale);+#endif+#if QUENCH_COST+  free (RECUR_USER_OPTIONS->User_Quench_Cost_Scale);+#endif+#if RATIO_TEMPERATURE_SCALES+  free (RECUR_USER_OPTIONS->User_Temperature_Ratio);+#endif+#if MULTI_MIN+  free (RECUR_USER_OPTIONS->Multi_Cost);+  free (RECUR_USER_OPTIONS->Multi_Grid);+  for (multi_index = 0; multi_index < RECUR_USER_OPTIONS->Multi_Number;+       ++multi_index) {+    free (RECUR_USER_OPTIONS->Multi_Params[multi_index]);+  }+  free (RECUR_USER_OPTIONS->Multi_Params);+#endif /* MULTI_MIN */+  free (RECUR_USER_OPTIONS);+  free (recur_parameter_dimension);+  free (recur_exit_code);+  free (recur_cost_flag);+  free (recur_parameter_lower_bound);+  free (recur_parameter_upper_bound);+  free (recur_cost_parameters);+  free (recur_parameter_int_real);+  free (recur_cost_tangents);+  free (recur_rand_seed);++  return (0);+  /* NOTREACHED */+}++/***********************************************************************+* recur_initialize_parameters+*	This depends on the users cost function to optimize (minimum).+*	The routine allocates storage needed for asa. The user should+*	define the number of parameters and their ranges,+*	and make sure the initial parameters are within+*	the minimum and maximum ranges. The array+*	recur_parameter_int_real should be REAL_TYPE (-1)+*       for real parameters,+***********************************************************************/+#if HAVE_ANSI+int+recur_initialize_parameters (double *recur_cost_parameters,+                             double *recur_parameter_lower_bound,+                             double *recur_parameter_upper_bound,+                             double *recur_cost_tangents,+                             double *recur_cost_curvature,+                             ALLOC_INT * recur_parameter_dimension,+                             int *recur_parameter_int_real,+#if RECUR_OPTIONS_FILE_DATA+                             FILE * recur_ptr_options,+#endif+                             USER_DEFINES * RECUR_USER_OPTIONS)+#else+int+recur_initialize_parameters (recur_cost_parameters,+                             recur_parameter_lower_bound,+                             recur_parameter_upper_bound,+                             recur_cost_tangents,+                             recur_cost_curvature,+                             recur_parameter_dimension,+                             recur_parameter_int_real,+#if RECUR_OPTIONS_FILE_DATA+                             recur_ptr_options,+#endif+                             RECUR_USER_OPTIONS)+     double *recur_parameter_lower_bound;+     double *recur_parameter_upper_bound;+     double *recur_cost_parameters;+     double *recur_cost_tangents;+     double *recur_cost_curvature;+     ALLOC_INT *recur_parameter_dimension;+     int *recur_parameter_int_real;+#if RECUR_OPTIONS_FILE_DATA+     FILE *recur_ptr_options;+#endif+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif+{+  ALLOC_INT index;+#if RECUR_OPTIONS_FILE_DATA+  char read_option[80];+  ALLOC_INT read_index;+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_init_decl */+  /* add some declarations if required */+#endif+#if MULTI_MIN+  int multi_index;+#endif++#if RECUR_OPTIONS_FILE_DATA+  fscanf (recur_ptr_options, "%s", read_option);++  for (index = 0; index < *recur_parameter_dimension; ++index) {+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_read_opt */+    /* put in some code as required to alter lines read from recur_asa_opt */+#endif+#if INT_ALLOC+    fscanf (recur_ptr_options, "%d", &read_index);+#else+#if INT_LONG+    fscanf (recur_ptr_options, "%ld", &read_index);+#else+    fscanf (recur_ptr_options, "%d", &read_index);+#endif+#endif+    fscanf (recur_ptr_options, "%lf%lf%lf%d",+            &(recur_parameter_lower_bound[read_index]),+            &(recur_parameter_upper_bound[read_index]),+            &(recur_cost_parameters[read_index]),+            &(recur_parameter_int_real[read_index]));+  }+#else /* RECUR_OPTIONS_FILE_DATA */+#if ASA_TEMPLATE_SELFOPT+  /*  NOTE:+     USER_OPTIONS->Temperature_Ratio_Scale = x[0];+     USER_OPTIONS->Cost_Parameter_Scale_Ratio = x[1];+   */++  /* store the initial parameter values */+  recur_cost_parameters[0] = 1.0E-5;+  recur_cost_parameters[1] = 1.0;++  recur_parameter_lower_bound[0] = 1.0E-6;+  recur_parameter_upper_bound[0] = 1.0E-4;++  recur_parameter_lower_bound[1] = 0.5;+  recur_parameter_upper_bound[1] = 3.0;++  /* store the initial parameter types */+  for (index = 0; index < *recur_parameter_dimension; ++index)+    recur_parameter_int_real[index] = REAL_TYPE;+#endif+#endif /* RECUR_OPTIONS_FILE_DATA */++#if USER_INITIAL_PARAMETERS_TEMPS+  if ((RECUR_USER_OPTIONS->User_Parameter_Temperature =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Parameter_Temperature");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Parameter_Temperature[index] = 1.0;+#endif /* USER_INITIAL_PARAMETERS_TEMPS */+#if USER_INITIAL_COST_TEMP+  if ((RECUR_USER_OPTIONS->User_Cost_Temperature =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Cost_Temperature");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  RECUR_USER_OPTIONS->User_Cost_Temperature[0] = 5.936648E+09;+#endif /* USER_INITIAL_COST_TEMP */+#if DELTA_PARAMETERS+  if ((RECUR_USER_OPTIONS->User_Delta_Parameter =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Delta_Parameter");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Delta_Parameter[index] = 0.001;+#endif /* DELTA_PARAMETERS */+#if QUENCH_PARAMETERS+  if ((RECUR_USER_OPTIONS->User_Quench_Param_Scale =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Quench_Param_Scale");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#endif /* QUENCH_PARAMETERS */+#if QUENCH_COST+  if ((RECUR_USER_OPTIONS->User_Quench_Cost_Scale =+       (double *) calloc (1, sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Quench_Cost_Scale");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  RECUR_USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#endif /* QUENCH_COST */++  /* use asa_opt_recur to read in QUENCH RECUR_USER_OPTIONS */+#if RECUR_OPTIONS_FILE_DATA+#if QUENCH_COST+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%lf",+          &(RECUR_USER_OPTIONS->User_Quench_Cost_Scale[0]));++#if QUENCH_PARAMETERS+  fscanf (recur_ptr_options, "%s", read_option);+  fscanf (recur_ptr_options, "%s", read_option);+  for (index = 0; index < *recur_parameter_dimension; ++index) {+#if INT_ALLOC+    fscanf (recur_ptr_options, "%d", &read_index);+#else+#if INT_LONG+    fscanf (recur_ptr_options, "%ld", &read_index);+#else+    fscanf (recur_ptr_options, "%d", &read_index);+#endif+#endif+    fscanf (recur_ptr_options, "%lf",+            &(RECUR_USER_OPTIONS->User_Quench_Param_Scale[read_index]));+  }+#endif /* QUENCH_PARAMETERS */+#endif /* QUENCH_COST */+#endif /* RECUR_OPTIONS_FILE_DATA */+#if RATIO_TEMPERATURE_SCALES+  if ((RECUR_USER_OPTIONS->User_Temperature_Ratio =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->User_Temperature_Ratio");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Temperature_Ratio[index] = 1.0;+#endif+#endif /* RATIO_TEMPERATURE_SCALES */+  /* Defines the limit of collection of sampled data by asa */+#if ASA_SAMPLE+  /* create memory for Bias_Generated[] */+  if ((RECUR_USER_OPTIONS->Bias_Generated =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->Bias_Generated");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE+  RECUR_USER_OPTIONS->Limit_Weights = 1.0E-7;+#if QUENCH_COST+  RECUR_USER_OPTIONS->User_Quench_Cost_Scale[0] = 1.0;+#endif+#if QUENCH_PARAMETERS+  for (index = 0; index < *recur_parameter_dimension; ++index)+    RECUR_USER_OPTIONS->User_Quench_Param_Scale[index] = 1.0;+#endif+#endif /* ASA_TEMPLATE */+#endif /* ASA_SAMPLE */++#if ASA_TEMPLATE+#if ASA_PARALLEL+  RECUR_USER_OPTIONS->Gener_Block = 1;+  RECUR_USER_OPTIONS->Gener_Block_Max = 1;+  RECUR_USER_OPTIONS->Gener_Mov_Avr = 1;+#endif+#endif+#if ASA_RESOLUTION+  if ((RECUR_USER_OPTIONS->Coarse_Resolution =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->Coarse_Resolution");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif+#if MULTI_MIN+#if ASA_TEMPLATE+  RECUR_USER_OPTIONS->Multi_Number = 2;+#endif+  if ((RECUR_USER_OPTIONS->Multi_Cost =+       (double *) calloc (RECUR_USER_OPTIONS->Multi_Number,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): RECUR_USER_OPTIONS->Multi_Cost");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((RECUR_USER_OPTIONS->Multi_Grid =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->Multi_Grid");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((RECUR_USER_OPTIONS->Multi_Params =+       (double **) calloc (RECUR_USER_OPTIONS->Multi_Number,+                           sizeof (double *))) == NULL) {+    strcpy (user_exit_msg,+            "initialize_parameters(): RECUR_USER_OPTIONS->Multi_Params");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  for (multi_index = 0; multi_index < RECUR_USER_OPTIONS->Multi_Number;+       ++multi_index) {+    if ((RECUR_USER_OPTIONS->Multi_Params[multi_index] =+         (double *) calloc (*recur_parameter_dimension,+                            sizeof (double))) == NULL) {+      strcpy (user_exit_msg,+              "recur_initialize_parameters(): RECUR_USER_OPTIONS->Multi_Params[multi_index]");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  }+#if ASA_TEST+  for (index = 0; index < *recur_parameter_dimension; ++index) {+    RECUR_USER_OPTIONS->Multi_Grid[index] = 0.05;+  }+  RECUR_USER_OPTIONS->Multi_Specify = 0;+#endif+#if ASA_TEMPLATE+  for (index = 0; index < *recur_parameter_dimension; ++index) {+    RECUR_USER_OPTIONS->Multi_Grid[index] =+      (recur_parameter_upper_bound[index] -+       recur_parameter_lower_bound[index]) / 100.0;+  }+  RECUR_USER_OPTIONS->Multi_Specify = 0;+#endif /* ASA_TEMPLATE */+#endif /* MULTI_MIN */+#if ASA_TEMPLATE_QUEUE+  RECUR_USER_OPTIONS->Queue_Size = 0;+#endif+#if ASA_QUEUE+#if ASA_RESOLUTION+  RECUR_USER_OPTIONS->Queue_Resolution =+    RECUR_USER_OPTIONS->Coarse_Resolution;+#else /* ASA_RESOLUTION */+  if ((RECUR_USER_OPTIONS->Queue_Resolution =+       (double *) calloc (*recur_parameter_dimension,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_initialize_parameters(): RECUR_USER_OPTIONS->Queue_Resolution");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* ASA_RESOLUTION */+#if ASA_TEMPLATE_QUEUE+  RECUR_USER_OPTIONS->Queue_Size = 0;+#endif+#endif /* ASA_QUEUE */+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_params */+  /* If not using RECUR_OPTIONS_FILE_DATA or data read from recur_asa_opt,+     store the recur_parameter ranges+     store the recur_parameter types+     store the initial recur_parameter values+     other changes needed for initialization */+#endif /* MY_TEMPLATE recur_params */+  RECUR_USER_OPTIONS->Asa_Recursive_Level = 1;++  return (0);+}++/***********************************************************************+* double recur_cost_function+*	This is the users cost function to optimize+*	(find the minimum).+*	cost_flag is set to TRUE if the parameter set+*	does not violates any constraints+*       recur_parameter_lower_bound and recur_parameter_upper_bound+*       may be adaptively changed during the search.+***********************************************************************/+#if HAVE_ANSI+double+recur_cost_function (double *x,+                     double *recur_parameter_lower_bound,+                     double *recur_parameter_upper_bound,+                     double *recur_cost_tangents,+                     double *recur_cost_curvature,+                     ALLOC_INT * recur_parameter_dimension,+                     int *recur_parameter_int_real,+                     int *recur_cost_flag,+                     int *recur_exit_code, USER_DEFINES * RECUR_USER_OPTIONS)+#else+double+recur_cost_function (x,+                     recur_parameter_lower_bound,+                     recur_parameter_upper_bound,+                     recur_cost_tangents,+                     recur_cost_curvature,+                     recur_parameter_dimension,+                     recur_parameter_int_real,+                     recur_cost_flag, recur_exit_code, RECUR_USER_OPTIONS)+     double *x;+     double *recur_parameter_lower_bound;+     double *recur_parameter_upper_bound;+     double *recur_cost_tangents;+     double *recur_cost_curvature;+     ALLOC_INT *recur_parameter_dimension;+     int *recur_parameter_int_real;+     int *recur_cost_flag;+     int *recur_exit_code;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif+{+  double cost_value;+  static LONG_INT recur_funevals = 0;+  int *exit_code;+#if OPTIONAL_DATA_PTR+  int data_ptr_flg;+#endif+#if OPTIONS_FILE+  FILE *ptr_options;+  char read_option[80];+  char read_if[4], read_FALSE[6], read_comm1[3], read_ASA_SAVE[9],+    read_comm2[3];+  int read_int;+#if INT_LONG+  LONG_INT read_long;+#endif+  double read_double;+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_cost_decl */+  /* add some declarations if required */+#endif++  double *parameter_lower_bound, *parameter_upper_bound;+  double *cost_parameters;+  double *cost_tangents, *cost_curvature;+  ALLOC_INT *parameter_dimension;+  int *parameter_int_real;+  int *cost_flag;+  static LONG_INT *rand_seed;+  static int initial_flag = 0;+#if MULTI_MIN+  int multi_index;+#endif++  USER_DEFINES *USER_OPTIONS;++  recur_funevals = recur_funevals + 1;++  if ((rand_seed = (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): rand_seed");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if ((USER_OPTIONS =+       (USER_DEFINES *) calloc (1, sizeof (USER_DEFINES))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): USER_OPTIONS");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if OPTIONS_FILE+  /* Test to see if asa_opt is in correct directory.+     This is useful for some PC and Mac compilers. */+  if ((ptr_options = fopen ("asa_opt", "r")) == NULL) {+    fprintf (ptr_out, "\n\n*** fopen asa_opt failed *** \n\n");+    fflush (ptr_out);+#if INCL_STDOUT+    printf ("\n\n*** EXIT fopen asa_opt failed *** \n\n");+#endif /* INCL_STDOUT */+    return (6);+  }++  fscanf (ptr_options, "%s%s%s%s%s",+          read_if, read_FALSE, read_comm1, read_ASA_SAVE, read_comm2);+  if (strcmp (read_if, "#if") || strcmp (read_FALSE, "FALSE") ||+      strcmp (read_comm1, "/*") || strcmp (read_ASA_SAVE, "ASA_SAVE") ||+      strcmp (read_comm2, "*/")) {+    fprintf (ptr_out, "\n\n*** not asa_opt for this version *** \n\n");+    fflush (ptr_out);+#if INCL_STDOUT+    printf ("\n\n*** EXIT not asa_opt for this version *** \n\n");+#endif /* INCL_STDOUT */+    return (-6);+  }+#if INT_LONG+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%ld", &read_long);+  USER_OPTIONS->Limit_Acceptances = read_long;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%ld", &read_long);+  USER_OPTIONS->Limit_Generated = read_long;+#else+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Limit_Acceptances = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Limit_Generated = read_int;+#endif+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Limit_Invalid_Generated_States = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Accepted_To_Generated_Ratio = read_double;++  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Cost_Precision = read_double;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Maximum_Cost_Repeat = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Number_Cost_Samples = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Temperature_Ratio_Scale = read_double;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Cost_Parameter_Scale_Ratio = read_double;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Temperature_Anneal_Scale = read_double;++  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Include_Integer_Parameters = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->User_Initial_Parameters = read_int;+#if INT_ALLOC+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Sequential_Parameters = read_int;+#else+#if INT_LONG+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%ld", &read_long);+  USER_OPTIONS->Sequential_Parameters = read_long;+#else+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Sequential_Parameters = read_int;+#endif+#endif+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Initial_Parameter_Temperature = read_double;++  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Acceptance_Frequency_Modulus = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Generated_Frequency_Modulus = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Reanneal_Cost = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Reanneal_Parameters = read_int;++  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%lf", &read_double);+  USER_OPTIONS->Delta_X = read_double;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->User_Tangents = read_int;+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%d", &read_int);+  USER_OPTIONS->Curvature_0 = read_int;+#else /* OPTIONS_FILE */+  /* USER_OPTIONS->Limit_Acceptances = 10000; */+  USER_OPTIONS->Limit_Acceptances = 1000;+  USER_OPTIONS->Limit_Generated = 99999;+  USER_OPTIONS->Limit_Invalid_Generated_States = 1000;+  USER_OPTIONS->Accepted_To_Generated_Ratio = 1.0E-6;++  USER_OPTIONS->Cost_Precision = 1.0E-18;+  USER_OPTIONS->Maximum_Cost_Repeat = 2;+  USER_OPTIONS->Number_Cost_Samples = 2;++  /* These variables are set below in x[.] */+  /* USER_OPTIONS->Temperature_Ratio_Scale = 1.0E-5; */+  /* USER_OPTIONS->Cost_Parameter_Scale_Ratio = 1.0; */++  USER_OPTIONS->Temperature_Anneal_Scale = 100.;++  USER_OPTIONS->Include_Integer_Parameters = FALSE;+  USER_OPTIONS->User_Initial_Parameters = FALSE;+  USER_OPTIONS->Sequential_Parameters = -1;+  USER_OPTIONS->Initial_Parameter_Temperature = 1.0;++  USER_OPTIONS->Acceptance_Frequency_Modulus = 100;+  USER_OPTIONS->Generated_Frequency_Modulus = 10000;+  USER_OPTIONS->Reanneal_Cost = 1;+  USER_OPTIONS->Reanneal_Parameters = TRUE;++  USER_OPTIONS->Delta_X = 0.001;+  USER_OPTIONS->User_Tangents = FALSE;+  USER_OPTIONS->Curvature_0 = TRUE;+#endif /* OPTIONS_FILE */++  USER_OPTIONS->Temperature_Ratio_Scale = x[0];+  USER_OPTIONS->Cost_Parameter_Scale_Ratio = x[1];++  if (initial_flag == 0) {+    /* first value of *rand_seed */+#if ASA_LIB+    *rand_seed = (asa_rand_seed ? *asa_rand_seed : (LONG_INT) 696969);+#else+    *rand_seed = 696969;+#endif+  }++  if ((parameter_dimension =+       (ALLOC_INT *) calloc (1, sizeof (ALLOC_INT))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): parameter_dimension");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((exit_code = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): exit_code");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((cost_flag = (int *) calloc (1, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): cost_flag");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  /* the number of parameters for the cost function */+#if OPTIONS_FILE_DATA+  fscanf (ptr_options, "%s", read_option);+  fscanf (ptr_options, "%s", read_option);++#if INT_ALLOC+  fscanf (ptr_options, "%d", &read_int);+  *parameter_dimension = read_int;+#else+#if INT_LONG+  fscanf (ptr_options, "%ld", &read_long);+  *parameter_dimension = read_long;+#else+  fscanf (ptr_options, "%d", &read_int);+  *parameter_dimension = read_int;+#endif+#endif++#else /* OPTIONS_FILE_DATA */+#if ASA_TEST+  /* set parameter dimension if SELF_OPTIMIZE=TRUE */+  *parameter_dimension = 4;+#endif /* ASA_TEST */+#endif /* OPTIONS_FILE_DATA */+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_dim */+  /* If not using OPTIONS_FILE_DATA or data read from asa_opt,+     set parameter dimension if SELF_OPTIMIZE=TRUE */+#endif /* MY_TEMPLATE recur_dim */++  if ((parameter_lower_bound =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): parameter_lower_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((parameter_upper_bound =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): parameter_upper_bound");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((cost_parameters =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): cost_parameters");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((parameter_int_real =+       (int *) calloc (*parameter_dimension, sizeof (int))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): parameter_int_real");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  if ((cost_tangents =+       (double *) calloc (*parameter_dimension, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "recur_cost_function(): cost_tangents");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  if (USER_OPTIONS->Curvature_0 == FALSE || USER_OPTIONS->Curvature_0 == -1) {+    if ((cost_curvature =+         (double *) calloc ((*parameter_dimension) *+                            (*parameter_dimension),+                            sizeof (double))) == NULL) {+      strcpy (user_exit_msg, "recur_cost_function(): cost_curvature");+      Exit_USER (user_exit_msg);+      return (-2);+    }+  } else {+    cost_curvature = (double *) NULL;+  }++#if ASA_TEMPLATE_SELFOPT+  /* Set memory to that required for use. */+  USER_OPTIONS->Asa_Data_Dim_Dbl = 2;+  if ((USER_OPTIONS->Asa_Data_Dbl =+       (double *) calloc (USER_OPTIONS->Asa_Data_Dim_Dbl,+                          sizeof (double))) == NULL) {+    strcpy (user_exit_msg,+            "recur_cost_function(): USER_OPTIONS->Asa_Data_Dbl");+    Exit_USER (user_exit_msg);+    return (-2);+  }+  /* Use Asa_Data_Dbl[0] as flag, e.g., if used with SELF_OPTIMIZE. */+  USER_OPTIONS->Asa_Data_Dbl[0] = 1.0;+#endif /* ASA_TEMPLATE_SELFOPT */++#if USER_COST_SCHEDULE+  USER_OPTIONS->Cost_Schedule = user_cost_schedule;+#endif+#if USER_ACCEPTANCE_TEST+  USER_OPTIONS->Acceptance_Test = user_acceptance_test;+#endif+#if USER_ACCEPT_ASYMP_EXP+  USER_OPTIONS->Asymp_Exp_Param = 1.0;+#endif+#if USER_GENERATING_FUNCTION+  USER_OPTIONS->Generating_Distrib = user_generating_distrib;+#endif+#if USER_REANNEAL_COST+  USER_OPTIONS->Reanneal_Cost_Function = user_reanneal_cost;+#endif+#if USER_REANNEAL_PARAMETERS+  USER_OPTIONS->Reanneal_Params_Function = user_reanneal_params;+#endif++  initialize_parameters (cost_parameters,+                         parameter_lower_bound,+                         parameter_upper_bound,+                         cost_tangents,+                         cost_curvature,+                         parameter_dimension, parameter_int_real,+#if OPTIONS_FILE_DATA+                         ptr_options,+#endif+                         USER_OPTIONS);+#if OPTIONS_FILE+  fclose (ptr_options);+#endif++#if ASA_SAVE+  USER_OPTIONS->Random_Array_Dim = SHUFFLE;+  USER_OPTIONS->Random_Array = random_array;+#endif /* ASA_SAVE */++  /* It might be a good idea to place a loop around this call,+     and to average over several values of funevals returned by+     trajectories of cost_value. */++  funevals = 0;++#if USER_ASA_OUT+  if ((USER_OPTIONS->Asa_Out_File =+       (char *) calloc (80, sizeof (char))) == NULL) {+    strcpy (user_exit_msg,+            "recur_cost_function(): USER_OPTIONS->Asa_Out_File");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#if ASA_TEMPLATE_SELFOPT+  strcpy (USER_OPTIONS->Asa_Out_File, "asa_rcur");+#endif+#endif++#if OPTIONAL_DATA_PTR+  data_ptr_flg = 1;+#if ASA_TEMPLATE+  /* N.b.:  If OPTIONAL_DATA_PTR is being used for RECUR_USER_OPTIONS+   * as well as for USER_OPTIONS, do not create (or free) additional memory+   * in recur_cost_function() for Asa_Data_Dim_Ptr and Asa_Data_Ptr to+   * be passed to the inner cost_function(), but rather link pointers to+   * those in RECUR_USER_OPTIONS.  Typically, define separate structures+   * within the structure defined by Asa_Data_Ptr to access info depending+   * on whether the run in a particular level of cost function in this+   * recursive operation.  In this case, set * #if TRUE to #if FALSE just+   * below.  See the ASA-README for more discussion.+   */++#if TRUE+  USER_OPTIONS->Asa_Data_Dim_Ptr = 1;+  if ((USER_OPTIONS->Asa_Data_Ptr =+       (OPTIONAL_PTR_TYPE *) calloc (USER_OPTIONS->Asa_Data_Dim_Ptr,+                                     sizeof (OPTIONAL_PTR_TYPE))) == NULL) {+    strcpy (user_exit_msg,+            "recur_cost_function(): USER_OPTIONS->Asa_Data_Ptr");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#else+  USER_OPTIONS->Asa_Data_Dim_Ptr = RECUR_USER_OPTIONS->Asa_Data_Dim_Ptr;+  USER_OPTIONS->Asa_Data_Ptr = RECUR_USER_OPTIONS->Asa_Data_Ptr;+  data_ptr_flg = 0;+#endif+#endif /* ASA_TEMPLATE */+  USER_OPTIONS->Asa_Data_Dim_Ptr = 1;+  if ((USER_OPTIONS->Asa_Data_Ptr =+       (OPTIONAL_PTR_TYPE *) calloc (USER_OPTIONS->Asa_Data_Dim_Ptr,+                                     sizeof (OPTIONAL_PTR_TYPE))) == NULL) {+    strcpy (user_exit_msg,+            "recur_cost_function(): USER_OPTIONS->Asa_Data_Ptr");+    Exit_USER (user_exit_msg);+    return (-2);+  }+#endif /* OPTIONAL_DATA_PTR */++  cost_value = asa (USER_COST_FUNCTION,+                    randflt,+                    rand_seed,+                    cost_parameters,+                    parameter_lower_bound,+                    parameter_upper_bound,+                    cost_tangents,+                    cost_curvature,+                    parameter_dimension,+                    parameter_int_real, cost_flag, exit_code, USER_OPTIONS);+  if (*exit_code == -1) {+#if INCL_STDOUT+    printf ("\n\n*** error in calloc in ASA ***\n\n");+#endif /* INCL_STDOUT */+    fprintf (ptr_out, "\n\n*** error in calloc in ASA ***\n\n");+    fflush (ptr_out);+    return (-1);+  }+#if MY_TEMPLATE                 /* MY_TEMPLATE_recur_post_asa */+#endif++  if (cost_value > .001) {+    *recur_cost_flag = FALSE;+  } else {+    *recur_cost_flag = TRUE;+  }++#if FALSE                       /* set to 1 to activate FAST EXIT */+  /* Make a quick exit */+  if (recur_funevals >= 10) {+    *recur_cost_flag = FALSE;+    RECUR_USER_OPTIONS->Limit_Invalid_Generated_States = 0;+    fprintf (ptr_out, "FAST EXIT set at recur_funevals = 10\n\n");+  }+#endif++#if TIME_CALC+  /* print every RECUR_PRINT_FREQUENCY evaluations */+  if ((RECUR_PRINT_FREQUENCY > 0) &&+      ((recur_funevals % RECUR_PRINT_FREQUENCY) == 0)) {+    USER_OPTIONS->Temperature_Ratio_Scale = x[0];+    fprintf (ptr_out, "USER_OPTIONS->Temperature_Ratio_Scale = %12.7g\n",+             USER_OPTIONS->Temperature_Ratio_Scale);+    USER_OPTIONS->Cost_Parameter_Scale_Ratio = x[1];+    fprintf (ptr_out, "USER_OPTIONS->Cost_Parameter_Scale_Ratio = %12.7g\n",+             USER_OPTIONS->Cost_Parameter_Scale_Ratio);+  }+  print_time ("", ptr_out);+#endif++  fprintf (ptr_out, "recur_funevals = %ld, *recur_cost_flag = %d\n",+           recur_funevals, *recur_cost_flag);+  /* cost function = number generated at best cost */+#if ASA_TEMPLATE_SELFOPT+  funevals = (LONG_INT) (USER_OPTIONS->Asa_Data_Dbl[1]);+  fprintf (ptr_out, "\tbest_funevals = %ld, cost_value = %12.7g\n\n",+           funevals, cost_value);+  /* cost function = total number generated during run */+#endif /* ASA_TEMPLATE_SELFOPT */++#if ASA_SAMPLE+  fprintf (ptr_out, "\tfunevals = %ld, cost_value = %12.7g\n\n",+           funevals, cost_value);+#endif+  fflush (ptr_out);++#if ASA_TEMPLATE_SAMPLE+  ptr_asa = fopen ("asa_out", "r");+  sample (ptr_out, ptr_asa);+#endif++#if OPTIONAL_DATA_DBL+  free (USER_OPTIONS->Asa_Data_Dbl);+#endif+#if OPTIONAL_DATA_INT+  free (USER_OPTIONS->Asa_Data_Int);+#endif+#if OPTIONAL_DATA_PTR+  if (data_ptr_flg == 1) {+    free (USER_OPTIONS->Asa_Data_Ptr);+  }+#endif+#if USER_ASA_OUT+  free (USER_OPTIONS->Asa_Out_File);+#endif+#if ASA_SAMPLE+  free (USER_OPTIONS->Bias_Generated);+#endif+#if ASA_QUEUE+#if ASA_RESOLUTION+#else+  free (USER_OPTIONS->Queue_Resolution);+#endif+#endif+#if ASA_RESOLUTION+  free (USER_OPTIONS->Coarse_Resolution);+#endif+  if (USER_OPTIONS->Curvature_0 == FALSE || USER_OPTIONS->Curvature_0 == -1)+    free (cost_curvature);+#if USER_INITIAL_PARAMETERS_TEMPS+  free (USER_OPTIONS->User_Parameter_Temperature);+#endif+#if USER_INITIAL_COST_TEMP+  free (USER_OPTIONS->User_Cost_Temperature);+#endif+#if DELTA_PARAMETERS+  free (USER_OPTIONS->User_Delta_Parameter);+#endif+#if QUENCH_PARAMETERS+  free (USER_OPTIONS->User_Quench_Param_Scale);+#endif+#if QUENCH_COST+  free (USER_OPTIONS->User_Quench_Cost_Scale);+#endif+#if RATIO_TEMPERATURE_SCALES+  free (USER_OPTIONS->User_Temperature_Ratio);+#endif+#if MULTI_MIN+  free (USER_OPTIONS->Multi_Grid);+  for (multi_index = 0; multi_index < USER_OPTIONS->Multi_Number;+       ++multi_index) {+    free (USER_OPTIONS->Multi_Params[multi_index]);+  }+#endif /* MULTI_MIN */+#if OPTIONAL_DATA_PTR+  if (data_ptr_flg == 0) {+    USER_OPTIONS = NULL;+  }+#endif+  free (USER_OPTIONS);+  free (parameter_dimension);+  free (exit_code);+  free (cost_flag);+  free (parameter_lower_bound);+  free (parameter_upper_bound);+  free (cost_parameters);+  free (parameter_int_real);+  free (cost_tangents);+  free (rand_seed);++  return ((double) funevals);+}++#if USER_COST_SCHEDULE+#if HAVE_ANSI+double+recur_user_cost_schedule (double test_temperature,+                          USER_DEFINES * RECUR_USER_OPTIONS)+#else+double+recur_user_cost_schedule (test_temperature, RECUR_USER_OPTIONS)+     double test_temperature;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif /* HAVE_ANSI */+{+#if ASA_TEMPLATE+  double x;++  x = test_temperature;++  return (x);+#endif+}+#endif /* USER_COST_SCHEDULE */++#if USER_ACCEPTANCE_TEST+#if HAVE_ANSI+void+recur_user_acceptance_test (double current_cost,+                            double *recur_parameter_lower_bound,+                            double *recur_parameter_upper_bound,+                            ALLOC_INT * recur_parameter_dimension,+                            USER_DEFINES * RECUR_USER_OPTIONS)+#else+void+recur_user_acceptance_test (current_cost, recur_parameter_lower_bound,+                            recur_parameter_upper_bound,+                            recur_parameter_dimension, RECUR_USER_OPTIONS)+     double current_cost;+     double *recur_parameter_lower_bound;+     double *recur_parameter_upper_bound;+     ALLOC_INT *recur_parameter_dimension;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif /* HAVE_ANSI */+{+  double uniform_test, curr_cost_temp;+#if USER_ACCEPT_ASYMP_EXP+  double x, q, delta_cost;+#endif++#if ASA_TEMPLATE                /* ASA cost index */+  /* Calculate the current ASA cost index.  This could be useful+     to define a new schedule for the cost temperature, beyond+     simple changes that can be made using USER_COST_SCHEDULE. */++  int index;+  double k_temperature, quench, y;+  double xrecur_parameter_dimension;++#if QUENCH_COST+  quench = RECUR_USER_OPTIONS->User_Quench_Cost_Scale[0];+#else+  quench = 1.0;+#endif /* QUENCH_COST */+  xrecur_parameter_dimension = (double) *recur_parameter_dimension;+  for (index = 0; index < *recur_parameter_dimension; ++index)+    if (fabs+        (recur_parameter_upper_bound[index] -+         recur_parameter_lower_bound[index]) < (double) EPS_DOUBLE)+      *xrecur_parameter_dimension -= 1.0;++  y = -F_LOG (RECUR_USER_OPTIONS->Cost_Temp_Curr+              / RECUR_USER_OPTIONS->Cost_Temp_Init)+    / RECUR_USER_OPTIONS->Cost_Temp_Scale;++  k_temperature = F_POW (y, xrecur_parameter_dimension / quench);+#endif /* ASA cost index */++  uniform_test = randflt (RECUR_USER_OPTIONS->Random_Seed);+  curr_cost_temp = RECUR_USER_OPTIONS->Cost_Temp_Curr;++#if ASA_TEMPLATE+#if USER_COST_SCHEDULE+  curr_cost_temp =+    (RECUR_USER_OPTIONS->Cost_Schedule (RECUR_USER_OPTIONS->Cost_Temp_Curr,+                                        RECUR_USER_OPTIONS)+     + (double) EPS_DOUBLE);+#else+  curr_cost_temp = RECUR_USER_OPTIONS->Cost_Temp_Curr;+#endif+#endif /* ASA_TEMPLATE */++#if USER_ACCEPT_ASYMP_EXP+#if USER_COST_SCHEDULE+  curr_cost_temp =+    (RECUR_USER_OPTIONS->Cost_Schedule (RECUR_USER_OPTIONS->Cost_Temp_Curr,+                                        RECUR_USER_OPTIONS)+     + (double) EPS_DOUBLE);+#endif++  delta_cost = (current_cost - *(RECUR_USER_OPTIONS->Last_Cost))+    / (curr_cost_temp + (double) EPS_DOUBLE);++  q = RECUR_USER_OPTIONS->Asymp_Exp_Param;+  if (fabs (1.0 - q) < (double) EPS_DOUBLE)+    x = MIN (1.0, (F_EXP (-delta_cost)));       /* Boltzmann test */+  else if ((1.0 - (1.0 - q) * delta_cost) < (double) EPS_DOUBLE)+    x = MIN (1.0, (F_EXP (-delta_cost)));       /* Boltzmann test */+  else+    x = MIN (1.0, F_POW ((1.0 - (1.0 - q) * delta_cost), (1.0 / (1.0 - q))));++  RECUR_USER_OPTIONS->Prob_Bias = x;+  if (x >= uniform_test)+    RECUR_USER_OPTIONS->User_Acceptance_Flag = TRUE;+  else+    RECUR_USER_OPTIONS->User_Acceptance_Flag = FALSE;++#endif /* USER_ACCEPT_ASYMP_EXP */+}+#endif /* USER_ACCEPTANCE_TEST */++#if USER_GENERATING_FUNCTION+#if HAVE_ANSI+double+recur_user_generating_distrib (LONG_INT * seed,+                               ALLOC_INT * recur_parameter_dimension,+                               ALLOC_INT index_v,+                               double temperature_v,+                               double init_param_temp_v,+                               double temp_scale_params_v,+                               double parameter_v,+                               double parameter_range_v,+                               double *last_saved_parameter,+                               USER_DEFINES * RECUR_USER_OPTIONS)+#else+double+recur_user_generating_distrib (seed,+                               recur_parameter_dimension,+                               index_v,+                               temperature_v,+                               init_param_temp_v,+                               temp_scale_params_v,+                               parameter_v,+                               parameter_range_v,+                               last_saved_parameter, RECUR_USER_OPTIONS)+     LONG_INT *seed;+     ALLOC_INT *recur_parameter_dimension;+     ALLOC_INT index_v;+     double temperature_v;+     double init_param_temp_v;+     double temp_scale_params_v;+     double parameter_v;+     double parameter_range_v;+     double *last_saved_parameter;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif+{+#if ASA_TEMPLATE+  double x, y, z;++  /* This is the ASA distribution.  A slower temperature schedule can be+     obtained here, e.g., temperature_v = pow(temperature_v, 0.5); */++  x = randflt (seed);+  y = x < 0.5 ? -1.0 : 1.0;+  z = y * temperature_v * (F_POW ((1.0 + 1.0 / temperature_v),+                                  fabs (2.0 * x - 1.0)) - 1.0);++  x = parameter_v + z * parameter_range_v;++  return (x);+#endif /* ASA_TEMPLATE */+}+#endif /* USER_GENERATING_FUNCTION */++#if USER_REANNEAL_COST+#if HAVE_ANSI+int+recur_user_reanneal_cost (double *cost_best,+                          double *cost_last,+                          double *initial_cost_temperature,+                          double *current_cost_temperature,+                          USER_DEFINES * RECUR_USER_OPTIONS)+#else+int+recur_user_reanneal_cost (cost_best,+                          cost_last,+                          initial_cost_temperature,+                          current_cost_temperature, RECUR_USER_OPTIONS)+     double *cost_best;+     double *cost_last;+     double *initial_cost_temperature;+     double *current_cost_temperature;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif /* HAVE_ANSI */+{+#if ASA_TEMPLATE+  double tmp_dbl;++  tmp_dbl = MAX (fabs (*cost_last), fabs (*cost_best));+  tmp_dbl = MAX ((double) EPS_DOUBLE, tmp_dbl);+  *initial_cost_temperature = MIN (*initial_cost_temperature, tmp_dbl);++  return (TRUE);+#endif+}+#endif /* USER_REANNEAL_COST */++#if USER_REANNEAL_PARAMETERS+#if HAVE_ANSI+double+recur_user_reanneal_params (double current_temp,+                            double tangent,+                            double max_tangent,+                            USER_DEFINES * RECUR_USER_OPTIONS)+#else+double+recur_user_reanneal_params (current_temp,+                            tangent, max_tangent, RECUR_USER_OPTIONS)+     double current_temp;+     double tangent;+     double max_tangent;+     USER_DEFINES *RECUR_USER_OPTIONS;+#endif /* HAVE_ANSI */+{+#if ASA_TEMPLATE+  double x;++  x = current_temp * (max_tangent / tangent);++  return (x);+#endif+}+#endif /* USER_REANNEAL_PARAMETERS */+#endif /* SELF_OPTIMIZE */++#if FITLOC+#if HAVE_ANSI+double+calcf (double (*user_cost_function)++        +       (double *, double *, double *, double *, double *, ALLOC_INT *, int *,+        int *, int *, USER_DEFINES *), double *xloc,+       double *parameter_lower_bound, double *parameter_upper_bound,+       double *cost_tangents, double *cost_curvature,+       ALLOC_INT * parameter_dimension, int *parameter_int_real,+       int *cost_flag, int *exit_code, USER_DEFINES * OPTIONS, FILE * ptr_out)+#else+double+calcf (user_cost_function,+       xloc,+       parameter_lower_bound,+       parameter_upper_bound,+       cost_tangents,+       cost_curvature,+       parameter_dimension,+       parameter_int_real, cost_flag, exit_code, OPTIONS, ptr_out)+     double (*user_cost_function) ();+     double *x;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+     int *cost_flag;+     int *exit_code;+     USER_DEFINES *OPTIONS;+     FILE *ptr_out;+#endif+{+  ALLOC_INT index_v;+#if FITLOC_ROUND+  double x, min_parameter_v, max_parameter_v, parameter_range_v;+#endif+  double floc;+#if ASA_RESOLUTION+  double xres, xint, xplus, xminus, dx, dxminus, dxplus;+#endif++#if FITLOC_ROUND+  /* The following section for adjustments of parameters is taken from+     generate_new_state() in asa.c */+  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    if (fabs+        (parameter_lower_bound[index_v] - parameter_upper_bound[index_v]) <+        EPS_DOUBLE)+      continue;++    x = xloc[index_v];++    min_parameter_v = parameter_lower_bound[index_v];+    max_parameter_v = parameter_upper_bound[index_v];+    parameter_range_v = max_parameter_v - min_parameter_v;++    /* Handle discrete parameters. */+#if ASA_RESOLUTION+    xres = OPTIONS->Coarse_Resolution[index_v];+    if (xres > EPS_DOUBLE) {+      min_parameter_v -= (xres / 2.0);+      max_parameter_v += (xres / 2.0);+      parameter_range_v = max_parameter_v - min_parameter_v;+    }+#endif /* ASA_RESOLUTION */+    if (parameter_int_real[index_v] > 0) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        min_parameter_v -= 0.5;+        max_parameter_v += 0.5;+        parameter_range_v = max_parameter_v - min_parameter_v;+      }+#if ASA_RESOLUTION+    }+#endif+#if ASA_RESOLUTION+    if (xres > EPS_DOUBLE) {+      xint = xres * (double) ((LONG_INT) (x / xres));+      xplus = xint + xres;+      xminus = xint - xres;+      dx = fabs (xint - x);+      dxminus = fabs (xminus - x);+      dxplus = fabs (xplus - x);++      if (dx < dxminus && dx < dxplus)+        x = xint;+      else if (dxminus < dxplus)+        x = xminus;+      else+        x = xplus;+    }+#endif /* ASA_RESOLUTION */++    /* Handle discrete parameters.+       You might have to check rounding on your machine. */+    if (parameter_int_real[index_v] > 0) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        if (x < min_parameter_v + 0.5)+          x = min_parameter_v + 0.5 + (double) EPS_DOUBLE;+        if (x > max_parameter_v - 0.5)+          x = max_parameter_v - 0.5 + (double) EPS_DOUBLE;++        if (x + 0.5 > 0.0) {+          x = (double) ((LONG_INT) (x + 0.5));+        } else {+          x = (double) ((LONG_INT) (x - 0.5));+        }+        if (x > parameter_upper_bound[index_v])+          x = parameter_upper_bound[index_v];+        if (x < parameter_lower_bound[index_v])+          x = parameter_lower_bound[index_v];+      }+#if ASA_RESOLUTION+    }+    if (xres > EPS_DOUBLE) {+      if (x < min_parameter_v + xres / 2.0)+        x = min_parameter_v + xres / 2.0 + (double) EPS_DOUBLE;+      if (x > max_parameter_v - xres / 2.0)+        x = max_parameter_v - xres / 2.0 + (double) EPS_DOUBLE;++      if (x > parameter_upper_bound[index_v])+        x = parameter_upper_bound[index_v];+      if (x < parameter_lower_bound[index_v])+        x = parameter_lower_bound[index_v];+    }+#endif /* ASA_RESOLUTION */+    if ((x < parameter_lower_bound[index_v])+        || (x > parameter_upper_bound[index_v])) {+      ;+    } else {+      xloc[index_v] = x;+    }+  }+#endif /* FITLOC_ROUND */++  floc = user_cost_function (xloc,+                             parameter_lower_bound,+                             parameter_upper_bound,+                             cost_tangents,+                             cost_curvature,+                             parameter_dimension,+                             parameter_int_real,+                             cost_flag, exit_code, OPTIONS);++  if (*cost_flag == FALSE) {+    floc += OPTIONS->Penalty;+  }++  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    if (parameter_upper_bound[index_v] - xloc[index_v] < EPS_DOUBLE)+      floc += OPTIONS->Penalty;+    else if (xloc[index_v] - parameter_lower_bound[index_v] < EPS_DOUBLE)+      floc += OPTIONS->Penalty;+  }++  return (floc);+}++#if HAVE_ANSI+double+fitloc (double (*user_cost_function)++         +        (double *, double *, double *, double *, double *, ALLOC_INT *, int *,+         int *, int *, USER_DEFINES *), double *xloc,+        double *parameter_lower_bound, double *parameter_upper_bound,+        double *cost_tangents, double *cost_curvature,+        ALLOC_INT * parameter_dimension, int *parameter_int_real,+        int *cost_flag, int *exit_code, USER_DEFINES * OPTIONS,+        FILE * ptr_out)+#else+double+fitloc (user_cost_function,+        xloc,+        parameter_lower_bound,+        parameter_upper_bound,+        cost_tangents,+        cost_curvature,+        parameter_dimension,+        parameter_int_real, cost_flag, exit_code, OPTIONS, ptr_out)+     double (*user_cost_function) ();+     double *xloc;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+     int *cost_flag;+     int *exit_code;+     USER_DEFINES *OPTIONS;+     FILE *ptr_out;+#endif+{+  double x;+  ALLOC_INT index_v;+#if FITLOC_ROUND+  double min_parameter_v, max_parameter_v, parameter_range_v;+#endif+  double *xsave;+  double tol1, tol2, alpha, beta1, beta2, gamma, delta, floc, fsave, ffinal;+  int no_progress, tot_iters, locflg, bndflg;+#if ASA_RESOLUTION+  double xres, xint, xminus, xplus, dx, dxminus, dxplus;+#endif++#if FITLOC_PRINT+  if (OPTIONS->Fit_Local >= 1) {+    fprintf (ptr_out, "\n\nSTART LOCAL FIT\n");+  } else {+    fprintf (ptr_out, "\n\nSTART LOCAL FIT Independent of ASA\n");+  }+  fflush (ptr_out);+#endif /* FITLOC_PRINT */++  xsave = (double *) calloc (*parameter_dimension, sizeof (double));+  bndflg = 0;++  /* The following simplex parameters may need adjustments for your system. */+  tol1 = EPS_DOUBLE;+  tol2 = EPS_DOUBLE * 100.;+  no_progress = 4;+  alpha = 1.0;+  beta1 = 0.75;+  beta2 = 0.75;+  gamma = 1.25;+  delta = 2.50;++  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    xsave[index_v] = xloc[index_v];+  }++  fsave = user_cost_function (xloc,+                              parameter_lower_bound,+                              parameter_upper_bound,+                              cost_tangents,+                              cost_curvature,+                              parameter_dimension,+                              parameter_int_real,+                              cost_flag, exit_code, OPTIONS);++  tot_iters = simplex (user_cost_function,+                       xloc,+                       parameter_lower_bound,+                       parameter_upper_bound,+                       cost_tangents,+                       cost_curvature,+                       parameter_dimension,+                       parameter_int_real,+                       cost_flag,+                       exit_code,+                       OPTIONS,+                       ptr_out,+                       tol1,+                       tol2, no_progress, alpha, beta1, beta2, gamma, delta);+  fflush (ptr_out);++  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    x = xloc[index_v];+    if ((x < parameter_lower_bound[index_v])+        || (x > parameter_upper_bound[index_v])) {+      bndflg = 1;+    }+  }++  /* The following section for adjustments of parameters is taken from+     generate_new_state() in asa.c */+#if FITLOC_ROUND+  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    if (fabs+        (parameter_lower_bound[index_v] - parameter_upper_bound[index_v]) <+        EPS_DOUBLE)+      continue;++    x = xloc[index_v];++    min_parameter_v = parameter_lower_bound[index_v];+    max_parameter_v = parameter_upper_bound[index_v];+    parameter_range_v = max_parameter_v - min_parameter_v;++    /* Handle discrete parameters. */+#if ASA_RESOLUTION+    xres = OPTIONS->Coarse_Resolution[index_v];+    if (xres > EPS_DOUBLE) {+      min_parameter_v -= (xres / 2.0);+      max_parameter_v += (xres / 2.0);+      parameter_range_v = max_parameter_v - min_parameter_v;+    }+#endif /* ASA_RESOLUTION */+    if (parameter_int_real[index_v] > 0) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        min_parameter_v -= 0.5;+        max_parameter_v += 0.5;+        parameter_range_v = max_parameter_v - min_parameter_v;+      }+#if ASA_RESOLUTION+    }+#endif+#if ASA_RESOLUTION+    if (xres > EPS_DOUBLE) {+      xint = xres * (double) ((LONG_INT) (x / xres));+      xplus = xint + xres;+      xminus = xint - xres;+      dx = fabs (xint - x);+      dxminus = fabs (xminus - x);+      dxplus = fabs (xplus - x);++      if (dx < dxminus && dx < dxplus)+        x = xint;+      else if (dxminus < dxplus)+        x = xminus;+      else+        x = xplus;+    }+#endif /* ASA_RESOLUTION */++    /* Handle discrete parameters.+       You might have to check rounding on your machine. */+    if (parameter_int_real[index_v] > 0) {+#if ASA_RESOLUTION+      if (xres > EPS_DOUBLE) {+        ;+      } else {+#endif /* ASA_RESOLUTION */+        if (x < min_parameter_v + 0.5)+          x = min_parameter_v + 0.5 + (double) EPS_DOUBLE;+        if (x > max_parameter_v - 0.5)+          x = max_parameter_v - 0.5 + (double) EPS_DOUBLE;++        if (x + 0.5 > 0.0) {+          x = (double) ((LONG_INT) (x + 0.5));+        } else {+          x = (double) ((LONG_INT) (x - 0.5));+        }+        if (x > parameter_upper_bound[index_v])+          x = parameter_upper_bound[index_v];+        if (x < parameter_lower_bound[index_v])+          x = parameter_lower_bound[index_v];+      }+#if ASA_RESOLUTION+    }+    if (xres > EPS_DOUBLE) {+      if (x < min_parameter_v + xres / 2.0)+        x = min_parameter_v + xres / 2.0 + (double) EPS_DOUBLE;+      if (x > max_parameter_v - xres / 2.0)+        x = max_parameter_v - xres / 2.0 + (double) EPS_DOUBLE;++      if (x > parameter_upper_bound[index_v])+        x = parameter_upper_bound[index_v];+      if (x < parameter_lower_bound[index_v])+        x = parameter_lower_bound[index_v];+    }+#endif /* ASA_RESOLUTION */+    if ((x < parameter_lower_bound[index_v])+        || (x > parameter_upper_bound[index_v])) {+      bndflg = 1;+#if FITLOC_PRINT+      if (OPTIONS->Fit_Local == 2)+        fprintf (ptr_out, "IGNORE FITLOC: OUT OF BOUNDS xloc[%ld] = %g\n",+                 index_v, xloc[index_v]);+      else+        fprintf (ptr_out, "OUT OF BOUNDS xloc[%ld] = %g\n",+                 index_v, xloc[index_v]);+#else+      ;+#endif /* FITLOC_PRINT */+    } else {+      xloc[index_v] = x;+    }+  }+#endif /* FITLOC_ROUND */++  floc = user_cost_function (xloc,+                             parameter_lower_bound,+                             parameter_upper_bound,+                             cost_tangents,+                             cost_curvature,+                             parameter_dimension,+                             parameter_int_real,+                             cost_flag, exit_code, OPTIONS);++  if (fabs (floc - fsave) < (double) EPS_DOUBLE) {+    locflg = 1;+    ffinal = fsave;+#if FITLOC_PRINT+    fprintf (ptr_out, "\nsame global cost = %g\tlocal cost = %g\n\n",+             fsave, floc);+#endif /* FITLOC_PRINT */+  } else {+    if (floc < fsave) {+      if (OPTIONS->Fit_Local == 2 && bndflg == 1) {+        locflg = 1;+        ffinal = fsave;+      } else {+        locflg = 0;+        ffinal = floc;+      }+    } else {+      locflg = 1;+      ffinal = fsave;+    }+#if FITLOC_PRINT+    fprintf (ptr_out, "\nDIFF global cost = %g\tlocal cost = %g\n\n",+             fsave, floc);+#endif /* FITLOC_PRINT */+  }++  for (index_v = 0; index_v < *parameter_dimension; ++index_v) {+    if (fabs (xloc[index_v] - xsave[index_v]) < (double) EPS_DOUBLE) {+#if FITLOC_PRINT+      fprintf (ptr_out, "same global param[%ld] = %g\tlocal param = %g\n",+               index_v, xsave[index_v], xloc[index_v]);+#else+      ;+#endif /* FITLOC_PRINT */+    } else {+#if FITLOC_PRINT+      fprintf (ptr_out, "DIFF global param[%ld] = %g\tlocal param = %g\n",+               index_v, xsave[index_v], xloc[index_v]);+#else+      ;+#endif /* FITLOC_PRINT */+      if (locflg == 1) {+        xloc[index_v] = xsave[index_v];+      }+    }+  }++#if FITLOC_PRINT+  fprintf (ptr_out, "\n");+  fflush (ptr_out);+#endif /* FITLOC_PRINT */++  free (xsave);++  return (ffinal);+}++/*+   Written by Mark Johnson <mjohnson@netcom.com>, based on ++   %A J.A. Nelder+   %A R. Mead+   %T A simplex method for function minimization+   %J Computer J. (UK)+   %V 7+   %D 1964+   %P 308-313++   with improvements from++   %A G.P. Barabino+   %A G.S. Barabino+   %A B. Bianco+   %A M. Marchesi+   %T A study on the performances of simplex methods for function minimization+   %B Proc. IEEE Int. Conf. Circuits and Computers+   %D 1980+   %P 1150-1153++   adapted for use in ASA by Lester Ingber <ingber@ingber.com>+ */++#if HAVE_ANSI+int+simplex (double (*user_cost_function)++          +         (double *, double *, double *, double *, double *, ALLOC_INT *,+          int *, int *, int *, USER_DEFINES *), double *x,+         double *parameter_lower_bound, double *parameter_upper_bound,+         double *cost_tangents, double *cost_curvature,+         ALLOC_INT * parameter_dimension, int *parameter_int_real,+         int *cost_flag, int *exit_code, USER_DEFINES * OPTIONS,+         FILE * ptr_out, double tol1, double tol2, int no_progress,+         double alpha, double beta1, double beta2, double gamma, double delta)+#else+int+simplex (user_cost_function,+         x,+         parameter_lower_bound,+         parameter_upper_bound,+         cost_tangents,+         cost_curvature,+         parameter_dimension,+         parameter_int_real,+         cost_flag,+         exit_code,+         OPTIONS,+         ptr_out, tol1, tol2, no_progress, alpha, beta1, beta2, gamma, delta)+     double (*user_cost_function) ();+     double *x;+     double *parameter_lower_bound;+     double *parameter_upper_bound;+     double *cost_tangents;+     double *cost_curvature;+     ALLOC_INT *parameter_dimension;+     int *parameter_int_real;+     int *cost_flag;+     int *exit_code;+     USER_DEFINES *OPTIONS;+     FILE *ptr_out;+     double tol1;+     double tol2;+     int no_progress;+     double alpha;+     double beta1;+     double beta2;+     double gamma;+     double delta;+#endif+{+  double fs, fl, fh, fr, fe, fc1, fc2, ftmp, flast;+  double err1;+  double *fvals;+  double **splx;                /* the simplex of points */+  double *x0;                   /* centroid of simplex */+  double *xr;                   /* point for a reflection */+  double *xe;                   /* point for an expansion */+  double *xc1;                  /* point for a minor contraction */+  double *xc2;                  /* point for a major contraction */+  int s, l, h;+  int i, j, iters, futility;+  int lastprint;++  fvals = (double *) calloc (*parameter_dimension + 1, sizeof (double));+  splx = (double **) calloc (*parameter_dimension + 1, sizeof (double *));+  for (i = 0; i <= *parameter_dimension; i++)+    splx[i] = (double *) calloc (*parameter_dimension, sizeof (double));+  x0 = (double *) calloc (*parameter_dimension, sizeof (double));+  xr = (double *) calloc (*parameter_dimension, sizeof (double));+  xe = (double *) calloc (*parameter_dimension, sizeof (double));+  xc1 = (double *) calloc (*parameter_dimension, sizeof (double));+  xc2 = (double *) calloc (*parameter_dimension, sizeof (double));++  /* build the initial simplex */+  for (i = 0; i < *parameter_dimension; i++) {+    splx[0][i] = x[i];+  }+  for (i = 1; i <= *parameter_dimension; i++) {+    for (j = 0; j < *parameter_dimension; j++) {+      if ((j + 1) == i)+        splx[i][j] = (x[j] * 2.25) + tol2;+      else+        splx[i][j] = x[j];+      xr[j] = splx[i][j];+    }+    fvals[i] = calcf (user_cost_function,+                      xr,+                      parameter_lower_bound,+                      parameter_upper_bound,+                      cost_tangents,+                      cost_curvature,+                      parameter_dimension,+                      parameter_int_real,+                      cost_flag, exit_code, OPTIONS, ptr_out);+  }++  /* and of course compute function at starting point */+  fvals[0] = calcf (user_cost_function,+                    x,+                    parameter_lower_bound,+                    parameter_upper_bound,+                    cost_tangents,+                    cost_curvature,+                    parameter_dimension,+                    parameter_int_real,+                    cost_flag, exit_code, OPTIONS, ptr_out);++  /* now find the largest, 2nd largest, smallest f values */+  if (fvals[0] > fvals[1]) {+    h = 0;+    s = 1;+    l = 1;+  } else {+    h = 1;+    s = 0;+    l = 0;+  }+  fh = fvals[h];+  fs = fvals[s];+  fl = fvals[l];+  for (i = 2; i <= *parameter_dimension; i++) {+    if (fvals[i] <= fvals[l]) {+      l = i;+      fl = fvals[i];+    } else {+      if (fvals[i] >= fvals[h]) {+        s = h;+        fs = fh;+        h = i;+        fh = fvals[i];+      } else if (fvals[i] >= fvals[s]) {+        s = i;+        fs = fvals[i];+      }+    }+  }+#if FITLOC_PRINT+  if ((s == h) || (s == l) || (h == l))+    fprintf (ptr_out, "\nPANIC: s,l,h not unique %d %d %d\n", s, h, l);++  fprintf (ptr_out, "INITIAL SIMPLEX:\n");+  for (i = 0; i <= *parameter_dimension; i++) {+    for (j = 0; j < *parameter_dimension; j++) {+      fprintf (ptr_out, "   %11.4g", splx[i][j]);+    }+    fprintf (ptr_out, "      f = %12.5g", fvals[i]);+    if (i == h)+      fprintf (ptr_out, "  HIGHEST");+    if (i == s)+      fprintf (ptr_out, "  SECOND HIGHEST");+    if (i == l)+      fprintf (ptr_out, "  LOWEST");+    fprintf (ptr_out, "\n");+  }+#endif /* FITLOC_PRINT */++/* MAJOR LOOP */++  flast = fl;+  futility = 0;+  lastprint = 0;+  iters = 0;+  err1 = 1.1 + (1.1 * tol1);+  while ((err1 > tol1) && (iters < OPTIONS->Iter_Max) &&+         (futility < (*parameter_dimension * no_progress))) {+    iters++;++    /* now find the largest, 2nd largest, smallest f values */+    if (fvals[0] > fvals[1]) {+      h = 0;+      s = 1;+      l = 1;+    } else {+      h = 1;+      s = 0;+      l = 0;+    }+    fh = fvals[h];+    fs = fvals[s];+    fl = fvals[l];+    for (i = 2; i <= *parameter_dimension; i++) {+      if (fvals[i] <= fvals[l]) {+        l = i;+        fl = fvals[i];+      } else {+        if (fvals[i] >= fvals[h]) {+          s = h;+          fs = fh;+          h = i;+          fh = fvals[i];+        } else if (fvals[i] >= fvals[s]) {+          s = i;+          fs = fvals[i];+        }+      }+    }+#if FITLOC_PRINT+    if ((s == h) || (s == l) || (h == l))+      fprintf (ptr_out, "\nPANIC: s,l,h not unique %d %d %d\n", s, h, l);+#endif++    /* compute the centroid */+    for (j = 0; j < *parameter_dimension; j++) {+      x0[j] = 0.0;+      for (i = 0; i <= *parameter_dimension; i++) {+        if (i != h)+          x0[j] += splx[i][j];+      }+      x0[j] /= ((double) *parameter_dimension);+    }++    if (fl < flast) {+      flast = fl;+      futility = 0;+    } else+      futility += 1;++#if FITLOC_PRINT+    fprintf (ptr_out, "Iteration %3d f(best) = %12.6g halt? = %11.5g\n",+             iters, fl, err1);+    if ((iters - lastprint) >= 100) {+      fprintf (ptr_out, "\n     Best point seen so far:\n");+      for (i = 0; i < *parameter_dimension; i++) {+        fprintf (ptr_out, "     x[%3d] = %15.7g\n", i, splx[l][i]);+      }+      lastprint = iters;+      fprintf (ptr_out, "\n");+    }+    fflush (ptr_out);+#endif /* FITLOC_PRINT */++    /* STEP 1: compute a reflected point xr */+    for (i = 0; i < *parameter_dimension; i++) {+      xr[i] = ((1.0 + alpha) * x0[i]) - (alpha * splx[h][i]);+    }+    fr = calcf (user_cost_function,+                xr,+                parameter_lower_bound,+                parameter_upper_bound,+                cost_tangents,+                cost_curvature,+                parameter_dimension,+                parameter_int_real, cost_flag, exit_code, OPTIONS, ptr_out);++    /* typical outcome: <2nd-biggest , >lowest .  Go again */+    if ((fr < fs) && (fr > fl)) {+      for (i = 0; i < *parameter_dimension; i++) {+        splx[h][i] = xr[i];+      }+      fvals[h] = fr;+      goto more_iterations;+    }++    /* STEP 2: if reflected point is favorable, expand the simplex */+    if (fr < fl) {+      for (i = 0; i < *parameter_dimension; i++) {+        xe[i] = (gamma * xr[i]) + ((1.0 - gamma) * x0[i]);+      }+      fe = calcf (user_cost_function,+                  xe,+                  parameter_lower_bound,+                  parameter_upper_bound,+                  cost_tangents,+                  cost_curvature,+                  parameter_dimension,+                  parameter_int_real, cost_flag, exit_code, OPTIONS, ptr_out);+      if (fe < fr) {            /* win big; expansion point tiny */+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xe[i];+        }+        fvals[h] = fh = fe;+      } else+        /* still ok; reflection point a winner */+      {+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xr[i];+        }+        fvals[h] = fh = fr;+      }+      goto more_iterations;+    }++    /* STEP 3: if reflected point is unfavorable, contract simplex */+    if (fr > fs) {+      if (fr < fh) {            /* may as well replace highest pt */+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xr[i];+        }+        fvals[h] = fh = fr;+      }+      for (i = 0; i < *parameter_dimension; i++) {+        xc1[i] = (beta1 * xr[i]) + ((1.0 - beta1) * x0[i]);+      }+      fc1 = calcf (user_cost_function,+                   xc1,+                   parameter_lower_bound,+                   parameter_upper_bound,+                   cost_tangents,+                   cost_curvature,+                   parameter_dimension,+                   parameter_int_real,+                   cost_flag, exit_code, OPTIONS, ptr_out);+      if (fc1 < fh) {           /* slight contraction worked */+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xc1[i];+        }+        fvals[h] = fh = fc1;+        goto more_iterations;+      }+      /* now have to try strong contraction */+      for (i = 0; i < *parameter_dimension; i++) {+        xc2[i] = (beta2 * splx[h][i]) + ((1.0 - beta2) * x0[i]);+      }+      fc2 = calcf (user_cost_function,+                   xc2,+                   parameter_lower_bound,+                   parameter_upper_bound,+                   cost_tangents,+                   cost_curvature,+                   parameter_dimension,+                   parameter_int_real,+                   cost_flag, exit_code, OPTIONS, ptr_out);+      if (fc2 < fh) {           /* strong contraction worked */+        for (i = 0; i < *parameter_dimension; i++) {+          splx[h][i] = xc2[i];+        }+        fvals[h] = fh = fc2;+        goto more_iterations;+      }+    }++    /* STEP 4: nothing worked.  collapse the simplex around xl */+    for (i = 0; i <= *parameter_dimension; i++) {+      if (i != l) {+        for (j = 0; j < *parameter_dimension; j++) {+          splx[i][j] = (splx[i][j] + splx[l][j]) / delta;+          xr[j] = splx[i][j];+        }+        fvals[i] = calcf (user_cost_function,+                          xr,+                          parameter_lower_bound,+                          parameter_upper_bound,+                          cost_tangents,+                          cost_curvature,+                          parameter_dimension,+                          parameter_int_real,+                          cost_flag, exit_code, OPTIONS, ptr_out);+      }+    }++  more_iterations:++    ftmp = 0.00;+    for (i = 0; i <= *parameter_dimension; i++) {+      ftmp += fvals[i];+    }+    ftmp /= ((double) (*parameter_dimension + 1));++    err1 = 0.00;+    for (i = 0; i <= *parameter_dimension; i++) {+      err1 += ((fvals[i] - ftmp) * (fvals[i] - ftmp));+    }+    err1 /= ((double) (*parameter_dimension + 1));+    err1 = sqrt (err1);+  }                             /* end of major while loop */++  /* find the smallest f value */+  l = 0;+  fl = fvals[0];+  for (i = 1; i <= *parameter_dimension; i++) {+    if (fvals[i] < fvals[l])+      l = i;+  }++  /* give it back to the user */+  for (i = 0; i < *parameter_dimension; i++) {+    x[i] = splx[l][i];+  }++  free (fvals);+  for (i = 0; i <= *parameter_dimension; i++)+    free (splx[i]);+  free (splx);+  free (x0);+  free (xr);+  free (xe);+  free (xc1);+  free (xc2);++  return (iters);+}+#else+#endif /* FITLOC */++#if ASA_TEMPLATE_SAMPLE++#if HAVE_ANSI+void+sample (FILE * ptr_out, FILE * ptr_asa)+#else+void+sample (ptr_out, ptr_asa)+     FILE *ptr_out;+     FILE *ptr_asa;+#endif+{+  int ind, n_samples, n_accept, index, dim;+  double cost, cost_temp, bias_accept;+  double param, temp, bias_gener, aver_weight, range;+  double sum, norm, answer, prod, binsize;+  char ch[80], sample[8];++  /*+     This is a demonstration of using ASA_SAMPLE to perform the double integral+     of exp(-x^2 - y^2) for x and y between 0 and 2.  The mesh is quite crude.++     The temperature-dependent acceptance and generated biases factor are+     divided out, and the actual cost function weights each point.+   */++  dim = 2;+  norm = sum = 0.;+  n_samples = 0;++  fprintf (ptr_out,+           ":SAMPLE:   n_accept   cost        cost_temp    bias_accept    \+ aver_weight\n");+  fprintf (ptr_out,+           ":SAMPLE:   index      param[]     temp[]       bias_gener[]   \+ range[]\n");+  for (;;) {+    fscanf (ptr_asa, "%s", ch);+    if (!strcmp (ch, "exit_status")) {+      break;+    }+    if (strcmp (ch, ":SAMPLE#")) {+      continue;+    }+    ++n_samples;+    fprintf (ptr_out, "%s\n", ch);+    fflush (ptr_out);+    fscanf (ptr_asa, "%s%d%lf%lf%lf%lf",+            sample, &n_accept, &cost, &cost_temp, &bias_accept, &aver_weight);+    if (strcmp (sample, ":SAMPLE+")) {+      fprintf (ptr_out, "%s %11d %12.7g %12.7g %12.7g %12.7g\n",+               sample, n_accept, cost, cost_temp, bias_accept, aver_weight);+    } else {+      fprintf (ptr_out, "%s %10d %12.7g %12.7g %12.7g %12.7g\n",+               sample, n_accept, cost, cost_temp, bias_accept, aver_weight);+    }+    prod = bias_accept;+    binsize = 1.0;+    for (ind = 0; ind < dim; ++ind) {+      fscanf (ptr_asa, "%s%d%lf%lf%lf%lf",+              sample, &index, &param, &temp, &bias_gener, &range);+      fprintf (ptr_out, "%s %11d %12.7g %12.7g %12.7g %12.7g\n",+               sample, index, param, temp, bias_gener, range);+      prod *= bias_gener;+      binsize *= range;+    }+    /* In this example, retrieve integrand from sampling function */+    sum += ((F_EXP (-cost) * binsize) / prod);+    norm += (binsize / prod);+  }+  sum /= norm;++  answer = 1.0;+  for (ind = 0; ind < dim; ++ind) {+    answer *= (0.5 * sqrt (3.14159265) * erf (2.0));+  }++  fprintf (ptr_out, "\n");+  fprintf (ptr_out, "sum = %12.7g, answer = %12.7g\n", sum, answer);+  fprintf (ptr_out, "n_samples = %d, norm = %12.7g\n", n_samples, norm);+  fflush (ptr_out);++}+#endif /* ASA_TEMPLATE_SAMPLE */+#if ASA_TEMPLATE_LIB+int+main ()+{+  double main_cost_value;+  double *main_cost_parameters;+  int main_exit_code;+  LONG_INT number_params;+  ALLOC_INT n_param;+  FILE *ptr_main;++#if INCL_STDOUT+  ptr_main = stdout;+#endif /* INCL_STDOUT */++  /* Note this assumes the *parameter_dimension = 4 */+  number_params = 4;++  if ((main_cost_parameters =+       (double *) calloc (number_params, sizeof (double))) == NULL) {+    strcpy (user_exit_msg, "ASA_TEMPLATE_LIB main(): main_cost_parameters");+    Exit_USER (user_exit_msg);+    return (-2);+  }++  asa_seed (696969);            /* This is the default random seed. */+  asa_main (&main_cost_value, main_cost_parameters, &main_exit_code);++  fprintf (ptr_main, "main_exit_code = %d\n", main_exit_code);+  fprintf (ptr_main, "main_cost_value = %12.7g\n", main_cost_value);+  fprintf (ptr_main, "parameter\tvalue\n");+  for (n_param = 0; n_param < number_params; ++n_param) {+    fprintf (ptr_main,+#if INT_ALLOC+             "%d\t\t%12.7g\n",+#else+#if INT_LONG+             "%ld\t\t%12.7g\n",+#else+             "%d\t\t%12.7g\n",+#endif+#endif+             n_param, main_cost_parameters[n_param]);+  }++  free (main_cost_parameters);++  return (0);+/* NOTREACHED */+}+#endif /* ASA_TEMPLATE_LIB */++void+Exit_USER (char *statement)+{+#if INCL_STDOUT+  printf ("\n\n*** EXIT calloc failed *** %s\n\n", statement);+#else+  ;+#endif /* INCL_STDOUT */+}
+ include/asa.h view
@@ -0,0 +1,337 @@+#ifndef _ASA_H_+#define _ASA_H_++/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+***********************************************************************/++ /* $Id: asa.h,v 25.15 2004/09/23 18:10:48 ingber Exp ingber $ */++ /* asa.h for Adaptive Simulated Annealing */++#include "asa_usr_asa.h"++#define ZERO			((double) 0.0)+#define ONE			((double) 1.0)+#define TWO			((double) 2.0)+#define TEN			((double) 10.0)+#define HALF			((double) 0.5)++#define NORMAL_EXIT			((int) 0)+#define P_TEMP_TOO_SMALL		((int) 1)+#define C_TEMP_TOO_SMALL		((int) 2)+#define COST_REPEATING			((int) 3)+#define TOO_MANY_INVALID_STATES		((int) 4)+#define IMMEDIATE_EXIT			((int) 5)+#define INVALID_USER_INPUT		((int) 7)+#define INVALID_COST_FUNCTION		((int) 8)+#define INVALID_COST_FUNCTION_DERIV	((int) 9)+#define CALLOC_FAILED			((int) -1)++#ifndef TIME_STD+#define TIME_STD FALSE+#endif++#ifndef TIME_GETRUSAGE+#define TIME_GETRUSAGE TRUE+#endif++#if TIME_CALC+#if TIME_GETRUSAGE+#include <sys/time.h>+#include <sys/resource.h>+#if TIME_STD+#include <sys/syscall.h>+#endif /* TIME_STD */+#else /* TIME_GETRUSAGE */+#if TRUE                        /* change to FALSE for SunOS 4.1.x */+#include <time.h>+#else+#include </usr/5include/time.h>+#endif+#endif /* TIME_GETRUSAGE */+#endif /* TIME_CALC */++ /* Set this to TRUE to override the P_TEMP_TOO_SMALL test */+#ifndef NO_PARAM_TEMP_TEST+#define NO_PARAM_TEMP_TEST FALSE+#endif++ /* Set this to TRUE to override the C_TEMP_TOO_SMALL test */+#ifndef NO_COST_TEMP_TEST+#define NO_COST_TEMP_TEST FALSE+#endif++#ifndef SYSTEM_CALL+#define SYSTEM_CALL TRUE+#endif++ /* Printing Options */++#ifndef ASA_PRINT+#define ASA_PRINT TRUE+#endif++#if ASA_PRINT+#else+#if ASA_SAMPLE+#define ASA_PRINT TRUE+#endif+#endif++#ifndef ASA_OUT+#define ASA_OUT "asa_out"+#endif++#ifndef DROPPED_PARAMETERS+#define DROPPED_PARAMETERS FALSE+#endif++ /* You can set ASA_PRINT_INTERMED to TRUE to print out+    intermediate data when SELF_OPTIMIZE is set to TRUE */+#ifndef ASA_PRINT_INTERMED+#if SELF_OPTIMIZE+#define ASA_PRINT_INTERMED FALSE+#else+#define ASA_PRINT_INTERMED TRUE+#endif+#endif++#ifndef ASA_PRINT_MORE+#define ASA_PRINT_MORE FALSE+#endif++char exit_msg[160];             /* temp storage for exit messages */++ /* The state of the system in terms of parameters and function value */+typedef struct {+  double cost;+  double *parameter;+#if ASA_PARALLEL+#if USER_ACCEPTANCE_TEST+  int par_user_accept_flag;+  int par_cost_accept_flag;+#endif+#endif+} STATE;++#if ASA_PARALLEL+  /* parallel generated states */+STATE *gener_block_state_qsort;+#endif++ /* essential MACROS */++#if USER_REANNEAL_PARAMETERS+#else+ /* FUNCTION_REANNEAL_PARAMS(temperature, tangent, max_tangent)+    determines the reannealed temperature. */+#define FUNCTION_REANNEAL_PARAMS(temperature, tangent, max_tangent) \+ (temperature * (max_tangent / tangent))+#endif++ /* IABS(i)+    absolute value for integers, in stdlib.h on _some_ machines */+#define IABS(i) ((i) < 0? -(i) : (i))++ /*  NO_REANNEAL(x)+    can determine whether to calculate derivatives. */+#define NO_REANNEAL(x)	(IABS(parameter_type[x]) == 2)++ /* VFOR+    is a simple macro to iterate on each parameter index. */++#define VFOR(index_v) \+ for (index_v = 0; index_v < *number_parameters; ++index_v)++#if CHECK_EXPONENT+ /* EXPONENT_CHECK+    checks that an exponent x is within a valid range and,+    if not, adjusts its magnitude to fit in the range. */+#define MIN_EXPONENT (0.9 * F_LOG ((double) MIN_DOUBLE))+#define MAX_EXPONENT (0.9 * F_LOG ((double) MAX_DOUBLE))+#define EXPONENT_CHECK(x) \+ ((x) < MIN_EXPONENT ? MIN_EXPONENT : \+ ((x) > MAX_EXPONENT ? MAX_EXPONENT : (x)))+#else+#define EXPONENT_CHECK(x) (x)+#endif /* CHECK_EXPONENT */++ /* PARAMETER_RANGE_TOO_SMALL(x)+    checks if the range of parameter x is too small to work with.+    If user_cost_function changes the parameter ranges,+    this test could be used to adaptively bypass+    some parameters, e.g., depending on constraints. */+#define PARAMETER_RANGE_TOO_SMALL(x) \+ (fabs(parameter_minimum[x] - parameter_maximum[x]) < (double) EPS_DOUBLE)++ /* INTEGER_PARAMETER(x)+    determines if the parameter is an integer type. */+#define INTEGER_PARAMETER(x) (parameter_type[x] > 0)++ /* ROW_COL_INDEX(i, j)+    converts from row i, column j to an index. */+#define ROW_COL_INDEX(i, j) ((i) + *number_parameters * (j))++#if HAVE_ANSI++ /* asa function prototypes */+void accept_new_state (double (*user_random_generator) (LONG_INT *),+                       LONG_INT * seed,+                       double *parameter_minimum,+                       double *parameter_maximum,+                       double *current_cost_temperature,+#if ASA_SAMPLE+                       double *current_user_parameter_temp,+#endif+                       ALLOC_INT * number_parameters,+                       LONG_INT * recent_number_acceptances,+                       LONG_INT * number_accepted,+                       LONG_INT * index_cost_acceptances,+                       LONG_INT * number_acceptances_saved,+                       LONG_INT * recent_number_generated,+                       LONG_INT * number_generated,+                       LONG_INT * index_parameter_generations,+                       STATE * current_generated_state,+                       STATE * last_saved_state,+#if ASA_SAMPLE+                       FILE * ptr_asa_out,+#endif+                       USER_DEFINES * OPTIONS);++void generate_new_state (double (*user_random_generator) (LONG_INT *),+                         LONG_INT * seed,+                         double *parameter_minimum,+                         double *parameter_maximum,+                         double *current_parameter_temperature,+#if USER_GENERATING_FUNCTION+                         double *initial_user_parameter_temp,+                         double *temperature_scale_parameters,+#endif+                         ALLOC_INT * number_parameters,+                         int *parameter_type,+                         STATE * current_generated_state,+                         STATE * last_saved_state, USER_DEFINES * OPTIONS);++void reanneal (double *parameter_minimum,+               double *parameter_maximum,+               double *tangents,+               double *maximum_tangent,+               double *current_cost_temperature,+               double *initial_cost_temperature,+               double *temperature_scale_cost,+               double *current_user_parameter_temp,+               double *initial_user_parameter_temp,+               double *temperature_scale_parameters,+               ALLOC_INT * number_parameters,+               int *parameter_type,+               LONG_INT * index_cost_acceptances,+               LONG_INT * index_parameter_generations,+               STATE * last_saved_state,+               STATE * best_generated_state, USER_DEFINES * OPTIONS);++void+  cost_derivatives (double (*user_cost_function)++                     +                    (double *, double *, double *, double *, double *,+                     ALLOC_INT *, int *, int *, int *, USER_DEFINES *),+                    double *parameter_minimum, double *parameter_maximum,+                    double *tangents, double *curvature,+                    double *maximum_tangent, ALLOC_INT * number_parameters,+                    int *parameter_type, int *exit_status,+                    int *curvature_flag, int *valid_state_generated_flag,+                    LONG_INT * number_invalid_generated_states,+                    STATE * current_generated_state,+                    STATE * best_generated_state, FILE * ptr_asa_out,+                    USER_DEFINES * OPTIONS);++double generate_asa_state (double (*user_random_generator) (LONG_INT *),+                           LONG_INT * seed, double *temp);++int+  asa_exit (double (*user_cost_function)++             +            (double *, double *, double *, double *, double *, ALLOC_INT *,+             int *, int *, int *, USER_DEFINES *), double *final_cost,+            double *parameter_initial_final, double *parameter_minimum,+            double *parameter_maximum, double *tangents, double *curvature,+            double *maximum_tangent, double *current_cost_temperature,+            double *initial_user_parameter_temp,+            double *current_user_parameter_temp,+            double *accepted_to_generated_ratio,+            ALLOC_INT * number_parameters, int *parameter_type,+            int *valid_state_generated_flag, int *exit_status,+            ALLOC_INT * index_exit_v, ALLOC_INT * start_sequence,+            LONG_INT * number_accepted, LONG_INT * best_number_accepted_saved,+            LONG_INT * index_cost_acceptances, LONG_INT * number_generated,+            LONG_INT * number_invalid_generated_states,+            LONG_INT * index_parameter_generations,+            LONG_INT * best_number_generated_saved,+            STATE * current_generated_state, STATE * last_saved_state,+            STATE * best_generated_state, FILE * ptr_asa_out,+            USER_DEFINES * OPTIONS);++void Exit_ASA (char *statement);++int asa_test_asa_options (LONG_INT * seed,+                          double *parameter_initial_final,+                          double *parameter_minimum,+                          double *parameter_maximum,+                          double *tangents,+                          double *curvature,+                          ALLOC_INT * number_parameters,+                          int *parameter_type,+                          int *valid_state_generated_flag,+                          int *exit_status,+                          FILE * ptr_asa_out, USER_DEFINES * OPTIONS);++int cost_function_test (double cost,+                        double *parameter,+                        double *parameter_minimum,+                        double *parameter_maximum,+                        ALLOC_INT * number_parameters,+                        double *xnumber_parameters);++void print_string (FILE * ptr_asa_out, char *string);+void print_string_index (FILE * ptr_asa_out, char *string, ALLOC_INT index);++#if ASA_PRINT+void print_state (double *parameter_minimum,+                  double *parameter_maximum,+                  double *tangents,+                  double *curvature,+                  double *current_cost_temperature,+                  double *current_user_parameter_temp,+                  double *accepted_to_generated_ratio,+                  ALLOC_INT * number_parameters,+                  int *curvature_flag,+                  LONG_INT * number_accepted,+                  LONG_INT * index_cost_acceptances,+                  LONG_INT * number_generated,+                  LONG_INT * number_invalid_generated_states,+                  STATE * last_saved_state,+                  STATE * best_generated_state,+                  FILE * ptr_asa_out, USER_DEFINES * OPTIONS);++void print_asa_options (FILE * ptr_asa_out, USER_DEFINES * OPTIONS);+#endif /* ASA_PRINT */+++#if MULTI_MIN+static int multi_compare (const void *cost_ii, const void *cost_jj);+double *multi_cost_qsort;+#endif++#if ASA_PARALLEL+static int sort_parallel (const void *cost_ii, const void *cost_jj);+#endif++#else /* HAVE_ANSI */+#endif /* HAVE_ANSI */++#endif /* _ASA_H_ */
+ include/asa_usr.h view
@@ -0,0 +1,293 @@+#ifndef _ASA_USER_H_+#define _ASA_USER_H_++/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+***********************************************************************/++ /* $Id: asa_usr.h,v 25.15 2004/09/23 18:10:45 ingber Exp ingber $ */++ /* asa_usr.h for Adaptive Simulated Annealing */++#include "asa_usr_asa.h"++#define SHUFFLE 256             /* size of random array */++#if ASA_TEMPLATE_ASA_OUT_PID+#include <sys/types.h>+#endif++#if TIME_CALC+ /* print the time every PRINT_FREQUENCY function evaluations+    Define PRINT_FREQUENCY to 0 to not print out the time. */+#define PRINT_FREQUENCY ((LONG_INT) 1000)+#endif++#if USER_ACCEPTANCE_TEST+#define MIN(x,y)	((x) < (y) ? (x) : (y))+#endif++ /* system function prototypes */++#if ASA_TEMPLATE_ASA_OUT_PID+int getpid ();+#endif++#if HAVE_ANSI+++#if IO_PROTOTYPES+#if OPTIONS_FILE+int fscanf ();+#endif+#endif++ /* user-defined */+double USER_COST_FUNCTION (double *cost_parameters,+                           double *parameter_lower_bound,+                           double *parameter_upper_bound,+                           double *cost_tangents,+                           double *cost_curvature,+                           ALLOC_INT * parameter_dimension,+                           int *parameter_int_real,+                           int *cost_flag,+                           int *exit_code, USER_DEFINES * USER_OPTIONS);+#if ASA_LIB+int+asa_main (+           hs_cost_func *func, +           int number_parameters,+           double *upper_bounds,+           double *lower_bounds,+           int *type,+           double *main_cost_value,+           double *main_cost_parameters, +           int *main_exit_code,+           long int rand_seed+  );+#else+int main (int argc, char **argv);+#endif++#if ASA_TEMPLATE_LIB+int main ();+#endif++ /* possibly with accompanying data file */+int initialize_parameters (double *cost_parameters,+                           double *parameter_lower_bound,+                           double *parameter_upper_bound,+                           double *cost_tangents,+                           double *cost_curvature,+                           ALLOC_INT * parameter_dimension,+                           int *parameter_int_real,+#if OPTIONS_FILE_DATA+                           FILE * ptr_options,+#endif+                           USER_DEFINES * USER_OPTIONS);++//double myrand (LONG_INT * rand_seed);+//double randflt (LONG_INT * rand_seed);+//double resettable_randflt (LONG_INT * rand_seed, int reset);++#if USER_COST_SCHEDULE+double user_cost_schedule (double test_temperature,+                           USER_DEFINES * USER_OPTIONS);+#endif++#if USER_ACCEPTANCE_TEST+void user_acceptance_test (double current_cost,+                           double *parameter_lower_bound,+                           double *parameter_upper_bound,+                           ALLOC_INT * parameter_dimension,+                           USER_DEFINES * USER_OPTIONS);+#endif++#if USER_GENERATING_FUNCTION+double user_generating_distrib (LONG_INT * seed,+                                ALLOC_INT * parameter_dimension,+                                ALLOC_INT index_v,+                                double temperature_v,+                                double init_param_temp_v,+                                double temp_scale_params_v,+                                double parameter_v,+                                double parameter_range_v,+                                double *last_saved_parameter,+                                USER_DEFINES * USER_OPTIONS);+#endif++#if USER_REANNEAL_COST+int user_reanneal_cost (double *cost_best,+                        double *cost_last,+                        double *initial_cost_temperature,+                        double *current_cost_temperature,+                        USER_DEFINES * USER_OPTIONS);+#endif++#if USER_REANNEAL_PARAMETERS+double user_reanneal_params (double current_temp,+                             double tangent,+                             double max_tangent, USER_DEFINES * USER_OPTIONS);+#endif++#if ASA_TEMPLATE_SAMPLE+void sample (FILE * ptr_out, FILE * ptr_asa);+#endif++void Exit_USER (char *statement);++#else /* HAVE_ANSI */+#endif /* HAVE_ANSI */++void Exit_USER ();++#if SELF_OPTIMIZE+#if TIME_CALC+#define RECUR_PRINT_FREQUENCY ((LONG_INT) 1)+#endif++#if HAVE_ANSI                   /* HAVE_ANSI SELF_OPTIMIZE */+double RECUR_USER_COST_FUNCTION (double *recur_cost_parameters,+                                 double *recur_parameter_lower_bound,+                                 double *recur_parameter_upper_bound,+                                 double *recur_cost_tangents,+                                 double *recur_cost_curvature,+                                 ALLOC_INT * recur_parameter_dimension,+                                 int *recur_parameter_int_real,+                                 int *recur_cost_flag,+                                 int *recur_exit_code,+                                 USER_DEFINES * RECUR_USER_OPTIONS);++int recur_initialize_parameters (double *recur_cost_parameters,+                                 double *recur_parameter_lower_bound,+                                 double *recur_parameter_upper_bound,+                                 double *recur_cost_tangents,+                                 double *recur_cost_curvature,+                                 ALLOC_INT * recur_parameter_dimension,+                                 int *recur_parameter_int_real,+#if RECUR_OPTIONS_FILE_DATA+                                 FILE * recur_ptr_options,+#endif+                                 USER_DEFINES * RECUR_USER_OPTIONS);++#if USER_COST_SCHEDULE+double recur_user_cost_schedule (double test_temperature,+                                 USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#if USER_ACCEPTANCE_TEST+void recur_user_acceptance_test (double current_cost,+                                 double *recur_parameter_lower_bound,+                                 double *recur_parameter_upper_bound,+                                 ALLOC_INT * recur_parameter_dimension,+                                 USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#if USER_GENERATING_FUNCTION+double recur_user_generating_distrib (LONG_INT * seed,+                                      ALLOC_INT * recur_parameter_dimension,+                                      ALLOC_INT index_v,+                                      double temperature_v,+                                      double init_param_temp_v,+                                      double temp_scale_params_v,+                                      double parameter_v,+                                      double parameter_range_v,+                                      double *last_saved_parameter,+                                      USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#if USER_REANNEAL_COST+int recur_user_reanneal_cost (double *cost_best,+                              double *cost_last,+                              double *initial_cost_temperature,+                              double *current_cost_temperature,+                              USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#if USER_REANNEAL_PARAMETERS+double recur_user_reanneal_params (double current_temp,+                                   double tangent,+                                   double max_tangent,+                                   USER_DEFINES * RECUR_USER_OPTIONS);+#endif++#else /* HAVE_ANSI SELF_OPTIMIZE */++double RECUR_USER_COST_FUNCTION ();+int recur_initialize_parameters ();++#if USER_COST_SCHEDULE+double recur_user_cost_schedule ();+#endif++#if USER_ACCEPTANCE_TEST+void recur_user_acceptance_test ();+#endif++#if USER_GENERATING_FUNCTION+double recur_user_generating_distrib ();+#endif++#if USER_REANNEAL_COST+int recur_user_reanneal_cost ();+#endif++#if USER_REANNEAL_PARAMETERS+double recur_user_reanneal_params ();+#endif++#endif /* HAVE_ANSI */+#endif /* SELF_OPTIMIZE */++#if FITLOC+#if HAVE_ANSI+double+  calcf (double (*user_cost_function)++          +         (double *, double *, double *, double *, double *, ALLOC_INT *,+          int *, int *, int *, USER_DEFINES *), double *cost_parameters,+         double *parameter_lower_bound, double *parameter_upper_bound,+         double *cost_tangents, double *cost_curvature,+         ALLOC_INT * parameter_dimension, int *parameter_int_real,+         int *cost_flag, int *exit_code, USER_DEFINES * USER_OPTIONS,+         FILE * ptr_out);++double+  fitloc (double (*user_cost_function)++           +          (double *, double *, double *, double *, double *, ALLOC_INT *,+           int *, int *, int *, USER_DEFINES *), double *cost_parameters,+          double *parameter_lower_bound, double *parameter_upper_bound,+          double *cost_tangents, double *cost_curvature,+          ALLOC_INT * parameter_dimension, int *parameter_int_real,+          int *cost_flag, int *exit_code, USER_DEFINES * USER_OPTIONS,+          FILE * ptr_out);++int+  simplex (double (*user_cost_function)++            +           (double *, double *, double *, double *, double *, ALLOC_INT *,+            int *, int *, int *, USER_DEFINES *), double *cost_parameters,+           double *parameter_lower_bound, double *parameter_upper_bound,+           double *cost_tangents, double *cost_curvature,+           ALLOC_INT * parameter_dimension, int *parameter_int_real,+           int *cost_flag, int *exit_code, USER_DEFINES * USER_OPTIONS,+           FILE * ptr_out, double tol1, double tol2, int no_progress,+           double alpha, double beta1, double beta2, double gamma,+           double delta);+#else /* HAVE_ANSI */++double calcf ();+double fitloc ();+int simplex ();++#endif /* HAVE_ANSI */+#endif /* FITLOC */++#endif /* _ASA_USER_H_ */
+ include/asa_usr_asa.h view
@@ -0,0 +1,682 @@+#ifndef _ASA_USER_ASA_H_+#define _ASA_USER_ASA_H_++/***********************************************************************+* Adaptive Simulated Annealing (ASA)+* Lester Ingber <ingber@ingber.com>+* Copyright (c) 1993-2004 Lester Ingber.  All Rights Reserved.+* The LICENSE file must be included with ASA code.+***********************************************************************/++ /* $Id: asa_usr_asa.h,v 25.15 2004/09/23 18:10:49 ingber Exp ingber $ */++ /* asa_usr_asa.h for Adaptive Simulated Annealing */++#include <errno.h>+#include <math.h>+#include <stdio.h>+#include <stdlib.h>             /* misc defs on most machines */+#include <string.h>++/* required if use machine-defined {DBL_EPSILON DBL_MIN DBL_MAX} */+/* #include <float.h> */++/* test for memory leaks */+/* #include "/usr/local/include/leak.h" */++#define	TRUE			1+#define	FALSE			0++#define MIN(x,y)	((x) < (y) ? (x) : (y))+#define MAX(x,y)	((x) > (y) ? (x) : (y))++ /* DEFAULT PARAMETERS SETTINGS */++ /* Pre-Compile Options */++ /* Special ASA_TEMPLATEs */++#ifndef MY_TEMPLATE+#define MY_TEMPLATE TRUE+#endif+#if MY_TEMPLATE                 /* MY_TEMPLATE_asa_user */++// #include <HsFFI.h>++typedef double hs_cost_func(double *x, int *flag);++/* #define ASA_LIB TRUE */+#define ASA_TEST FALSE+#define ASA_LIB TRUE+#define ASA_OUT  "STDOUT"+#define USER_OUT "STDOUT"+#define FITLOC TRUE+#define COST_FILE FALSE+// #define ASA_PRINT FALSE+// #define USER_ASA_OUT TRUE +#define OPTIONS_FILE FALSE+#define OPTIONAL_PTR_TYPE hs_cost_func+#define OPTIONAL_DATA_PTR TRUE+#define QUENCH_COST TRUE+#define QUENCH_PARAMETERS TRUE+++  /* you can add your own set of #define here */+#endif /* MY_TEMPLATE */++#ifndef ASA_TEMPLATE_LIB+#define ASA_TEMPLATE_LIB FALSE+#endif+#if ASA_TEMPLATE_LIB+#define ASA_LIB TRUE+#define ASA_TEST TRUE+#endif++#ifndef ASA_TEMPLATE_ASA_OUT_PID+#define ASA_TEMPLATE_ASA_OUT_PID FALSE+#endif+#if ASA_TEMPLATE_ASA_OUT_PID+#define USER_ASA_OUT TRUE+#endif++#ifndef ASA_TEMPLATE_MULTIPLE+#define ASA_TEMPLATE_MULTIPLE FALSE+#endif+#if ASA_TEMPLATE_MULTIPLE+#define COST_FILE FALSE+#define USER_ASA_OUT TRUE+#define ASA_TEST TRUE+#define QUENCH_COST TRUE+#define QUENCH_PARAMETERS TRUE+#define OPTIONS_FILE FALSE+#endif++#ifndef ASA_TEMPLATE_SELFOPT+#define ASA_TEMPLATE_SELFOPT FALSE+#endif+#if ASA_TEMPLATE_SELFOPT+#define COST_FILE FALSE+#define SELF_OPTIMIZE TRUE+#define OPTIONAL_DATA_DBL TRUE+#define USER_ASA_OUT TRUE+#define ASA_TEST TRUE+#define OPTIONS_FILE FALSE+#endif++#ifndef ASA_TEMPLATE_SAMPLE+#define ASA_TEMPLATE_SAMPLE FALSE+#endif+#if ASA_TEMPLATE_SAMPLE+#define COST_FILE FALSE+#define ASA_SAMPLE TRUE+#define USER_ACCEPTANCE_TEST TRUE+#define USER_COST_SCHEDULE TRUE+#define OPTIONS_FILE_DATA FALSE+#define USER_ACCEPT_ASYMP_EXP TRUE+#endif++#ifndef ASA_TEMPLATE_PARALLEL+#define ASA_TEMPLATE_PARALLEL FALSE+#endif+#if ASA_TEMPLATE_PARALLEL+#define COST_FILE FALSE+#define ASA_TEST TRUE+#define ASA_PARALLEL TRUE+#endif++#ifndef ASA_TEMPLATE_SAVE+#define ASA_TEMPLATE_SAVE FALSE+#endif+#if ASA_TEMPLATE_SAVE+#define COST_FILE FALSE+#define ASA_TEST TRUE+#define ASA_SAVE TRUE+#define QUENCH_PARAMETERS TRUE+#define QUENCH_COST TRUE+#endif++#ifndef ASA_TEMPLATE_QUEUE+#define ASA_TEMPLATE_QUEUE FALSE+#endif+#if ASA_TEMPLATE_QUEUE+#define ASA_QUEUE TRUE+#define ASA_RESOLUTION FALSE+#define ASA_TEST TRUE+#define COST_FILE FALSE+#define ASA_PRINT_MORE TRUE+#endif++#ifndef ASA_TEST_POINT+#define ASA_TEST_POINT FALSE+#endif+#if ASA_TEST_POINT+#define ASA_TEST TRUE+#define COST_FILE FALSE+#define SMALL_FLOAT 1.0E-50+#define QUENCH_COST TRUE+#endif++ /* Standard Pre-Compile Options */++#ifndef USER_COST_FUNCTION+#define USER_COST_FUNCTION cost_function+#endif++#if SELF_OPTIMIZE+#ifndef RECUR_USER_COST_FUNCTION+#define RECUR_USER_COST_FUNCTION recur_cost_function+#endif+#endif++#ifndef INCL_STDOUT+#define INCL_STDOUT TRUE+#endif+#if INCL_STDOUT+#define TIME_CALC FALSE+#endif++#ifndef OPTIONS_FILE+#define OPTIONS_FILE TRUE+#endif++#if OPTIONS_FILE+#ifndef OPTIONS_FILE_DATA+#define OPTIONS_FILE_DATA TRUE+#endif+#else+#define OPTIONS_FILE_DATA FALSE+#endif++#ifndef RECUR_OPTIONS_FILE+#define RECUR_OPTIONS_FILE FALSE+#endif++#if RECUR_OPTIONS_FILE+#ifndef RECUR_OPTIONS_FILE_DATA+#define RECUR_OPTIONS_FILE_DATA FALSE+#endif+#else+#define RECUR_OPTIONS_FILE_DATA FALSE+#endif++#ifndef COST_FILE+#define COST_FILE TRUE+#endif++#ifndef ASA_LIB+#define ASA_LIB FALSE+#endif++#ifndef HAVE_ANSI+#define HAVE_ANSI TRUE+#endif++#ifndef IO_PROTOTYPES+#define IO_PROTOTYPES FALSE+#endif++#ifndef TIME_CALC+#define TIME_CALC FALSE+#endif++#ifndef INT_LONG+#define INT_LONG TRUE+#endif++#if INT_LONG+#define LONG_INT long int+#else+#define LONG_INT int+#endif++#ifndef INT_ALLOC+#define INT_ALLOC FALSE+#endif++#if INT_ALLOC+#define ALLOC_INT int+#else+#define ALLOC_INT LONG_INT+#endif++ /* You can define SMALL_FLOAT to better correlate to your machine's+    precision, i.e., as used in asa */+#ifndef SMALL_FLOAT+#define SMALL_FLOAT 1.0E-18+#endif++ /* You can define your machine's maximum and minimum doubles here */+#ifndef MIN_DOUBLE+#define MIN_DOUBLE ((double) SMALL_FLOAT)+#endif++#ifndef MAX_DOUBLE+#define MAX_DOUBLE ((double) 1.0 / (double) SMALL_FLOAT)+#endif++#ifndef EPS_DOUBLE+#define EPS_DOUBLE ((double) SMALL_FLOAT)+#endif++#ifndef CHECK_EXPONENT+#define CHECK_EXPONENT FALSE+#endif++#ifndef ASA_TEST+#define ASA_TEST FALSE+#endif++#ifndef ASA_TEMPLATE+#define ASA_TEMPLATE FALSE+#endif++#ifndef USER_INITIAL_COST_TEMP+#define USER_INITIAL_COST_TEMP FALSE+#endif++#ifndef RATIO_TEMPERATURE_SCALES+#define RATIO_TEMPERATURE_SCALES FALSE+#endif++#ifndef USER_INITIAL_PARAMETERS_TEMPS+#define USER_INITIAL_PARAMETERS_TEMPS FALSE+#endif++#ifndef DELTA_PARAMETERS+#define DELTA_PARAMETERS FALSE+#endif++#ifndef QUENCH_PARAMETERS+#define QUENCH_PARAMETERS FALSE+#endif++#ifndef QUENCH_COST+#define QUENCH_COST FALSE+#endif++#ifndef QUENCH_PARAMETERS_SCALE+#define QUENCH_PARAMETERS_SCALE TRUE+#endif++#ifndef QUENCH_COST_SCALE+#define QUENCH_COST_SCALE TRUE+#endif++#ifndef OPTIONAL_DATA_DBL+#define OPTIONAL_DATA_DBL FALSE+#endif++#ifndef OPTIONAL_DATA_INT+#define OPTIONAL_DATA_INT FALSE+#endif++#ifndef OPTIONAL_DATA_PTR+#define OPTIONAL_DATA_PTR FALSE+#endif+#if OPTIONAL_DATA_PTR+/* user must define USER_TYPE; if a struct, it must be declared above */+#ifndef OPTIONAL_PTR_TYPE+#define OPTIONAL_PTR_TYPE USER_TYPE+#endif+#endif /* OPTIONAL_DATA_PTR */++#ifndef USER_REANNEAL_COST+#define USER_REANNEAL_COST FALSE+#endif++#ifndef USER_REANNEAL_PARAMETERS+#define USER_REANNEAL_PARAMETERS FALSE+#endif++#ifndef MAXIMUM_REANNEAL_INDEX+#define MAXIMUM_REANNEAL_INDEX 50000+#endif++#ifndef REANNEAL_SCALE+#define REANNEAL_SCALE 10+#endif++#ifndef USER_COST_SCHEDULE+#define USER_COST_SCHEDULE FALSE+#endif++#ifndef USER_ACCEPT_ASYMP_EXP+#define USER_ACCEPT_ASYMP_EXP FALSE+#endif++#ifndef USER_ACCEPT_THRESHOLD+#define USER_ACCEPT_THRESHOLD FALSE+#endif++#ifndef USER_ACCEPTANCE_TEST+#define USER_ACCEPTANCE_TEST FALSE+#endif++#ifndef USER_GENERATING_FUNCTION+#define USER_GENERATING_FUNCTION FALSE+#endif++ /* in asa.c, field-width.precision = G_FIELD.G_PRECISION */+#ifndef G_FIELD+#define G_FIELD 12+#endif+#ifndef G_PRECISION+#define G_PRECISION 7+#endif++#define INTEGER_TYPE		((int) 1)+#define REAL_TYPE		((int) -1)+#define INTEGER_NO_REANNEAL	((int) 2)+#define REAL_NO_REANNEAL	((int) -2)++ /* Set this to TRUE to self-optimize the Program Options */+#ifndef SELF_OPTIMIZE+#define SELF_OPTIMIZE FALSE+#endif++#ifndef USER_OUT+#define USER_OUT "asa_usr_out"+#endif++#ifndef USER_ASA_OUT+#define USER_ASA_OUT FALSE+#endif++#ifndef ASA_SAMPLE+#define ASA_SAMPLE FALSE+#endif++#ifndef ASA_QUEUE+#define ASA_QUEUE FALSE+#endif++#ifndef ASA_RESOLUTION+#define ASA_RESOLUTION FALSE+#endif++#ifndef ASA_PARALLEL+#define ASA_PARALLEL FALSE+#endif++#ifndef ASA_SAVE_OPT+#define ASA_SAVE_OPT FALSE+#endif+#if ASA_SAVE_OPT+#define ASA_SAVE TRUE+#endif++#ifndef ASA_SAVE_BACKUP+#define ASA_SAVE_BACKUP FALSE+#endif+#if ASA_SAVE_BACKUP+#define ASA_SAVE TRUE+#endif++#ifndef ASA_SAVE+#define ASA_SAVE FALSE+#endif++#ifndef ASA_PIPE+#define ASA_PIPE FALSE+#endif++#ifndef ASA_PIPE_FILE+#define ASA_PIPE_FILE FALSE+#endif++#ifndef FDLIBM_POW+#define FDLIBM_POW FALSE+#endif+#if FDLIBM_POW+#define F_POW s_pow+#else+#define F_POW pow+#endif++#ifndef FDLIBM_LOG+#define FDLIBM_LOG FALSE+#endif+#if FDLIBM_LOG+#define F_LOG s_log+#else+#define F_LOG log+#endif++#ifndef FDLIBM_EXP+#define FDLIBM_EXP FALSE+#endif+#if FDLIBM_EXP+#define F_EXP s_exp+#else+#define F_EXP exp+#endif++#ifndef FITLOC+#define FITLOC FALSE+#endif++#ifndef FITLOC_ROUND+#define FITLOC_ROUND TRUE+#endif++#ifndef FITLOC_PRINT+#define FITLOC_PRINT TRUE+#endif++#ifndef MULTI_MIN+#define MULTI_MIN FALSE+#endif++ /* Program Options */++typedef struct {+  LONG_INT Limit_Acceptances;+  LONG_INT Limit_Generated;+  int Limit_Invalid_Generated_States;+  double Accepted_To_Generated_Ratio;++  double Cost_Precision;+  int Maximum_Cost_Repeat;+  int Number_Cost_Samples;+  double Temperature_Ratio_Scale;+  double Cost_Parameter_Scale_Ratio;+  double Temperature_Anneal_Scale;+#if USER_INITIAL_COST_TEMP+  double *User_Cost_Temperature;+#endif++  int Include_Integer_Parameters;+  int User_Initial_Parameters;+  ALLOC_INT Sequential_Parameters;+  double Initial_Parameter_Temperature;+#if RATIO_TEMPERATURE_SCALES+  double *User_Temperature_Ratio;+#endif+#if USER_INITIAL_PARAMETERS_TEMPS+  double *User_Parameter_Temperature;+#endif++  int Acceptance_Frequency_Modulus;+  int Generated_Frequency_Modulus;+  int Reanneal_Cost;+  int Reanneal_Parameters;++  double Delta_X;+#if DELTA_PARAMETERS+  double *User_Delta_Parameter;+#endif+  int User_Tangents;+  int Curvature_0;++#if QUENCH_PARAMETERS+  double *User_Quench_Param_Scale;+#endif+#if QUENCH_COST+  double *User_Quench_Cost_Scale;+#endif++  LONG_INT N_Accepted;+  LONG_INT N_Generated;+  int Locate_Cost;+  int Immediate_Exit;++  double *Best_Cost;+  double *Best_Parameters;+  double *Last_Cost;+  double *Last_Parameters;++#if OPTIONAL_DATA_DBL+  ALLOC_INT Asa_Data_Dim_Dbl;+  double *Asa_Data_Dbl;+#endif+#if OPTIONAL_DATA_INT+  ALLOC_INT Asa_Data_Dim_Int;+  LONG_INT *Asa_Data_Int;+#endif+#if OPTIONAL_DATA_PTR+  ALLOC_INT Asa_Data_Dim_Ptr;+  OPTIONAL_PTR_TYPE *Asa_Data_Ptr;+#endif+#if USER_ASA_OUT+  char *Asa_Out_File;+#endif+#if USER_COST_SCHEDULE+  double (*Cost_Schedule) ();+#endif+#if USER_ACCEPT_ASYMP_EXP+  double Asymp_Exp_Param;+#endif+#if USER_ACCEPTANCE_TEST+  void (*Acceptance_Test) ();+  int User_Acceptance_Flag;+  int Cost_Acceptance_Flag;+  double Cost_Temp_Curr;+  double Cost_Temp_Init;+  double Cost_Temp_Scale;+  double Prob_Bias;+  LONG_INT *Random_Seed;+#endif+#if USER_GENERATING_FUNCTION+  double (*Generating_Distrib) ();+#endif+#if USER_REANNEAL_COST+  int (*Reanneal_Cost_Function) ();+#endif+#if USER_REANNEAL_PARAMETERS+  double (*Reanneal_Params_Function) ();+#endif+#if ASA_SAMPLE+  double Bias_Acceptance;+  double *Bias_Generated;+  double Average_Weights;+  double Limit_Weights;+#endif+#if ASA_QUEUE+  ALLOC_INT Queue_Size;+  double *Queue_Resolution;+#endif+#if ASA_RESOLUTION+  double *Coarse_Resolution;+#endif+#if FITLOC+  int Fit_Local;+  int Iter_Max;+  double Penalty;+#endif+#if MULTI_MIN+  int Multi_Number;+  double *Multi_Cost;+  double **Multi_Params;+  double *Multi_Grid;+  int Multi_Specify;+#endif+#if ASA_PARALLEL+  int Gener_Mov_Avr;+  LONG_INT Gener_Block;+  LONG_INT Gener_Block_Max;+#endif+  int Asa_Recursive_Level;+} USER_DEFINES;++ /* system function prototypes */++#if HAVE_ANSI++/* This block gives trouble under some Ultrix */+#if FALSE+int fprintf (FILE * fp, const char *string, ...);+int sprintf (char *s, const char *format, ...);+FILE *popen (const char *command, const char *mode);+void exit (int code);+#endif++#if IO_PROTOTYPES+int fprintf ();+int sprintf ();+int fflush (FILE * fp);+int fclose (FILE * fp);+void exit ();+int fread ();+int fwrite ();+int pclose ();+#endif++double+  asa (double (*user_cost_function)++        +       (double *, double *, double *, double *, double *, ALLOC_INT *, int *,+        int *, int *, USER_DEFINES *),+       double (*user_random_generator) (LONG_INT *), LONG_INT * rand_seed,+       double *parameter_initial_final, double *parameter_minimum,+       double *parameter_maximum, double *tangents, double *curvature,+       ALLOC_INT * number_parameters, int *parameter_type,+       int *valid_state_generated_flag, int *exit_status,+       USER_DEFINES * OPTIONS);++#if TIME_CALC+void print_time (char *message, FILE * ptr_out);+#endif++#if FDLIBM_POW+double s_pow (double x, double y);+#endif+#if FDLIBM_LOG+double s_log (double x);+#endif+#if FDLIBM_EXP+double s_exp (double x);+#endif++#else /* HAVE_ANSI */++#if IO_PROTOTYPES+int fprintf ();+int sprintf ();+int fflush ();+int fclose ();+int fread ();+int fwrite ();+FILE *popen ();+int pclose ();+#endif++double asa ();++#if TIME_CALC+void print_time ();+#endif++#if FDLIBM_POW+double s_pow ();+#endif+#if FDLIBM_LOG+double s_log ();+#endif+#if FDLIBM_EXP+double s_exp ();+#endif++#endif /* HAVE_ANSI */++#endif /* _ASA_USER_ASA_H_ */